Statistics
| Revision:

svn-gvsig-desktop / branches / gvSIG_19_ext3D_osgVP_2_2_0 / libraries / lib3DMap / src / org / gvsig / gvsig3d / cacheservices / FLayerCacheService.java @ 31887

History | View | Annotate | Download (16.4 KB)

1 21940 jcampos
package org.gvsig.gvsig3d.cacheservices;
2 14899 salva
3
import java.awt.Color;
4
import java.awt.Dimension;
5
import java.awt.Graphics2D;
6
import java.awt.Image;
7 16292 jcampos
import java.awt.geom.AffineTransform;
8 14899 salva
import java.awt.geom.Rectangle2D;
9
import java.awt.image.BufferedImage;
10
import java.io.File;
11
import java.io.IOException;
12 15441 julio
import java.net.URL;
13 31741 rgaitan
import java.util.ArrayList;
14 15441 julio
import java.util.HashMap;
15
import java.util.Hashtable;
16 31741 rgaitan
import java.util.Iterator;
17 31738 rgaitan
import java.util.PriorityQueue;
18 15441 julio
import java.util.Vector;
19 14899 salva
20 31726 rgaitan
import javax.imageio.ImageIO;
21
22 31741 rgaitan
import org.apache.log4j.Logger;
23 14899 salva
import org.cresques.cts.IProjection;
24 14922 salva
import org.gvsig.cacheservice.CacheService;
25 14917 salva
import org.gvsig.cacheservice.CacheServiceException;
26
import org.gvsig.cacheservice.RasterCacheService;
27
import org.gvsig.cacheservice.TileNum;
28 15405 julio
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
29 31741 rgaitan
import org.gvsig.gvsig3d.map3d.MapContext3D;
30 31394 mten
import org.gvsig.osgvp.terrain.Terrain;
31 16292 jcampos
import org.gvsig.raster.buffer.BufferFactory;
32
import org.gvsig.raster.buffer.RasterBuffer;
33 18954 jcampos
import org.gvsig.raster.buffer.WriterBufferServer;
34 16292 jcampos
import org.gvsig.raster.dataset.GeoRasterWriter;
35
import org.gvsig.raster.dataset.InvalidSetViewException;
36
import org.gvsig.raster.dataset.NotSupportedExtensionException;
37
import org.gvsig.raster.dataset.Params;
38 16723 rgaitan
import org.gvsig.raster.dataset.io.RasterDriverException;
39 15441 julio
import org.gvsig.remoteClient.utils.Utilities;
40 15082 salva
import org.gvsig.remoteClient.wcs.WCSStatus;
41 14933 salva
import org.gvsig.remoteClient.wms.ICancellable;
42
import org.gvsig.remoteClient.wms.WMSStatus;
43 14922 salva
44 15339 julio
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
45 22171 jcampos
import com.iver.ai2.gvsig3d.map3d.layers.Layer3DProps;
46 15339 julio
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
47 14899 salva
import com.iver.cit.gvsig.fmap.ViewPort;
48 15441 julio
import com.iver.cit.gvsig.fmap.drivers.wcs.FMapWCSDriver;
49
import com.iver.cit.gvsig.fmap.drivers.wcs.FMapWCSDriverFactory;
50
import com.iver.cit.gvsig.fmap.drivers.wms.FMapWMSDriver;
51
import com.iver.cit.gvsig.fmap.drivers.wms.FMapWMSDriverFactory;
52 14899 salva
import com.iver.cit.gvsig.fmap.layers.FLayer;
53 15485 julio
import com.iver.cit.gvsig.fmap.layers.FLyrDefault;
54 15851 jcampos
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
55 15441 julio
import com.iver.cit.gvsig.fmap.layers.FLyrWCS;
56
import com.iver.cit.gvsig.fmap.layers.FLyrWMS;
57
import com.iver.utiles.FileUtils;
58 14914 salva
import com.iver.utiles.swing.threads.Cancellable;
59 14899 salva
60
public class FLayerCacheService extends RasterCacheService {
61 31738 rgaitan
        private boolean _loadFailed = true;
62 14899 salva
        private Rectangle2D _lyrExtentRect;
63 31738 rgaitan
        private FLayer _layer;
64 14927 salva
        private IProjection _viewProj;
65 31738 rgaitan
        private int _dataType;
66 14927 salva
67 14933 salva
        // WMS terrain
68 31738 rgaitan
        FMapWMSDriver _wmsDriver = null;
69
        FMapWCSDriver _wcsDriver = null;
70 14933 salva
71 31738 rgaitan
        WMSStatus _wmsStatus = null;
72
        WCSStatus _wcsStatus = null;
73
74
        Thread _requestThead = null;
75
        private RequestTileFromLayerThread _requestTileFromLayerThread;
76 31741 rgaitan
77
        private static Logger _logger = Logger.getLogger(FLayerCacheService.class
78
                        .getName());
79 17036 jcampos
80 31394 mten
        public FLayerCacheService(Terrain terrain, String name, FLayer layer,
81 17036 jcampos
                        IProjection viewProj) {
82 31394 mten
                super(terrain.getTerrainName(), name);
83 14899 salva
84
                _layer = layer;
85 14927 salva
                _viewProj = viewProj;
86 14899 salva
                _loadFailed = true;
87
88 14922 salva
                int cacheType = CacheService.GLOBAL;
89 31394 mten
                if (terrain.getCoordinateSystemType() == Terrain.CoordinateSystemType.GEOCENTRIC)
90 17036 jcampos
                        cacheType += SPHERIC;
91 14922 salva
                else
92 17036 jcampos
                        cacheType += PLANE;
93 14922 salva
                setCacheType(cacheType);
94
95 14927 salva
                try {
96 14899 salva
                        _lyrExtentRect = _layer.getFullExtent();
97 15339 julio
                } catch (ExpansionFileReadException e) {
98
                        e.printStackTrace();
99
                } catch (ReadDriverException e) {
100
                        e.printStackTrace();
101 14899 salva
                }
102
103 14970 salva
                Layer3DProps props3D = Layer3DProps.getLayer3DProps(layer);
104 14933 salva
                _dataType = props3D.getType();
105 17036 jcampos
                if (_dataType == Layer3DProps.layer3DImage)
106 14933 salva
                        setFileExtension(".png");
107
                else
108
                        setFileExtension(".tif");
109
110 14899 salva
                _loadFailed = false;
111 14933 salva
112 14899 salva
        }
113
114 17036 jcampos
        protected class MyCancel implements Cancellable, ICancellable {
115 14933 salva
116 14914 salva
                public boolean isCanceled() {
117
                        return false;
118
                }
119 14899 salva
120 14914 salva
                public void setCanceled(boolean canceled) {
121 14899 salva
122 14914 salva
                }
123 14899 salva
124 31726 rgaitan
                /* if you don�t put and ID the wms donwload will be fail */
125 15372 afraile
                public Object getID() {
126 17036 jcampos
                        return this;
127 15372 afraile
                }
128
129 17036 jcampos
        }
130 31738 rgaitan
131
        protected class RequestTileFromLayerThread implements Runnable {
132
133
                private class Request implements Comparable<Request> {
134
                        public Request(long timeStamp, String fName, Rectangle2D tileExtent) {
135
                                _timeStamp = timeStamp;
136
                                _fName = fName;
137
                                _tileExtent = tileExtent;
138
                        }
139
                        long _timeStamp;
140
                        String _fName;
141
                        Rectangle2D _tileExtent;
142
                        public int compareTo(Request o) {
143 31887 rgaitan
                                if(_timeStamp > o._timeStamp) return -1;
144
                                else if(_timeStamp < o._timeStamp) return 1;
145 31738 rgaitan
                                else return 0;
146
                        }
147
                }
148
149
                private HashMap<String, Request> _requestList = new HashMap<String, Request>();
150
                private PriorityQueue<Request> _priorityRequestList = new PriorityQueue<Request>();
151
                private volatile boolean _done = false;
152
153 31741 rgaitan
                protected synchronized void purgeOldRequests() {
154
                        int max_elements = 100;
155
                        if(_requestList.size() > max_elements) {
156
                                _logger.debug("max elements reached from request list thread...");
157
                                Iterator<Request> iterator = _requestList.values().iterator();
158
                                ArrayList<Request> removeRequests = new ArrayList<Request>();
159
                                int index = 0;
160
                                while(iterator.hasNext()) {
161
                                        Request request = iterator.next();
162
                                        if(index>max_elements) {
163
                                                removeRequests.add(request);
164
                                        }
165
                                        index++;
166
                                }
167
                                for(int i=0;i<removeRequests.size();i++) {
168
                                        _logger.debug("Removing old elements from request list thread...");
169
                                        _priorityRequestList.remove(removeRequests.get(i));
170
                                        _requestList.remove(removeRequests.get(i)._fName);
171
                                }
172
                        }
173
                }
174
175 31738 rgaitan
                public synchronized void requestTile(String fName, Rectangle2D tileExtent) {
176
                        Request request = _requestList.get(fName);
177
                        if(request == null) {
178
                                Request req = new Request(System.currentTimeMillis(),fName,tileExtent);
179
                                _requestList.put(fName,req);
180
                                _priorityRequestList.add(req);
181
                        } else {
182
                                request._timeStamp = System.currentTimeMillis();
183
                        }
184 31741 rgaitan
                        purgeOldRequests();
185 31738 rgaitan
                }
186
187
                public void run() {
188
                        while(!_done) {
189
                                Request request = null;
190
                                synchronized (this) {
191
                                        request = _priorityRequestList.poll();
192
                                }
193
                                if(request != null) {
194 31741 rgaitan
                                        _requestList.remove(request._fName);
195 31738 rgaitan
                                        getTileFromLayer(request._fName, request._tileExtent);
196
                                }
197
                                else {
198
                                        try {
199
                                                Thread.sleep(1);
200
                                        } catch (InterruptedException e) {
201
                                                e.printStackTrace();
202
                                        }
203
                                }
204
                        }
205
206
                }
207
208
                public void setDone(boolean value) { _done = value; }
209
210
        }
211
212
        private void requestTileFromLayer(String fName, Rectangle2D tileExtent) {
213
                if(_requestThead == null) {
214
                        _requestTileFromLayerThread = new RequestTileFromLayerThread();
215
                        _requestThead = new Thread(_requestTileFromLayerThread);
216
                        _requestThead.start();
217
                }
218
                _requestTileFromLayerThread.requestTile(fName, tileExtent);
219
220
        }
221 14899 salva
222 17036 jcampos
        private Image getTileFromLayer(String fName, Rectangle2D tileExtent) {
223 14933 salva
                BufferedImage image;
224 17036 jcampos
                if (_dataType == Layer3DProps.layer3DImage) {
225 31738 rgaitan
                        // Workaround to avoid too many System.gc() calls on layer.draw. which makes
226
                        // rendering stall when rendering the tile.
227
                        if (_layer instanceof FLyrWMS) { // WMS Elevation
228
                                try {
229
                                        FLyrWMS wmsLayer = (FLyrWMS) _layer;
230
                                        if (_wmsDriver == null) {
231 14899 salva
232 31738 rgaitan
                                                URL host = wmsLayer.getHost();
233
                                                _wmsDriver = FMapWMSDriverFactory
234
                                                                .getFMapDriverForURL(host);
235
                                        }
236
                                        if (_wmsStatus == null) {
237
                                                _wmsStatus = new WMSStatus();
238
                                                _wmsStatus.setFormat(wmsLayer.getFormat());
239
                                                _wmsStatus.setHeight(256);
240
                                                _wmsStatus.setWidth(256);
241
                                                _wmsStatus.setLayerNames(Utilities.createVector(
242
                                                                wmsLayer.getLayerQuery(), ","));
243
                                                _wmsStatus.setSrs(wmsLayer.getSRS());
244 14899 salva
245 31738 rgaitan
                                                HashMap props = wmsLayer.getProperties();
246
                                                Vector styles;
247
                                                Vector dimensions;
248
                                                styles = (Vector) (props.get("styles"));
249
                                                dimensions = (Vector) (props.get("dimensions"));
250
                                                _wmsStatus.setStyles(styles);
251
                                                _wmsStatus.setDimensions(dimensions);
252
                                                _wmsStatus.setTransparency((Boolean)props.get("wmsTransparency"));
253
                                                String getMapStr = wmsLayer.getOnlineResource("GetMap");
254
                                                _wmsStatus.setOnlineResource(getMapStr);
255
                                        }
256
                                        _wmsStatus.setExtent(tileExtent);
257
                                        File f = _wmsDriver.getMap(_wmsStatus, new MyCancel());
258
                                        if (f == null)
259
                                                return null;
260
                                        synchronized (this) {
261
                                                FileUtils.copy(f, new File(fName));
262
                                        }
263
                                } catch (Exception e) {
264
                                        return null;
265
                                }
266
                        } else {
267
                                int size = getTileSize();
268
                                image = new BufferedImage(size, size,
269
                                                BufferedImage.TYPE_INT_ARGB);
270 14899 salva
271 31738 rgaitan
                                ViewPort vp = new ViewPort(_viewProj);
272
                                vp.setExtent(tileExtent); // the real extent of the tile
273
                                // NotificationManager.addInfo("Extent solicitado--> "
274
                                // + tileExtent.getMinX() + " " + tileExtent.getMinY() + " "
275
                                // + tileExtent.getMaxX() + " " + tileExtent.getMaxY());
276
                                vp.setAdjustable(false);
277
                                vp.setImageSize(new Dimension(size, size));
278
                                // vp.setDist1pixel(1 / 150000);
279
                                vp.setDist1pixel(0.000000001);
280 17036 jcampos
281 31738 rgaitan
                                Graphics2D graphics = image.createGraphics();
282
                                Color backgColor = new Color(255, 255, 255, 0); // transparent
283
                                // background
284
                                graphics.setColor(backgColor);
285
                                graphics.fillRect(0, 0, size, size);
286 17036 jcampos
287 31738 rgaitan
                                // CancelDraw canceldraw = new MapControl.CancelDraw();
288
                                // canceldraw.setCanceled(false);
289
                                // For now we'll use a trick to make sure the layer is drawn
290
                                // even if it has scale dependency
291
                                // In the future, a scale corresponding to the tile should be
292
                                // passed
293
                                double scale = 0.5 * (_layer.getMaxScale() + _layer
294
                                                .getMinScale());
295
                                int trans = 255;
296 14933 salva
297 31738 rgaitan
                                // The layers of remote services don�t have transparency.
298
                                if (_layer.getClass().equals(FLyrVect.class)) {
299
                                        // Generate layers 3D properties
300
                                        Layer3DProps props3D = Layer3DProps.getLayer3DProps(_layer);
301
                                        // fix opaque the layer to save in disk
302
                                        ((FLyrDefault) _layer).setTransparency((int) (props3D
303
                                                        .getOpacity() * 255));
304
                                }
305 31741 rgaitan
306
                                if (_layer instanceof FLyrRasterSE) {
307
                                        // fix opaque the layer to save in disk
308
                                        ((FLyrRasterSE) _layer).setTransparency(255);
309
                                }
310 31738 rgaitan
311
                                try {
312
                                        _layer.draw(image, graphics, vp, new MyCancel(), scale);
313
                                } catch (Exception e) {
314
                                        return null;
315
                                }
316
                                // Restoring the real value of transparency
317
                                if (_layer.getClass().equals(FLyrVect.class)) {
318
                                        // fix the real transparency to the layer
319
                                        ((FLyrDefault) _layer).setTransparency(trans);
320
                                }
321
322
                                try {
323
                                        File file = new File(fName);
324
                                        String format = getFileExtension().substring(1);
325
                                        synchronized (this) {
326
                                                saveCachedFile(image, format, file);
327
                                        }
328
                                } catch (IOException e1) {
329
                                        e1.printStackTrace();
330
                                        return null;
331
                                }
332 14933 salva
                        }
333 17036 jcampos
                } else { // Elevation data
334
                        if (_layer instanceof FLyrWMS) { // WMS Elevation
335
                                try {
336
                                        FLyrWMS wmsLayer = (FLyrWMS) _layer;
337
                                        if (_wmsDriver == null) {
338
339
                                                URL host = wmsLayer.getHost();
340
                                                _wmsDriver = FMapWMSDriverFactory
341
                                                                .getFMapDriverForURL(host);
342
                                        }
343
                                        if (_wmsStatus == null) {
344
                                                _wmsStatus = new WMSStatus();
345
                                                _wmsStatus.setFormat(wmsLayer.getFormat());
346
                                                _wmsStatus.setHeight(32);
347
                                                _wmsStatus.setWidth(32);
348
                                                _wmsStatus.setLayerNames(Utilities.createVector(
349
                                                                wmsLayer.getLayerQuery(), ","));
350
                                                _wmsStatus.setSrs(wmsLayer.getSRS());
351
352
                                                HashMap props = wmsLayer.getProperties();
353
                                                Vector styles;
354
                                                Vector dimensions;
355
                                                styles = (Vector) (props.get("styles"));
356
                                                dimensions = (Vector) (props.get("dimensions"));
357
                                                _wmsStatus.setStyles(styles);
358
                                                _wmsStatus.setDimensions(dimensions);
359
                                                _wmsStatus.setTransparency(false);
360
                                                String getMapStr = wmsLayer.getOnlineResource("GetMap");
361
                                                _wmsStatus.setOnlineResource(getMapStr);
362
                                        }
363
                                        _wmsStatus.setExtent(tileExtent);
364
                                        File f = _wmsDriver.getMap(_wmsStatus, new MyCancel());
365
                                        if (f == null)
366
                                                return null;
367 31738 rgaitan
                                        synchronized (this) {
368
                                                FileUtils.copy(f, new File(fName));
369
                                        }
370 17036 jcampos
                                } catch (Exception e) {
371
                                        return null;
372
                                }
373
                        } else if (_layer instanceof FLyrWCS) { // WCS Elevation
374
                                try {
375
                                        FLyrWCS wcsLayer = (FLyrWCS) _layer;
376
                                        if (_wcsDriver == null) {
377
378
                                                URL host = wcsLayer.getHost();
379
                                                _wcsDriver = FMapWCSDriverFactory
380
                                                                .getFMapDriverForURL(host);
381
                                        }
382
                                        if (_wcsStatus == null) {
383
                                                _wcsStatus = new WCSStatus();
384
385
                                                Hashtable props = wcsLayer.getProperties();
386
387
                                                _wcsStatus.setCoveraName((String) props.get("name"));
388
                                                _wcsStatus.setFormat((String) props.get("format"));
389
                                                _wcsStatus.setHeight(32);
390
                                                _wcsStatus.setWidth(32);
391
                                                _wcsStatus.setSrs((String) props.get("crs"));
392
                                                _wcsStatus.setParameters((String) props
393
                                                                .get("parameter"));
394
                                                String time = (String) props.get("time");
395
                                                if (time.length() > 0)
396
                                                        _wcsStatus.setTime(time);
397
                                        }
398
                                        _wcsStatus.setExtent(tileExtent);
399
400
                                        File f = _wcsDriver.getCoverage(_wcsStatus, new MyCancel());
401
                                        if (f == null)
402
                                                return null;
403 31738 rgaitan
                                        synchronized (this) {
404
                                                FileUtils.copy(f, new File(fName));
405
                                        }
406 17036 jcampos
                                } catch (Exception e) {
407
                                        return null;
408
                                }
409
                        }
410 15082 salva
                        // RASTER_GRID
411 17036 jcampos
                        if (_layer instanceof FLyrRasterSE) {
412
413 31394 mten
                                FLyrRasterSE rasterLayer = (FLyrRasterSE) _layer;
414 17036 jcampos
                                BufferFactory bufferFactory = new BufferFactory(rasterLayer
415
                                                .getDataSource());
416
417
                                int bands[] = { 0 };
418 15405 julio
                                bufferFactory.setDrawableBands(bands);
419 31726 rgaitan
                                bufferFactory.setAdjustToExtent(true);
420 15273 salva
421 16292 jcampos
                                try {
422
                                        bufferFactory.setAreaOfInterest(tileExtent.getMinX(),
423 25560 jcampos
                                                        tileExtent.getMinY(), tileExtent.getMaxX(),
424
                                                        tileExtent.getMaxY(), 32, 32);
425 16292 jcampos
                                } catch (ArrayIndexOutOfBoundsException e1) {
426 31726 rgaitan
                                        return null;
427 16292 jcampos
                                } catch (InvalidSetViewException e1) {
428 31726 rgaitan
                                        return null;
429 16292 jcampos
                                } catch (InterruptedException e1) {
430 31726 rgaitan
                                        return null;
431 16723 rgaitan
                                } catch (RasterDriverException e) {
432 31726 rgaitan
                                        return null;
433 16292 jcampos
                                }
434 15405 julio
435
                                RasterBuffer raster = (RasterBuffer) bufferFactory
436
                                                .getRasterBuf();
437 17848 jcampos
                                raster.setNoDataValue(0.0);
438 15076 salva
                                try {
439 15405 julio
                                        WriterBufferServer bufferServer = new WriterBufferServer(
440
                                                        raster);
441
                                        Params p = GeoRasterWriter.getWriter(fName).getParams();
442
                                        AffineTransform at = new AffineTransform(tileExtent
443
                                                        .getWidth() / 32, 0, 0,
444
                                                        -(tileExtent.getHeight() / 32), tileExtent
445
                                                                        .getMinX(), tileExtent.getMaxY());
446
                                        GeoRasterWriter grw = GeoRasterWriter.getWriter(
447
                                                        bufferServer, fName, 1, at, raster.getWidth(),
448
                                                        raster.getHeight(), raster.getDataType(), p, null);
449 31738 rgaitan
                                        synchronized (this) {
450
                                                try {
451
                                                        grw.dataWrite();
452
                                                } catch (InterruptedException e) {
453
                                                        e.printStackTrace();
454
                                                }
455
                                                grw.writeClose();
456 16292 jcampos
                                        }
457 31738 rgaitan
458 15405 julio
                                } catch (NotSupportedExtensionException e) {
459 31738 rgaitan
                                        // e.printStackTrace();
460 31726 rgaitan
                                        return null;
461 15405 julio
                                } catch (RasterDriverException e) {
462 31738 rgaitan
                                        // e.printStackTrace();
463 31726 rgaitan
                                        return null;
464 15339 julio
                                } catch (IOException e) {
465 31738 rgaitan
                                        // e.printStackTrace();
466 31726 rgaitan
                                        return null;
467 14933 salva
                                }
468 16292 jcampos
469 15076 salva
                        }
470 14933 salva
                }
471 31726 rgaitan
                try {
472
                        image = ImageIO.read(new File(fName));
473
                } catch (IOException e) {
474
                        return null;
475
                }
476
                return image;
477 14899 salva
        }
478
479 21095 jcampos
        public String getTileAsFName(TileNum t, Rectangle2D extent)
480
                        throws CacheServiceException {
481 17036 jcampos
                if (_loadFailed) {
482
                        throw new CacheServiceException(new Exception());
483 16292 jcampos
                }
484 31738 rgaitan
485 14899 salva
                String fName = getTileFileName(t);
486 31738 rgaitan
                boolean fileExists = false;
487
                synchronized (this) {
488
                        fileExists = new File(fName).exists();
489
                }
490
                if (!fileExists) {
491 15664 jcampos
                        Rectangle2D tileExtent = extent;
492 31738 rgaitan
                        requestTileFromLayer(fName,tileExtent);
493
                        //if (getTileFromLayer(fName, tileExtent) == null)
494
                        fName = null;
495 15664 jcampos
                }
496
                return fName;
497
        }
498 14899 salva
499 21095 jcampos
        public Image getTileAsImage(TileNum tileNum, Rectangle2D extent)
500
                        throws CacheServiceException {
501 17036 jcampos
502
                if (_loadFailed) {
503
                        throw new CacheServiceException(new Exception());
504
                }
505 14899 salva
                String fName = getTileFileName(tileNum);
506 31738 rgaitan
                Image image = null;
507
                boolean fileExists = false;
508
                synchronized (this) {
509
                        fileExists = new File(fName).exists();
510
                }
511
                if (!fileExists) {
512
                        Rectangle2D tileExtent = extent;
513
                        requestTileFromLayer(fName,tileExtent);
514
                        //image = getTileFromLayer(fName, tileExtent);
515
                } else {
516
                        try {
517
                                image = ImageIO.read(new File(fName));
518
                        } catch (IOException e) {
519
                                return null;
520
                        }
521
                }
522
                return image;
523 14899 salva
        }
524
525 15664 jcampos
        public boolean intersectsLayer(Rectangle2D extent) {
526
                return _lyrExtentRect.intersects(extent);
527
        }
528 31887 rgaitan
529
        @Override
530
        protected void finalize() throws Throwable {
531
                _logger.info("finalizing cache service and thread");
532
                _requestTileFromLayerThread.setDone(true);
533
                _requestThead.join();
534
                super.finalize();
535
        }
536 14922 salva
537 14899 salva
}