Statistics
| Revision:

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

History | View | Annotate | Download (21.2 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.exolab.castor.xml.ValidationException;
23
import org.gvsig.cacheservice.CacheService;
24
import org.gvsig.cacheservice.CacheServiceException;
25
import org.gvsig.cacheservice.RasterCacheService;
26
import org.gvsig.cacheservice.TileNum;
27
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
28
import org.gvsig.osgvp.terrain.Terrain;
29
import org.gvsig.raster.buffer.BufferFactory;
30
import org.gvsig.raster.buffer.RasterBuffer;
31
import org.gvsig.raster.buffer.WriterBufferServer;
32
import org.gvsig.raster.dataset.GeoRasterWriter;
33
import org.gvsig.raster.dataset.InvalidSetViewException;
34
import org.gvsig.raster.dataset.NotSupportedExtensionException;
35
import org.gvsig.raster.dataset.Params;
36
import org.gvsig.raster.dataset.io.RasterDriverException;
37
import org.gvsig.remoteClient.utils.Utilities;
38
import org.gvsig.remoteClient.wcs.WCSStatus;
39
import org.gvsig.remoteClient.wms.ICancellable;
40
import org.gvsig.remoteClient.wms.WMSStatus;
41

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

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

    
68
        // WMS terrain
69
        FMapWMSDriver _wmsDriver = null;
70
        FMapWCSDriver _wcsDriver = null;
71

    
72
        WMSStatus _wmsStatus = null;
73
        WCSStatus _wcsStatus = null;
74

    
75
        Thread _requestThead = null;
76
        Thread _downloadMonitorThread = null;
77
        private RequestTileFromLayerThread _requestTileFromLayerThread;
78
        private DownloadMonitor _downloadMonitor;
79

    
80
        private static Logger _logger = Logger.getLogger(FLayerCacheService.class
81
                        .getName());
82

    
83
        public FLayerCacheService(Terrain terrain, String name, FLayer layer,
84
                        IProjection viewProj) {
85
                super(terrain.getTerrainName(), name);
86

    
87
                _layer = layer;
88
                _viewProj = viewProj;
89
                _loadFailed = true;
90

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

    
98
                try {
99
                        _lyrExtentRect = _layer.getFullExtent();
100
                } catch (ExpansionFileReadException e) {
101
                        e.printStackTrace();
102
                } catch (ReadDriverException e) {
103
                        e.printStackTrace();
104
                }
105

    
106
                Layer3DProps props3D = Layer3DProps.getLayer3DProps(layer);
107
                _dataType = props3D.getType();
108
                if (_dataType == Layer3DProps.layer3DImage)
109
                        setFileExtension(".png");
110
                else
111
                        setFileExtension(".tif");
112

    
113
                _loadFailed = false;
114

    
115
        }
116

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

    
152
        }
153

    
154
        protected class RequestTileFromLayerThread implements Runnable {
155

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

    
172
                private HashMap<String, Request> _requestList = new HashMap<String, Request>();
173
                private PriorityQueue<Request> _priorityRequestList = new PriorityQueue<Request>();
174
                private volatile boolean _done = false;
175

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

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

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

    
229
                }
230

    
231
                public void setDone(boolean value) { _done = value; }
232

    
233
        }
234

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

    
243
        }
244

    
245
        private void getTileFromLayer(String fName, Rectangle2D tileExtent) {
246
                BufferedImage image;
247

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

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

    
274
                                                        HashMap props = wmsLayer.getProperties();
275
                                                        Vector styles;
276
                                                        Vector dimensions;
277
                                                        styles = (Vector) (props.get("styles"));
278
                                                        dimensions = (Vector) (props.get("dimensions"));
279
                                                        _wmsStatus.setStyles(styles);
280
                                                        _wmsStatus.setDimensions(dimensions);
281
                                                        _wmsStatus.setTransparency((Boolean)props.get("wmsTransparency"));
282
                                                        String getMapStr = wmsLayer.getOnlineResource("GetMap");
283
                                                        _wmsStatus.setOnlineResource(getMapStr);
284
                                                }
285
                                                _wmsStatus.setExtent(tileExtent);
286
                                                
287
                                                // Build a cancellable
288
                                                MyCancellable cancelDownload = new MyCancellable(new MyCancel());
289
                                                
290
                                                //Run monitor thread for remote services
291
                                                if(_downloadMonitorThread == null) {
292
                                                        _downloadMonitor = new DownloadMonitor();
293
                                                        _downloadMonitorThread = new Thread(_downloadMonitor);
294
                                                        _downloadMonitorThread.start();
295
                                                }
296
                                                _downloadMonitor.monitorThis(cancelDownload, System.currentTimeMillis());
297
                                                File f = _wmsDriver.getMap(_wmsStatus, cancelDownload);
298
                                                _downloadMonitor.endMonitor();
299
                                                if (f == null)
300
                                                        return;
301
                                                synchronized (cacheMutex) {
302
                                                        FileUtils.copy(f, new File(fName));
303
                                                }
304
//                                                wmsLayer.setName(f.getName());
305
//                                                wmsLayer.setLoadParams(f);
306
//                                                wmsLayer.load();
307
                                                //wmsLayer.init();
308
                                        } catch (Exception e) {
309
                                                return;
310
                                        }
311
                                } else {
312
                                        int size = getTileSize();
313
                                        image = new BufferedImage(size, size,
314
                                                        BufferedImage.TYPE_INT_ARGB);
315

    
316
                                        ViewPort vp = new ViewPort(_viewProj);
317
                                        vp.setExtent(tileExtent); // the real extent of the tile
318
                                        // NotificationManager.addInfo("Extent solicitado--> "
319
                                        // + tileExtent.getMinX() + " " + tileExtent.getMinY() + " "
320
                                        // + tileExtent.getMaxX() + " " + tileExtent.getMaxY());
321
                                        vp.setAdjustable(false);
322
                                        vp.setImageSize(new Dimension(size, size));
323
                                        // vp.setDist1pixel(1 / 150000);
324
                                        vp.setDist1pixel(0.000000001);
325

    
326
                                        Graphics2D graphics = image.createGraphics();
327
                                        Color backgColor = new Color(255, 255, 255, 0); // transparent
328
                                        // background
329
                                        graphics.setColor(backgColor);
330
                                        graphics.fillRect(0, 0, size, size);
331

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

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

    
350
                                        }
351

    
352
                                        if (_layer instanceof FLyrRasterSE) {
353
                                                // fix opaque the layer to save in disk
354
                                                ((FLyrRasterSE) _layer).setTransparency(255);
355
                                        }
356

    
357
                                        try {
358
                                                _layer.draw(image, graphics, vp, new MyCancel(), scale);
359
                                                if ((_layer.getClass().equals(FLyrVect.class))&& ((FLyrVect)_layer).isLabeled())
360
                                                        ((FLyrVect)_layer).drawLabels(image, graphics, vp, new MyCancel(), scale,72);
361

    
362
                                        } catch (Exception e) {
363
                                                return;
364
                                        }
365
                                        // Restoring the real value of transparency
366
                                        if (_layer.getClass().equals(FLyrVect.class)) {
367
                                                // fix the real transparency to the layer
368
                                                ((FLyrDefault) _layer).setTransparency(trans);
369
                                        }
370

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

    
388
                                                        URL host = wmsLayer.getHost();
389
                                                        _wmsDriver = FMapWMSDriverFactory
390
                                                        .getFMapDriverForURL(host);
391
                                                }
392
                                                if (_wmsStatus == null) {
393
                                                        _wmsStatus = new WMSStatus();
394
                                                        _wmsStatus.setFormat(wmsLayer.getFormat());
395
                                                        _wmsStatus.setHeight(32);
396
                                                        _wmsStatus.setWidth(32);
397
                                                        _wmsStatus.setLayerNames(Utilities.createVector(
398
                                                                        wmsLayer.getLayerQuery(), ","));
399
                                                        _wmsStatus.setSrs(wmsLayer.getSRS());
400

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

    
429
                                                synchronized (cacheMutex) {
430
                                                        FileUtils.copy(f, new File(fName));
431
                                                }
432

    
433
                                        } catch (Exception e) {
434
                                                return;
435
                                        }
436
                                } else if (_layer instanceof FLyrWCS) { // WCS Elevation
437
                                        try {
438
                                                FLyrWCS wcsLayer = (FLyrWCS) _layer;
439
                                                if (_wcsDriver == null) {
440

    
441
                                                        URL host = wcsLayer.getHost();
442
                                                        _wcsDriver = FMapWCSDriverFactory
443
                                                        .getFMapDriverForURL(host);
444
                                                }
445
                                                if (_wcsStatus == null) {
446
                                                        _wcsStatus = new WCSStatus();
447

    
448
                                                        Hashtable props = wcsLayer.getProperties();
449

    
450
                                                        _wcsStatus.setCoveraName((String) props.get("name"));
451
                                                        _wcsStatus.setFormat((String) props.get("format"));
452
                                                        _wcsStatus.setHeight(32);
453
                                                        _wcsStatus.setWidth(32);
454
                                                        _wcsStatus.setSrs((String) props.get("crs"));
455
                                                        _wcsStatus.setParameters((String) props
456
                                                                        .get("parameter"));
457
                                                        String time = (String) props.get("time");
458
                                                        if (time.length() > 0)
459
                                                                _wcsStatus.setTime(time);
460
                                                }
461
                                                _wcsStatus.setExtent(tileExtent);
462

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

    
487
                                                FLyrRasterSE rasterLayer = (FLyrRasterSE) _layer;
488
                                                BufferFactory bufferFactory = rasterLayer.getBufferFactory();
489

    
490
                                                //int bands[] = { 0 };
491
                                                bufferFactory.setAllDrawableBands();
492
                                                bufferFactory.setAdjustToExtent(false);
493
                                                bufferFactory.setNoDataToFill(0.0);
494

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

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

    
538
                                                } catch (NotSupportedExtensionException e) {
539
                                                        // e.printStackTrace();
540
                                                        return;
541
                                                } catch (RasterDriverException e) {
542
                                                        // e.printStackTrace();
543
                                                        return;
544
                                                } catch (IOException e) {
545
                                                        // e.printStackTrace();
546
                                                        return;
547
                                                }
548

    
549
                                        }
550
                        }
551
                }                
552

    
553
                //The method cant return a image because ImageIO crashes with tiff images.
554
                /*try {
555
                        synchronized (cacheMutex) {
556
                                image = ImageIO.read(new File(fName));
557
                        }
558
                } catch (IOException e) {
559
                        return null;
560
                }
561
                return image;*/
562
        }
563

    
564
        public String getTileAsFName(TileNum t, Rectangle2D extent)
565
        throws CacheServiceException {
566
                if (_loadFailed) {
567
                        throw new CacheServiceException(new Exception());
568
                }
569

    
570
                String fName = getTileFileName(t);
571
                boolean fileExists = false;
572
                synchronized (cacheMutex) {
573
                        fileExists = new File(fName).exists();
574
                }
575
                if (!fileExists) {
576
                        Rectangle2D tileExtent = extent;
577
                        requestTileFromLayer(fName,tileExtent);
578
                        //if (getTileFromLayer(fName, tileExtent) == null)
579
                        fName = null;
580
                }
581
                
582
                return fName;
583
        }
584

    
585
        /**
586
         * @TODO: This method crashes with tiff images use getTileAsFileName instead
587
         */
588
        public Image getTileAsImage(TileNum tileNum, Rectangle2D extent)
589
        throws CacheServiceException {
590

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

    
615

    
616
        public boolean intersectsLayer(Rectangle2D extent) {
617
                return _lyrExtentRect.intersects(extent);
618
        }
619

    
620
        public void free() throws Throwable {
621
                _logger.info("finalizing cache service and thread");
622
                if(_requestTileFromLayerThread != null)
623
                        _requestTileFromLayerThread.setDone(true);
624
                if(_downloadMonitor != null)
625
                        _downloadMonitor.setDone(true);
626
                _requestThead.join();
627
                _downloadMonitorThread.join();
628
        }
629

    
630
        public WMSStatus getWMSStatus(){
631
                
632
                return _wmsStatus; 
633
                
634
        }
635
        /*@Override
636
        protected void finalize() throws Throwable {
637
                _logger.info("finalizing cache service and thread");
638
                _requestTileFromLayerThread.setDone(true);
639
                _requestThead.join();
640
                super.finalize();
641
        }*/
642
        
643
        protected class DownloadMonitor implements Runnable 
644
        {
645
                private volatile boolean _done = false;
646
                private volatile boolean _monitoring = false;
647
                private volatile long _time = 0;
648
                private volatile MyCancellable _cancellable = null;
649

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

    
680
                public void setDone(boolean value) { _done = value; }
681
        }
682
}