Statistics
| Revision:

gvsig-3d / 1.10 / trunk / libraries / lib3DMap / src / org / gvsig / gvsig3d / cacheservices / FLayerCacheService.java @ 36

History | View | Annotate | Download (20.9 KB)

1
package org.gvsig.gvsig3d.cacheservices;
2

    
3
import java.awt.Color;
4
import java.awt.Dimension;
5
import java.awt.Graphics2D;
6
import java.awt.Image;
7
import java.awt.geom.AffineTransform;
8
import java.awt.geom.Rectangle2D;
9
import java.awt.image.BufferedImage;
10
import java.io.File;
11
import java.io.IOException;
12
import java.net.URL;
13
import java.util.ArrayList;
14
import java.util.HashMap;
15
import java.util.Hashtable;
16
import java.util.Iterator;
17
import java.util.PriorityQueue;
18
import java.util.Vector;
19

    
20
import org.apache.log4j.Logger;
21
import org.cresques.cts.IProjection;
22
import org.gvsig.cacheservice.CacheService;
23
import org.gvsig.cacheservice.CacheServiceException;
24
import org.gvsig.cacheservice.RasterCacheService;
25
import org.gvsig.cacheservice.TileNum;
26
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
27
import org.gvsig.osgvp.terrain.Terrain;
28
import org.gvsig.raster.buffer.BufferFactory;
29
import org.gvsig.raster.buffer.RasterBuffer;
30
import org.gvsig.raster.buffer.WriterBufferServer;
31
import org.gvsig.raster.dataset.GeoRasterWriter;
32
import org.gvsig.raster.dataset.InvalidSetViewException;
33
import org.gvsig.raster.dataset.NotSupportedExtensionException;
34
import org.gvsig.raster.dataset.Params;
35
import org.gvsig.raster.dataset.io.RasterDriverException;
36
import org.gvsig.remoteClient.utils.Utilities;
37
import org.gvsig.remoteClient.wcs.WCSStatus;
38
import org.gvsig.remoteClient.wms.ICancellable;
39
import org.gvsig.remoteClient.wms.WMSStatus;
40

    
41
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
42
import com.iver.ai2.gvsig3d.map3d.layers.Layer3DProps;
43
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
44
import com.iver.cit.gvsig.fmap.ViewPort;
45
import com.iver.cit.gvsig.fmap.drivers.wcs.FMapWCSDriver;
46
import com.iver.cit.gvsig.fmap.drivers.wcs.FMapWCSDriverFactory;
47
import com.iver.cit.gvsig.fmap.drivers.wms.FMapWMSDriver;
48
import com.iver.cit.gvsig.fmap.drivers.wms.FMapWMSDriverFactory;
49
import com.iver.cit.gvsig.fmap.layers.FLayer;
50
import com.iver.cit.gvsig.fmap.layers.FLyrDefault;
51
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
52
import com.iver.cit.gvsig.fmap.layers.FLyrWCS;
53
import com.iver.cit.gvsig.fmap.layers.FLyrWMS;
54
import com.iver.utiles.FileUtils;
55
import com.iver.utiles.swing.threads.Cancellable;
56

    
57
public class FLayerCacheService extends RasterCacheService {
58
        private boolean _loadFailed = true;
59
        private Rectangle2D _lyrExtentRect;
60
        private FLayer _layer;
61
        private IProjection _viewProj;
62
        private int _dataType;
63
        private Object cacheMutex = new Object();
64

    
65
        // WMS terrain
66
        FMapWMSDriver _wmsDriver = null;
67
        FMapWCSDriver _wcsDriver = null;
68

    
69
        WMSStatus _wmsStatus = null;
70
        WCSStatus _wcsStatus = null;
71

    
72
        Thread _requestThead = null;
73
        Thread _downloadMonitorThread = null;
74
        private RequestTileFromLayerThread _requestTileFromLayerThread;
75
        private DownloadMonitor _downloadMonitor;
76

    
77
        private static Logger _logger = Logger.getLogger(FLayerCacheService.class
78
                        .getName());
79

    
80
        public FLayerCacheService(Terrain terrain, String name, FLayer layer,
81
                        IProjection viewProj) {
82
                super(terrain.getTerrainName(), name);
83

    
84
                _layer = layer;
85
                _viewProj = viewProj;
86
                _loadFailed = true;
87

    
88
                int cacheType = CacheService.GLOBAL;
89
                if (terrain.getCoordinateSystemType() == Terrain.CoordinateSystemType.GEOCENTRIC)
90
                        cacheType += SPHERIC;
91
                else
92
                        cacheType += PLANE;
93
                setCacheType(cacheType);
94

    
95
                try {
96
                        _lyrExtentRect = _layer.getFullExtent();
97
                } catch (ExpansionFileReadException e) {
98
                        e.printStackTrace();
99
                } catch (ReadDriverException e) {
100
                        e.printStackTrace();
101
                }
102

    
103
                Layer3DProps props3D = Layer3DProps.getLayer3DProps(layer);
104
                _dataType = props3D.getType();
105
                if (_dataType == Layer3DProps.layer3DImage)
106
                        setFileExtension(".png");
107
                else
108
                        setFileExtension(".tif");
109

    
110
                _loadFailed = false;
111

    
112
        }
113

    
114
        protected class MyCancel implements Cancellable {
115
                private boolean cancel = false;
116
                
117
                public MyCancel()
118
                {
119
                }
120
                
121
                public void setCanceled(boolean canceled) {
122
                        cancel = canceled;
123
                }
124
                
125
                public boolean isCanceled() {
126
                        return cancel;
127
                }
128
        }
129
        
130
        protected class MyCancellable implements ICancellable
131
        {
132
                private Cancellable original;
133
                public MyCancellable(Cancellable cancelOriginal)
134
                {
135
                        this.original = cancelOriginal;
136
                }
137
                public void setCanceled(boolean canceled)
138
                {
139
                        original.setCanceled(canceled);
140
                }
141
                public boolean isCanceled() {
142
                        if (original == null) return false;
143
                        return original.isCanceled();
144
                }
145
                public Object getID() {
146
                        return this;
147
                }
148

    
149
        }
150

    
151
        protected class RequestTileFromLayerThread implements Runnable {
152

    
153
                private class Request implements Comparable<Request> {
154
                        public Request(long timeStamp, String fName, Rectangle2D tileExtent) {
155
                                _timeStamp = timeStamp;
156
                                _fName = fName;
157
                                _tileExtent = tileExtent;
158
                        }
159
                        long _timeStamp;
160
                        String _fName;
161
                        Rectangle2D _tileExtent;
162
                        public int compareTo(Request o) {
163
                                if(_timeStamp > o._timeStamp) return -1;
164
                                else if(_timeStamp < o._timeStamp) return 1;
165
                                else return 0;
166
                        }
167
                }
168

    
169
                private HashMap<String, Request> _requestList = new HashMap<String, Request>();
170
                private PriorityQueue<Request> _priorityRequestList = new PriorityQueue<Request>();
171
                private volatile boolean _done = false;
172

    
173
                protected synchronized void purgeOldRequests() {
174
                        int max_elements = 100;
175
                        if(_requestList.size() > max_elements) {
176
                                //_logger.debug("max elements reached from request list thread...");
177
                                Iterator<Request> iterator = _requestList.values().iterator();
178
                                ArrayList<Request> removeRequests = new ArrayList<Request>();
179
                                int index = 0;
180
                                while(iterator.hasNext()) {
181
                                        Request request = iterator.next();
182
                                        if(index>max_elements) {
183
                                                removeRequests.add(request);
184
                                        }
185
                                        index++;
186
                                }
187
                                for(int i=0;i<removeRequests.size();i++) {
188
                                        //_logger.debug("Removing old elements from request list thread...");
189
                                        _priorityRequestList.remove(removeRequests.get(i));
190
                                        _requestList.remove(removeRequests.get(i)._fName);
191
                                }
192
                        }
193
                }
194

    
195
                public synchronized void requestTile(String fName, Rectangle2D tileExtent) {
196
                        Request request = _requestList.get(fName);
197
                        if(request == null) {
198
                                Request req = new Request(System.currentTimeMillis(),fName,tileExtent);
199
                                _requestList.put(fName,req);
200
                                _priorityRequestList.add(req);
201
                        } else {
202
                                request._timeStamp = System.currentTimeMillis();
203
                        }
204
                        purgeOldRequests();
205
                }
206

    
207
                public void run() {
208
                        while(!_done) {
209
                                Request request = null;
210
                                synchronized (this) {
211
                                        request = _priorityRequestList.poll();
212
                                }
213
                                if(request != null) {
214
                                        _requestList.remove(request._fName);
215
                                        getTileFromLayer(request._fName, request._tileExtent);
216
                                }
217
                                else {
218
                                        try {
219
                                                Thread.sleep(1);
220
                                        } catch (InterruptedException e) {
221
                                                e.printStackTrace();
222
                                        }
223
                                }
224
                        }
225

    
226
                }
227

    
228
                public void setDone(boolean value) { _done = value; }
229

    
230
        }
231

    
232
        private void requestTileFromLayer(String fName, Rectangle2D tileExtent) {
233
                if(_requestThead == null) {
234
                        _requestTileFromLayerThread = new RequestTileFromLayerThread();
235
                        _requestThead = new Thread(_requestTileFromLayerThread);
236
                        _requestThead.start();
237
                }
238
                _requestTileFromLayerThread.requestTile(fName, tileExtent);
239

    
240
        }
241

    
242
        private void getTileFromLayer(String fName, Rectangle2D tileExtent) {
243
                BufferedImage image;
244

    
245
                // Check if the file exists, because some files are in request queue
246
                // while the request is processing.
247
                boolean fileExists = new File(fName).exists();
248
                if(!fileExists)
249
                {
250
                        if (_dataType == Layer3DProps.layer3DImage) {
251
                                // Workaround to avoid too many System.gc() calls on layer.draw. which makes
252
                                // rendering stall when rendering the tile.
253
                                if (_layer instanceof FLyrWMS) { // WMS Elevation
254
                                        try {
255
                                                FLyrWMS wmsLayer = (FLyrWMS) _layer;
256
                                                if (_wmsDriver == null) {
257

    
258
                                                        URL host = wmsLayer.getHost();
259
                                                        _wmsDriver = FMapWMSDriverFactory
260
                                                        .getFMapDriverForURL(host);
261
                                                }
262
                                                if (_wmsStatus == null) {
263
                                                        _wmsStatus = new WMSStatus();
264
                                                        _wmsStatus.setFormat(wmsLayer.getFormat());
265
                                                        _wmsStatus.setHeight(512);
266
                                                        _wmsStatus.setWidth(512);
267
                                                        _wmsStatus.setLayerNames(Utilities.createVector(
268
                                                                        wmsLayer.getLayerQuery(), ","));
269
                                                        _wmsStatus.setSrs(wmsLayer.getSRS());
270

    
271
                                                        HashMap props = wmsLayer.getProperties();
272
                                                        Vector styles;
273
                                                        Vector dimensions;
274
                                                        styles = (Vector) (props.get("styles"));
275
                                                        dimensions = (Vector) (props.get("dimensions"));
276
                                                        _wmsStatus.setStyles(styles);
277
                                                        _wmsStatus.setDimensions(dimensions);
278
                                                        _wmsStatus.setTransparency((Boolean)props.get("wmsTransparency"));
279
                                                        String getMapStr = wmsLayer.getOnlineResource("GetMap");
280
                                                        _wmsStatus.setOnlineResource(getMapStr);
281
                                                }
282
                                                _wmsStatus.setExtent(tileExtent);
283
                                                
284
                                                // Build a cancellable
285
                                                MyCancellable cancelDownload = new MyCancellable(new MyCancel());
286
                                                
287
                                                //Run monitor thread for remote services
288
                                                if(_downloadMonitorThread == null) {
289
                                                        _downloadMonitor = new DownloadMonitor();
290
                                                        _downloadMonitorThread = new Thread(_downloadMonitor);
291
                                                        _downloadMonitorThread.start();
292
                                                }
293
                                                _downloadMonitor.monitorThis(cancelDownload, System.currentTimeMillis());
294
                                                File f = _wmsDriver.getMap(_wmsStatus, cancelDownload);
295
                                                _downloadMonitor.endMonitor();
296
                                                if (f == null)
297
                                                        return;
298
                                                synchronized (cacheMutex) {
299
                                                        FileUtils.copy(f, new File(fName));
300
                                                }
301

    
302
                                        } catch (Exception e) {
303
                                                return;
304
                                        }
305
                                } else {
306
                                        int size = getTileSize();
307
                                        image = new BufferedImage(size, size,
308
                                                        BufferedImage.TYPE_INT_ARGB);
309

    
310
                                        ViewPort vp = new ViewPort(_viewProj);
311
                                        vp.setExtent(tileExtent); // the real extent of the tile
312
                                        // NotificationManager.addInfo("Extent solicitado--> "
313
                                        // + tileExtent.getMinX() + " " + tileExtent.getMinY() + " "
314
                                        // + tileExtent.getMaxX() + " " + tileExtent.getMaxY());
315
                                        vp.setAdjustable(false);
316
                                        vp.setImageSize(new Dimension(size, size));
317
                                        // vp.setDist1pixel(1 / 150000);
318
                                        vp.setDist1pixel(0.000000001);
319

    
320
                                        Graphics2D graphics = image.createGraphics();
321
                                        Color backgColor = new Color(255, 255, 255, 0); // transparent
322
                                        // background
323
                                        graphics.setColor(backgColor);
324
                                        graphics.fillRect(0, 0, size, size);
325

    
326
                                        // CancelDraw canceldraw = new MapControl.CancelDraw();
327
                                        // canceldraw.setCanceled(false);
328
                                        // For now we'll use a trick to make sure the layer is drawn
329
                                        // even if it has scale dependency
330
                                        // In the future, a scale corresponding to the tile should be
331
                                        // passed
332
                                        double scale = 0.5 * (_layer.getMaxScale() + _layer
333
                                                        .getMinScale());
334
                                        int trans = 255;
335

    
336
                                        // The layers of remote services don๏ฟฝt have transparency.
337
                                        if (_layer.getClass().equals(FLyrVect.class)) {
338
                                                // Generate layers 3D properties
339
                                                Layer3DProps props3D = Layer3DProps.getLayer3DProps(_layer);
340
                                                // fix opaque the layer to save in disk
341
                                                ((FLyrDefault) _layer).setTransparency((int) (props3D
342
                                                                .getOpacity() * 255));
343

    
344
                                        }
345

    
346
                                        if (_layer instanceof FLyrRasterSE) {
347
                                                // fix opaque the layer to save in disk
348
                                                ((FLyrRasterSE) _layer).setTransparency(255);
349
                                        }
350

    
351
                                        try {
352
                                                _layer.draw(image, graphics, vp, new MyCancel(), scale);
353
                                                if ((_layer.getClass().equals(FLyrVect.class))&& ((FLyrVect)_layer).isLabeled())
354
                                                        ((FLyrVect)_layer).drawLabels(image, graphics, vp, new MyCancel(), scale,72);
355

    
356
                                        } catch (Exception e) {
357
                                                return;
358
                                        }
359
                                        // Restoring the real value of transparency
360
                                        if (_layer.getClass().equals(FLyrVect.class)) {
361
                                                // fix the real transparency to the layer
362
                                                ((FLyrDefault) _layer).setTransparency(trans);
363
                                        }
364

    
365
                                        try {
366
                                                File file = new File(fName);
367
                                                String format = getFileExtension().substring(1);
368
                                                synchronized (cacheMutex) {
369
                                                        saveCachedFile(image, format, file);
370
                                                }
371
                                        } catch (IOException e1) {
372
                                                e1.printStackTrace();
373
                                                return;
374
                                        }
375
                                }
376
                        } else { // Elevation data
377
                                if (_layer instanceof FLyrWMS) { // WMS Elevation
378
                                        try {
379
                                                FLyrWMS wmsLayer = (FLyrWMS) _layer;
380
                                                if (_wmsDriver == null) {
381

    
382
                                                        URL host = wmsLayer.getHost();
383
                                                        _wmsDriver = FMapWMSDriverFactory
384
                                                        .getFMapDriverForURL(host);
385
                                                }
386
                                                if (_wmsStatus == null) {
387
                                                        _wmsStatus = new WMSStatus();
388
                                                        _wmsStatus.setFormat(wmsLayer.getFormat());
389
                                                        _wmsStatus.setHeight(32);
390
                                                        _wmsStatus.setWidth(32);
391
                                                        _wmsStatus.setLayerNames(Utilities.createVector(
392
                                                                        wmsLayer.getLayerQuery(), ","));
393
                                                        _wmsStatus.setSrs(wmsLayer.getSRS());
394

    
395
                                                        HashMap props = wmsLayer.getProperties();
396
                                                        Vector styles;
397
                                                        Vector dimensions;
398
                                                        styles = (Vector) (props.get("styles"));
399
                                                        dimensions = (Vector) (props.get("dimensions"));
400
                                                        _wmsStatus.setStyles(styles);
401
                                                        _wmsStatus.setDimensions(dimensions);
402
                                                        _wmsStatus.setTransparency(false);
403
                                                        String getMapStr = wmsLayer.getOnlineResource("GetMap");
404
                                                        _wmsStatus.setOnlineResource(getMapStr);
405
                                                }
406
                                                _wmsStatus.setExtent(tileExtent);
407
                                                
408
                                                // Build a cancellable
409
                                                MyCancellable cancelDownload = new MyCancellable(new MyCancel());
410
                                                
411
                                                //Run monitor thread for remote services
412
                                                if(_downloadMonitorThread == null) {
413
                                                        _downloadMonitor = new DownloadMonitor();
414
                                                        _downloadMonitorThread = new Thread(_downloadMonitor);
415
                                                        _downloadMonitorThread.start();
416
                                                }
417
                                                _downloadMonitor.monitorThis(cancelDownload, System.currentTimeMillis());
418
                                                File f = _wmsDriver.getMap(_wmsStatus, cancelDownload);
419
                                                _downloadMonitor.endMonitor();
420
                                                if (f == null)
421
                                                        return;
422

    
423
                                                synchronized (cacheMutex) {
424
                                                        FileUtils.copy(f, new File(fName));
425
                                                }
426

    
427
                                        } catch (Exception e) {
428
                                                return;
429
                                        }
430
                                } else if (_layer instanceof FLyrWCS) { // WCS Elevation
431
                                        try {
432
                                                FLyrWCS wcsLayer = (FLyrWCS) _layer;
433
                                                if (_wcsDriver == null) {
434

    
435
                                                        URL host = wcsLayer.getHost();
436
                                                        _wcsDriver = FMapWCSDriverFactory
437
                                                        .getFMapDriverForURL(host);
438
                                                }
439
                                                if (_wcsStatus == null) {
440
                                                        _wcsStatus = new WCSStatus();
441

    
442
                                                        Hashtable props = wcsLayer.getProperties();
443

    
444
                                                        _wcsStatus.setCoveraName((String) props.get("name"));
445
                                                        _wcsStatus.setFormat((String) props.get("format"));
446
                                                        _wcsStatus.setHeight(32);
447
                                                        _wcsStatus.setWidth(32);
448
                                                        _wcsStatus.setSrs((String) props.get("crs"));
449
                                                        _wcsStatus.setParameters((String) props
450
                                                                        .get("parameter"));
451
                                                        String time = (String) props.get("time");
452
                                                        if (time.length() > 0)
453
                                                                _wcsStatus.setTime(time);
454
                                                }
455
                                                _wcsStatus.setExtent(tileExtent);
456

    
457
                                                // Build a cancellable
458
                                                MyCancellable cancelDownload = new MyCancellable(new MyCancel());
459
                                                
460
                                                //Run monitor thread for remote services
461
                                                if(_downloadMonitorThread == null) {
462
                                                        _downloadMonitor = new DownloadMonitor();
463
                                                        _downloadMonitorThread = new Thread(_downloadMonitor);
464
                                                        _downloadMonitorThread.start();
465
                                                }
466
                                                _downloadMonitor.monitorThis(cancelDownload, System.currentTimeMillis());
467
                                                File f = _wcsDriver.getCoverage(_wcsStatus, new MyCancellable(new MyCancel()));
468
                                                _downloadMonitor.endMonitor();
469
                                                if (f == null)
470
                                                        return;
471
                                                synchronized (cacheMutex) {
472
                                                        FileUtils.copy(f, new File(fName));
473
                                                }
474
                                        } catch (Exception e) {
475
                                                return;
476
                                        }
477
                                } else
478
                                        // RASTER_GRID
479
                                        if (_layer instanceof FLyrRasterSE) {
480

    
481
                                                FLyrRasterSE rasterLayer = (FLyrRasterSE) _layer;
482
                                                BufferFactory bufferFactory = rasterLayer.getBufferFactory();
483

    
484
                                                //int bands[] = { 0 };
485
                                                bufferFactory.setAllDrawableBands();
486
                                                bufferFactory.setAdjustToExtent(false);
487
                                                bufferFactory.setNoDataToFill(0.0);
488

    
489
                                                // The y max and min are mixed because there are some problems 
490
                                                // computing the adjustedDataExtent.
491
                                                try {
492
                                                        bufferFactory.setAreaOfInterest(tileExtent.getMinX(),
493
                                                                        tileExtent.getMaxY(), tileExtent.getMaxX(),
494
                                                                        tileExtent.getMinY(), 32, 32);
495
                                                } catch (RasterDriverException e) {
496
                                                        // TODO Auto-generated catch block
497
                                                        e.printStackTrace();
498
                                                } catch (InvalidSetViewException e) {
499
                                                        // TODO Auto-generated catch block
500
                                                        e.printStackTrace();
501
                                                } catch (InterruptedException e) {
502
                                                        // TODO Auto-generated catch block
503
                                                        e.printStackTrace();
504
                                                } catch (Exception e) {
505
                                                        return;
506
                                                }
507

    
508
                                                RasterBuffer raster = (RasterBuffer) bufferFactory
509
                                                .getRasterBuf();
510
                                                raster.setNoDataValue(0.0);
511
                                                raster.setNotValidValue(0.0);
512
                                                try {
513
                                                        WriterBufferServer bufferServer = new WriterBufferServer(
514
                                                                        raster);
515
                                                        Params p = GeoRasterWriter.getWriter(fName).getParams();
516
                                                        AffineTransform at = new AffineTransform(tileExtent
517
                                                                        .getWidth() / 32, 0, 0,
518
                                                                        -(tileExtent.getHeight() / 32), tileExtent
519
                                                                        .getMinX(), tileExtent.getMaxY());
520
                                                        GeoRasterWriter grw = GeoRasterWriter.getWriter(
521
                                                                        bufferServer, fName, 1, at, raster.getWidth(),
522
                                                                        raster.getHeight(), raster.getDataType(), p, null);
523
                                                        synchronized (cacheMutex) {
524
                                                                try {
525
                                                                        grw.dataWrite();
526
                                                                } catch (InterruptedException e) {
527
                                                                        e.printStackTrace();
528
                                                                }
529
                                                                grw.writeClose();
530
                                                        }
531

    
532
                                                } catch (NotSupportedExtensionException e) {
533
                                                        // e.printStackTrace();
534
                                                        return;
535
                                                } catch (RasterDriverException e) {
536
                                                        // e.printStackTrace();
537
                                                        return;
538
                                                } catch (IOException e) {
539
                                                        // e.printStackTrace();
540
                                                        return;
541
                                                }
542

    
543
                                        }
544
                        }
545
                }                
546

    
547
                //The method cant return a image because ImageIO crashes with tiff images.
548
                /*try {
549
                        synchronized (cacheMutex) {
550
                                image = ImageIO.read(new File(fName));
551
                        }
552
                } catch (IOException e) {
553
                        return null;
554
                }
555
                return image;*/
556
        }
557

    
558
        public String getTileAsFName(TileNum t, Rectangle2D extent)
559
        throws CacheServiceException {
560
                if (_loadFailed) {
561
                        throw new CacheServiceException(new Exception());
562
                }
563

    
564
                String fName = getTileFileName(t);
565
                boolean fileExists = false;
566
                synchronized (cacheMutex) {
567
                        fileExists = new File(fName).exists();
568
                }
569
                if (!fileExists) {
570
                        Rectangle2D tileExtent = extent;
571
                        requestTileFromLayer(fName,tileExtent);
572
                        //if (getTileFromLayer(fName, tileExtent) == null)
573
                        fName = null;
574
                }
575
                
576
                return fName;
577
        }
578

    
579
        /**
580
         * @TODO: This method crashes with tiff images use getTileAsFileName instead
581
         */
582
        public Image getTileAsImage(TileNum tileNum, Rectangle2D extent)
583
        throws CacheServiceException {
584

    
585
                if (_loadFailed) {
586
                        throw new CacheServiceException(new Exception());
587
                }
588
                String fName = getTileFileName(tileNum);
589
                Image image = null;
590
                boolean fileExists = false;
591
                synchronized (cacheMutex) {
592
                        fileExists = new File(fName).exists();
593
                }
594
                if (!fileExists) {
595
                        Rectangle2D tileExtent = extent;
596
                        requestTileFromLayer(fName,tileExtent);
597
                        //image = getTileFromLayer(fName, tileExtent);
598
                } else {
599
                        //ImageIO cant read tiff images. Change in the next version.
600
                        /*try {
601
                                //image = ImageIO.read(new File(fName));
602
                        } catch (IOException e) {
603
                                return null;
604
                        }*/
605
                }
606
                return image;
607
        }
608

    
609

    
610
        public boolean intersectsLayer(Rectangle2D extent) {
611
                return _lyrExtentRect.intersects(extent);
612
        }
613

    
614
        public void free() throws Throwable {
615
                _logger.info("finalizing cache service and thread");
616
                if(_requestTileFromLayerThread != null)
617
                        _requestTileFromLayerThread.setDone(true);
618
                if(_downloadMonitor != null)
619
                        _downloadMonitor.setDone(true);
620
                if(_requestThead != null)
621
                        _requestThead.join();
622
                if(_downloadMonitorThread != null)
623
                        _downloadMonitorThread.join();
624
        }
625

    
626

    
627
        /*@Override
628
        protected void finalize() throws Throwable {
629
                _logger.info("finalizing cache service and thread");
630
                _requestTileFromLayerThread.setDone(true);
631
                _requestThead.join();
632
                super.finalize();
633
        }*/
634
        
635
        protected class DownloadMonitor implements Runnable 
636
        {
637
                private volatile boolean _done = false;
638
                private volatile boolean _monitoring = false;
639
                private volatile long _time = 0;
640
                private volatile MyCancellable _cancellable = null;
641

    
642
                public void run() {
643
                        while(!_done) {
644
                                try {
645
                                        if(_monitoring && (System.currentTimeMillis() - _time > 5000))
646
                                        {
647
                                                if(_cancellable != null) _cancellable.setCanceled(true);
648
                                        }
649
                                        Thread.sleep(500);
650
                                } catch (InterruptedException e) {
651
                                        // TODO Auto-generated catch block
652
                                        e.printStackTrace();
653
                                }
654
                        }
655
                }
656
                
657
                public void monitorThis(MyCancellable cancellable, long initDownloadTime)
658
                {
659
                        _monitoring = true;
660
                        _time = initDownloadTime;
661
                        _cancellable = cancellable;
662
                }
663
                
664
                public void endMonitor()
665
                {
666
                        _monitoring = false;
667
                        // Cancel the download to finish the gvSIG monitor because is buged and 
668
                        // it never ends.
669
                        if(_cancellable != null) _cancellable.setCanceled(true);
670
                }
671

    
672
                public void setDone(boolean value) { _done = value; }
673
        }
674
}