Statistics
| Revision:

gvsig-raster / org.gvsig.raster.tilecache / branches / org.gvsig.raster.tilecache_dataaccess_refactoring / org.gvsig.raster.tilecache.io / src / main / java / org / gvsig / raster / tilecache / io / TileProvider.java @ 2312

History | View | Annotate | Download (31.8 KB)

1
package org.gvsig.raster.tilecache.io;
2

    
3
import java.awt.Image;
4
import java.awt.geom.AffineTransform;
5
import java.awt.geom.NoninvertibleTransformException;
6
import java.awt.geom.Point2D;
7
import java.io.File;
8
import java.io.FileNotFoundException;
9
import java.io.IOException;
10
import java.lang.reflect.Constructor;
11
import java.lang.reflect.InvocationTargetException;
12
import java.util.List;
13

    
14
import org.gvsig.compat.net.ICancellable;
15
import org.gvsig.fmap.dal.DALLocator;
16
import org.gvsig.fmap.dal.DataStore;
17
import org.gvsig.fmap.dal.DataStoreParameters;
18
import org.gvsig.fmap.dal.coverage.RasterLibrary;
19
import org.gvsig.fmap.dal.coverage.RasterLocator;
20
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
21
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
22
import org.gvsig.fmap.dal.coverage.datastruct.DatasetBand;
23
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
24
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
25
import org.gvsig.fmap.dal.coverage.exception.BandNotFoundInListException;
26
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
27
import org.gvsig.fmap.dal.coverage.exception.FileNotSupportedException;
28
import org.gvsig.fmap.dal.coverage.exception.InfoByPointException;
29
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
30
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
31
import org.gvsig.fmap.dal.coverage.exception.ParsingException;
32
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
33
import org.gvsig.fmap.dal.coverage.exception.QueryException;
34
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
35
import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException;
36
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
37
import org.gvsig.fmap.dal.coverage.store.parameter.MultiDimensionalStoreParameters;
38
import org.gvsig.fmap.dal.coverage.store.parameter.RasterDataParameters;
39
import org.gvsig.fmap.dal.coverage.store.parameter.RemoteStoreParameters;
40
import org.gvsig.fmap.dal.coverage.store.parameter.TileDataParameters;
41
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
42
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
43
import org.gvsig.fmap.dal.coverage.util.MathUtils;
44
import org.gvsig.fmap.dal.exception.InitializeException;
45
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
46
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
47
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
48
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
49
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
50
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
51
import org.gvsig.fmap.dal.spi.DataStoreProvider;
52
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
53
import org.gvsig.metadata.MetadataLocator;
54
import org.gvsig.raster.cache.tile.Tile;
55
import org.gvsig.raster.cache.tile.TileCache;
56
import org.gvsig.raster.cache.tile.TileCacheLibrary;
57
import org.gvsig.raster.cache.tile.TileCacheLocator;
58
import org.gvsig.raster.cache.tile.TileCacheManager;
59
import org.gvsig.raster.cache.tile.exception.TileBuildException;
60
import org.gvsig.raster.cache.tile.exception.TileGettingException;
61
import org.gvsig.raster.cache.tile.layer.TiledLayer;
62
import org.gvsig.raster.cache.tile.provider.CacheStruct;
63
import org.gvsig.raster.cache.tile.provider.TileServer;
64
import org.gvsig.raster.impl.buffer.SpiRasterQuery;
65
import org.gvsig.raster.impl.datastruct.BandListImpl;
66
import org.gvsig.raster.impl.datastruct.DatasetBandImpl;
67
import org.gvsig.raster.impl.datastruct.ExtentImpl;
68
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
69
import org.gvsig.raster.impl.provider.MemoryTileMatrixBuffer;
70
import org.gvsig.raster.impl.provider.RasterProvider;
71
import org.gvsig.raster.impl.provider.RemoteRasterProvider;
72
import org.gvsig.raster.impl.provider.TiledRasterProvider;
73
import org.gvsig.raster.impl.store.DefaultRasterStore;
74
import org.gvsig.raster.impl.store.DefaultStoreFactory;
75
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
76
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
77
import org.gvsig.raster.impl.store.properties.RemoteDataStoreStatistics;
78
import org.gvsig.tools.ToolsLocator;
79
import org.gvsig.tools.locator.LocatorException;
80
import org.slf4j.Logger;
81
import org.slf4j.LoggerFactory;
82

    
83
/**
84
 * Provider for WMTS service
85
 *
86
 * @author Nacho Brodin (nachobrodin@gmail.com)
87
 */
88
public class TileProvider extends AbstractRasterProvider implements TiledRasterProvider {
89
        public static String                NAME                     = "Tile Store";
90
        public static String                DESCRIPTION              = "Raster Tiled Source";
91
        public static final String          METADATA_DEFINITION_NAME = "TileStore";
92
        private static final Logger         logger                   = LoggerFactory.getLogger(TileProvider.class);
93
        private RasterProvider              provider                 = null;
94
        private boolean                     open                     = false;
95
        private Extent                      viewRequest              = null;
96
        private TiledLayer                  tiledLayer               = null;
97
        private MathUtils                   math                     = RasterLocator.getManager().getMathUtils();
98
        private TileServer                  secondLevelTileServer    = null;
99
         
100
        public static void register() {                
101
                DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
102
                if (dataman != null && !dataman.getStoreProviders().contains(NAME)) {
103
                        dataman.registerStoreProvider(NAME,
104
                                        TileProvider.class, TileDataParametersImpl.class);
105
                }
106

    
107
                /*if(DALFileLocator.getFilesystemServerExplorerManager() != null)
108
                        DALFileLocator.getFilesystemServerExplorerManager().registerProvider(
109
                                        NAME, DESCRIPTION,
110
                                        TileServerExplorer.class);*/
111
                
112
                if (!dataman.getExplorerProviders().contains(TileServerExplorer.NAME)) {
113
                        dataman.registerExplorerProvider(TileServerExplorer.NAME, TileServerExplorer.class, TileServerExplorerParameters.class);
114
                }
115
                dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
116
        }
117
        
118
        /**
119
         * Loads the specific provider to download data
120
         * @param file
121
         * @return
122
         * @throws NotSupportedExtensionException
123
         * @throws FileNotSupportedException 
124
         */
125
        @SuppressWarnings("unchecked")
126
        private RasterProvider loadProvider(TileDataParametersImpl params, DataStoreProviderServices storeServices) throws ProviderNotRegisteredException, InitializeException {
127
                Object obj = params.getDataParameters();
128
                DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
129
                DataStoreProvider prov = null;
130
                
131
                if(obj != null && obj instanceof DataStoreParameters) //Remote 
132
                        prov = dataManager.createProvider(storeServices, (DataStoreParameters)obj);
133
                else { //File
134
                        if(params.getFile() != null) {
135
                                //We have to locate a provider's name which manages the selected file
136
                                //A FilesystemServerExplorer will give a getProviderNames service
137
                                FilesystemServerExplorerParameters paramsExplorer = (FilesystemServerExplorerParameters)dataManager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
138
                                FilesystemServerExplorer serverExplorer = null;
139
                                try {
140
                                        paramsExplorer.setRoot(File.separator);
141
                                        serverExplorer = (FilesystemServerExplorer)dataManager.openServerExplorer(FilesystemServerExplorer.NAME, paramsExplorer);
142
                                } catch (ValidateDataParametersException e) {
143
                                        throw new InitializeException(e);
144
                                }
145
                                
146
                                //Gets the list of provider's name to manage the file
147
                                List<String> provName = serverExplorer.getProviderNameList(params.getFile());
148
                                if(provName.size() > 0) {
149
                                        for (int i = 0; i < provName.size(); i++) {
150
                                                //Gets the first provider what is not a TileProvider
151
                                                if(provName.get(i).compareTo(NAME) != 0) {
152
                                                        DataStoreParameters newparams = dataManager.createStoreParameters(provName.get(i));
153
                                                        ((FilesystemStoreParameters)newparams).setFile(params.getFile()); 
154
                                                        prov = dataManager.createProvider(storeServices, newparams);
155
                                                }
156
                                        }
157
                                }
158
                        }
159
                }
160
                
161
                if(prov != null && prov instanceof RasterProvider) {
162
                        if(((RasterProvider)prov).isRotated())
163
                                throw new InitializeException("Rotation not supported tiling files", new Throwable());
164

    
165
                        return (RasterProvider)prov;
166
                }
167
                
168
                return null;
169
        }
170
        
171
        /**
172
         * Gets the internal provider used to feed the TileProvider
173
         * @return
174
         */
175
        public RasterProvider getInternalProvider() {
176
                return provider;
177
        }
178
        
179
        public Image getImageLegend() {
180
                return provider.getImageLegend();
181
        }
182
        
183
        public String getFileSuffix() {
184
                try {
185
                        return provider instanceof RemoteRasterProvider ? provider.getFileSuffix() : "tif";
186
                } catch(Throwable e) {
187
                        //if wmts doesn't exists in the classpath
188
                        return "tif";
189
                }
190
        }
191
        
192
        public String getRMFFile() {
193
                TileCacheManager  manager = TileCacheLocator.getManager();
194
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
195
                
196
                String path = tiledLayer.getBaseLayerDirectory().substring(0, tiledLayer.getBaseLayerDirectory().lastIndexOf(File.separator) + 1) + 
197
                                          tileCache.getConfigurationDirectory() + File.separator + 
198
                                          tiledLayer.getID() + ".rmf";
199
                
200
                try {
201
                        if(!new File(path).exists() && 
202
                                provider != null && 
203
                                provider.getRMFFile() != null &&
204
                                new File(provider.getRMFFile()).exists()) 
205
                                RasterLocator.getManager().getFileUtils().copyFile(provider.getRMFFile(), path);
206
                        
207
                        if(provider != null && provider.getColorTable() != null) {        
208
                                ColorTable colorTable = provider.getColorTable();
209
                                RasterLocator.getManager().getProviderServices().saveObjectToRmfFile(path, ColorTable.class, colorTable);
210
                        }
211
                } catch (LocatorException e) {
212
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
213
                } catch (FileNotFoundException e) {
214
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
215
                } catch (IOException e) {
216
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
217
                } catch (RmfSerializerException e) {
218
                        logger.info("No se ha podido copiar la tabla de color a la capa tileada", e);
219
                }
220
                return path;
221
        }
222
        
223
        public TileProvider() throws NotSupportedExtensionException {
224
                super();
225
        }
226
        
227
        public void registerTileProviderFormats(Class<RasterProvider> c) {
228
                
229
        }
230
        
231
        /**
232
         * Assigns the provider associated to this tile server
233
         * @param prov
234
         * @throws NotSupportedExtensionException 
235
         */
236
        public void setProvider(RasterProvider prov) throws InitializeException  {
237
                this.provider = prov;
238
                init(getDataStoreParameters(), getStoreServices());
239
        }
240
        
241
        public TileProvider(TileDataParametersImpl params,
242
                        DataStoreProviderServices storeServices) throws InitializeException {
243
                super(params, storeServices, ToolsLocator.getDynObjectManager()
244
                                .createDynObject(
245
                                                MetadataLocator.getMetadataManager().getDefinition(
246
                                                                DataStore.METADATA_DEFINITION_NAME)));
247
                if(!params.isSecondLevelCache()) {
248
                        try {
249
                                provider = loadProvider(params, storeServices);
250
                        } catch (ProviderNotRegisteredException e) {
251
                                throw new InitializeException("Provider not registered", e);
252
                        }
253
                        init(params, storeServices);
254
                        if(provider.getFileSizeByProvider() != null && provider.getFileSizeByProvider().length > 0)
255
                                fileSize = provider.getFileSizeByProvider()[0];
256
                }
257
        }
258
        
259
        /**
260
         * Creates the second level cache if the client has set a <code>TileServer</code> and the
261
         * <code>CacheStruct</code> is different that the old one. 
262
         * <UL>
263
         * <LI>First level cache without TileServer from the client: do nothing</LI>
264
         * <LI>First level cache with TileServer from the client and the structure is 
265
         * different to the old one: Builds a second level TileProvider</LI>
266
         * <LI>First level cache with TileServer from the client and the structure is 
267
         * equal to the old one: do nothing</LI>
268
         * <LI>Second level cache: sets the TileServer</LI>
269
         * </UL>
270
         * @param params
271
         * @param storeServices
272
         * @throws NotSupportedExtensionException
273
         */
274
        /*private void createsSecondLevelCache(TileDataParametersImpl params) throws NotSupportedExtensionException {
275
                //Se obtiene el TileServer que haya pasado el cliente en los par?metros si ha pasado alguno.
276
                TileServer tileServer = params.getTileServer();
277
                //Se obtiene el CacheStruct y se compara con el del provider
278
                CacheStruct cacheStruct = null;
279
                if(tileServer != null)
280
                        cacheStruct = tileServer.getStruct();
281
                
282
                if(params.isSecondLevelCache()) { //Cache de segundo nivel
283
                        this.secondLevelTileServer = tileServer;
284
                } else if(cacheStruct != null && !provider.getTileServer().getStruct().compare(cacheStruct)) { //Cache de primer nivel
285
                        //Si son distintos habr? que crear una cach? de segundo nivel por lo que creamos un nuevo TileProvider
286
                        //que tenga como par?metro el provider viejo
287
                        TileDataParametersImpl par = new TileDataParametersImpl();
288
                        par.setDataParameters(provider.getDataParameters());
289
                        par.setTileServer(tileServer);
290
                        par.setSecondLevelCache(true);
291
                        TileProvider newProvider = new TileProvider(par, null);
292
                        newProvider.setProvider(this.provider);
293
                        //Al TileProvider actual se le asigna como provider el TileProvider creado
294
                        this.provider = newProvider;
295
                }
296
        }*/
297
        
298
        /**
299
         * Crea las referencias al fichero y carga
300
         * las estructuras con la informaci?n y los metadatos.
301
         * @param proj Proyecci?n
302
         * @param param Parametros de carga
303
         * @throws NotSupportedExtensionException
304
         */
305
        public void init (DataStoreParameters params,
306
                        DataStoreProviderServices storeServices) throws InitializeException  {
307
                setParam(storeServices, params);
308
                open = true;
309
                calculateDataType();
310
                calculateBandCount();
311
                calculateColorInterpretation();
312
                calculateTransparency();
313
                setColorTable(provider.getColorTable());
314
                noData = provider.getNoDataValue();
315
                setFName(provider.getURIOfFirstProvider());
316
                proj = provider.getProjection();
317
                ownTransformation = provider.getAffineTransform();
318
                externalTransformation = (AffineTransform)ownTransformation.clone();
319
                
320
                createTiledLayer();
321
                
322
                //Force to deletes the layer if the flag is to true
323
                if(tiledLayer != null) {
324
                        if(param instanceof TileDataParameters) {
325
                                if(((TileDataParameters)param).isDeletingCache()) {
326
                                        TileCacheManager  manager = TileCacheLocator.getManager();
327
                                        TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
328
                                        tileCache.removeLayer(tiledLayer);
329
                                        ((TileDataParameters)param).deleteCache(false);
330
                                }
331
                        }
332
                }
333
                
334
                if(provider instanceof RemoteRasterProvider)
335
                        stats = new RemoteDataStoreStatistics(provider);
336
        }
337

    
338
        /**
339
         * Calculates the data type of this provider
340
         * @return 
341
         */
342
        public void calculateDataType() {
343
                int[] datatype = null;
344
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
345
                        datatype = new int[provider.getBandCount() + 1];
346
                else
347
                        datatype = new int[provider.getBandCount()];
348
                for (int i = 0; i < provider.getDataType().length; i++) {
349
                        datatype[i] = provider.getDataType()[i];
350
                }
351
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
352
                        datatype[datatype.length - 1] = Buffer.TYPE_BYTE;
353
                setDataType(datatype);
354
        }
355
        
356
        /**
357
         * Calculates the number of bands
358
         */
359
        public void calculateBandCount() {
360
                bandCount = provider.getBandCount();
361
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
362
                        bandCount ++;
363
        }
364

    
365
        /**
366
         * Calculates the color interpretation
367
         */
368
        public void calculateColorInterpretation() {
369
                ColorInterpretation ci = provider.getColorInterpretation();
370
                if(ci != null) {
371
                        if(ci.isRGB() || ci.isBGR()) {
372
                                ci = DataStoreColorInterpretation.createRGBAInterpretation();
373
                        } else
374
                                ci = ci.cloneColorInterpretation();
375
                } else {
376
                        if(provider.getDataType()[0] == Buffer.TYPE_BYTE) {
377
                                if(provider.getBandCount() == 3)
378
                                        ci = DataStoreColorInterpretation.createRGBAInterpretation();
379
                                else
380
                                        ci = DataStoreColorInterpretation.createDefaultInterpretation(getBandCount());
381
                        } else {
382
                                if(getBandCount() == 1)
383
                                        ci = DataStoreColorInterpretation.createGrayInterpretation();
384
                                else 
385
                                        ci = DataStoreColorInterpretation.createDefaultInterpretation(getBandCount());
386
                        }
387
                }
388

    
389
                super.setColorInterpretation(ci);
390
        }
391
        
392
        
393
        public void calculateTransparency() {
394
                if(provider.getTransparency() != null)
395
                        transparency = provider.getTransparency().cloneTransparency();
396
                else 
397
                        transparency = new DataStoreTransparency(getColorInterpretation());
398
                if(getColorInterpretation() != null) {
399
                        transparency.setColorInterpretation(getColorInterpretation());
400
                        transparency.setTransparencyBand(getColorInterpretation().getAlphaBand());
401
                        transparency.activeTransparency();
402
                }
403
        }
404
        
405
        /**
406
         * Creates a new tiled layer if this hasn't been created yet or the ID has changed. 
407
         * An ID could changed because the file type has changed when the user uses WMTS properties.
408
         */
409
        private void createTiledLayer() {
410
                TileCacheManager  manager = TileCacheLocator.getManager();
411
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
412
                TiledLayer newLayer = tileCache.createLayer(provider.getTileServer(), TileCacheLibrary.DEFAULT_STRUCTURE);
413
                if(tiledLayer == null || newLayer.getID().compareTo(tiledLayer.getID()) != 0)
414
                        tiledLayer = newLayer;
415
        }
416
        
417
        public void reload() {
418
                try {
419
                        loadFromRmf(getRmfBlocksManager());
420
                        calculateColorInterpretation();
421
                        calculateTransparency();
422
                } catch (ParsingException e) {
423
                        logger.debug("No se ha podido leer el RMF", e);
424
                }
425
        }
426
        
427
        public int getZoomLevels() {
428
                if(provider.getTileServer() != null)
429
                        return provider.getTileServer().getStruct().getNumberOfLevels();
430
                return 0;
431
        }
432
        
433
        public int getNearestLevel(double pixelSize) {
434
                double[] pixelSizes = getPixelSizeByLevel();
435
                for (int i = 0; i < pixelSizes.length - 1; i++) {
436
                        if(pixelSize <= pixelSizes[i] && pixelSize > pixelSizes[i + 1]) {
437
                                return i;
438
                        }
439
                }
440
                if(pixelSize < pixelSizes[getZoomLevels() - 1])
441
                        return getZoomLevels() - 1;
442
                return 0;
443
        }
444
        
445
        /**
446
         * Returns a list of pixel sizes by level
447
         * @return
448
         */
449
        public double[] getPixelSizeByLevel() {
450
                double[] list = new double[getZoomLevels()];
451
                CacheStruct struct = provider.getTileServer().getStruct();
452
                for (int i = 0; i < struct.getNumberOfLevels(); i++) {
453
                        list[i] = math.adjustDouble(struct.getPixelSizeByLevel(i));
454
                }
455
                return list;
456
        }
457
        
458
        public Extent getCoordsInTheNearestLevel(Extent extent, int w, int h) {
459
                double[] pixelSizes = getPixelSizeByLevel();
460
                double currentPixelSize = extent.width() / (double)w;
461
                
462
                int level = 0;
463
                for (int i = 0; i < (pixelSizes.length - 1); i++) {
464
                        if(currentPixelSize < pixelSizes[i] && currentPixelSize >= pixelSizes[i + 1]) {
465
                                level = i + 1;
466
                                break;
467
                        }
468
                }
469
                
470
                return getZoomLevelCoordinates(level, extent, w, h);
471
        }
472
        
473
        public Extent getCoordsInLevel(Point2D viewCenter, int level, int w, int h) {
474
                level = adjustLevel(level);
475
                double pixelSize = provider.getTileServer().getStruct().getPixelSizeByLevel(level);
476
                
477
                /*Rectangle2D worldExtent = provider.getTileServer().getStruct().getWorldExtent();
478
                int nTiles = provider.getTileServer().getStruct().getLayerWidthOfTileMatrixByLevel(level);
479
                int[] nPixelsByTile = provider.getTileServer().getStruct().getTileSizeByLevel(level);
480
                
481
                double sizeWCByTile = worldExtent.getWidth() / (double)nTiles;
482
                double pixelSize = sizeWCByTile / (double)nPixelsByTile[0];*/
483
                
484
                double ulx = viewCenter.getX() - ((w / 2) * pixelSize);
485
                double uly = viewCenter.getY() - ((h / 2) * pixelSize);
486
                double lrx = ulx + (w * pixelSize);
487
                double lry = uly + (h * pixelSize);
488
                return new ExtentImpl(ulx, uly, lrx, lry);
489
        }
490
        
491
        /**
492
         * Adjust de level to the range
493
         * @param level
494
         * @return
495
         */
496
        private int adjustLevel(int level) {
497
                if(level < 0)
498
                        level = 0;
499
                if(level > getZoomLevels())
500
                        level = getZoomLevels();
501
                return level;
502
        }
503
        
504
        public AffineTransform getAffineTransform() {
505
                return provider.getAffineTransform();
506
        }
507
        
508
        /**
509
         * Gets the bounding box in world coordinates. If the layer has grid subsets (TileMatrixLimits) then
510
         * this will have a only extent but if the layer doesn't have grid subsets then this will have a different
511
         * extent in each level resolution. In this case we need to know the extent for each level.
512
         * @return Extent
513
         */
514
        public Extent getExtent() {
515
                return provider.getExtent();
516
        }
517

    
518
        public RasterProvider load() {
519
                return this;
520
        }
521
        
522
        public boolean isOpen() {
523
                return open;
524
        }
525

    
526
        public boolean isTiled() {
527
                return true;
528
        }
529
        
530
        public void close() {
531
                open = false;
532
                if(provider != null)
533
                        provider.close();
534
        }
535
        
536
        public String translateFileName(String fileName) {
537
                return fileName;
538
        }
539

    
540
        public void setView(Extent e) {
541
                viewRequest = e;
542
        }
543

    
544
        public Extent getView() {
545
                return viewRequest;
546
        }
547

    
548
        public double getWidth() {
549
                return provider.getWidth();
550
        }
551

    
552
        public double getHeight() {
553
                return provider.getHeight();
554
        }
555

    
556
        public Object readCompleteLine(int line, int band)
557
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
558
                return null;
559
        }
560
        
561
        public File getFileLayer() throws RasterDriverException {
562
                return null;
563
        }
564

    
565
        /**
566
         * Reads a complete block of data and returns an tridimensional array of the right type. This function is useful
567
         * to read a file very fast without setting a view. 
568
         * 
569
         * @param pos Posici?n donde se empieza  a leer
570
         * @param blockHeight Altura m?xima del bloque leido
571
         * @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
572
         * @throws InvalidSetViewException
573
         * @throws FileNotOpenException
574
         * @throws RasterDriverException
575
         */
576
        public Object readBlock(int pos, int blockHeight, double scale) 
577
        throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
578
                return provider.readBlock(pos, blockHeight, scale);
579
        }
580

    
581
        public Object getData(int x, int y, int band)
582
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
583
                return provider.getData(x, y, band);
584
        }
585
        
586
        /**
587
         * Assigns the list of bands RGB and read a window of data
588
         * @param rasterBuf
589
         * @param bandList
590
         * @param lastFile
591
         * @param ulx
592
         * @param uly
593
         * @param lrx
594
         * @param lry
595
         * @return
596
         * @throws RasterDriverException
597
         * @throws ProcessInterruptedException
598
         */
599
        public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile, 
600
                        double ulx, double uly, double lrx, double lry) throws RasterDriverException, ProcessInterruptedException {
601
                return null;
602
        }
603
        
604
        /**
605
         * Calculates the extent of a zoom level using other extent as a reference. The new extent is 
606
         * calculated with the same coordinate at the center. 
607
         * @param level
608
         * @param extent
609
         * @param w
610
         * @param h
611
         * @return
612
         */
613
        public Extent getZoomLevelCoordinates(int level, Extent extent, int w, int h) {
614
                double centerX = extent.getCenterX();
615
                double centerY = extent.getCenterY();
616
                return getCoordsInLevel(new Point2D.Double(centerX, centerY), level, w, h);
617
        }
618
        
619
        public boolean isRasterEnclosed() {
620
                if(provider != null)
621
                        return provider.isRasterEnclosed();
622
                return super.isRasterEnclosed();
623
        }
624
        
625
        /**
626
         * Gets the tile list in a selected extent
627
         * @param ex
628
         * @param bandList
629
         * @param bufWidth
630
         * @param bufHeight
631
         * @return
632
         * @throws TileBuildException 
633
         */
634
        private List<Tile> getTileList(SpiRasterQuery q) throws TileBuildException {
635
                TileServer tileServer = provider.getTileServer();
636
                CacheStruct struct = tileServer.getStruct();
637
                tileServer.setFileSuffix(getFileSuffix());
638
                
639
                createTiledLayer(); //Creates a new layer when the file type changes
640
                
641
                double pixelSizeRequest = q.getRequestBoundingBox().width() / q.getBufWidth();
642
                
643
                List<Tile> tileList = struct.getTileList(
644
                                        q.getAdjustedRequestBoundingBox().getUL(), 
645
                                        q.getAdjustedRequestBoundingBox().getLR(), 
646
                                        pixelSizeRequest);
647

    
648
                for (int i = 0; i < tileList.size(); i++) {
649
                        loadTileTimeParameters(tileList.get(i));
650
                }
651
                
652
                for (int i = 0; i < tileList.size(); i++) {
653
                        tileList.get(i).setDownloaderParams("BandList", q.getBandList().clone());
654
                }
655
                return tileList;
656
        }
657
        
658
        /**
659
         * Loads the multidimensional parameters in a tile 
660
         * @param tile
661
         */
662
        private void loadTileTimeParameters(Tile tile) {
663
                if(provider.getDataParameters() instanceof MultiDimensionalStoreParameters) {
664
                        MultiDimensionalStoreParameters par = (MultiDimensionalStoreParameters)provider.getDataParameters();
665
                        tile.setVariable(par.getStringVariable());
666
                        tile.setZ(par.getStringLevel());
667
                        tile.setTimeInstant(par.getStringTime());
668
                }
669
        }
670
        
671
        public boolean needEnhanced() {
672
                return provider.needEnhanced();
673
        }
674
        
675
        public Tile getTile(SpiRasterQuery q) throws TileGettingException {
676
                if(q.getCacheStruct() == null)
677
                        q.setCacheStruct(provider.getTileServer().getStruct());
678
                else
679
                        provider.getTileServer().setStruct(q.getCacheStruct());
680
                
681
                Tile tile = null;
682
                try {
683
                        tile = q.getCacheStruct().getTileStructure(
684
                                        q.getResolutionLevel(), q.getTileCol(), q.getTileRow(), 
685
                                        q.getAdjustedRequestBoundingBox().getUL(), 
686
                                        q.getAdjustedRequestBoundingBox().getLR());
687
                } catch (TileBuildException e1) {
688
                        throw new TileGettingException(e1);
689
                }
690
                
691
                loadTileTimeParameters(tile);
692
                
693
                //Creamos un BandList con todas las bandas del fichero
694
                BandList bandList = new BandListImpl();
695
                for(int i = 0; i < provider.getBandCount(); i++) {
696
                        try {
697
                                DatasetBand band = new DatasetBandImpl(provider.getURIOfFirstProvider(), i, provider.getDataType()[i], provider.getBandCount());
698
                                bandList.addBand(band);
699
                        } catch(BandNotFoundInListException e) {
700
                                //No a?adimos la banda
701
                        }
702
                }
703
                bandList.setDrawableBands(new int[]{0, 1, 2});
704
                
705
                tile.setDownloaderParams("BandList", bandList);
706
                createTiledLayer();
707
                return tiledLayer.getTile(tile);
708
        }
709
        
710
        @Override
711
        public void loadBuffer(SpiRasterQuery q) 
712
                        throws ProcessInterruptedException, RasterDriverException {
713
                try {
714
                        
715
                        if(q.requestIsTiled()) {
716
                                List<Tile> tileList = getTileList(q);
717
                                tiledLayer.getTiles(tileList, q.getTileListener(), q.getTaskStatus());
718
                        } else {
719
                                if(provider.isTiled()) {
720
                                        queryToInternalTiledProvider(q);
721
                                } else {
722
                                        queryToInternalProvider(q);
723
                                }
724
                        }
725
                        
726
                } catch (TileGettingException e) {
727
                        throw new RasterDriverException("Error getting the tile list", e);
728
                } catch (TileBuildException e) {
729
                        throw new RasterDriverException("Error building the tile list", e);
730
                } catch (QueryException e) {
731
                        throw new RasterDriverException("Error querying to the internal provider", e);
732
                }
733
                
734
        }
735
        
736
        private void queryToInternalTiledProvider(SpiRasterQuery parentQuery) throws TileGettingException, TileBuildException {
737
                List<Tile> tileList = getTileList(parentQuery);
738
                for (int i = 0; i < tileList.size(); i++) {
739
                        tiledLayer.getTile(tileList.get(i));
740
                }
741
                MemoryTileMatrixBuffer matrixBuffer = new MemoryTileMatrixBuffer(tileList);
742
                Buffer buf = matrixBuffer.getWindow(parentQuery.getAdjustedRequestBoundingBox(), parentQuery.getBufWidth(), parentQuery.getBufHeight(), parentQuery.getBandList().getDrawableBandsCount());
743
                parentQuery.setBufferResult(buf);
744
        }
745
        
746
        private void queryToInternalProvider(SpiRasterQuery parentQuery) throws ProcessInterruptedException, QueryException {
747
                DefaultRasterStore store = new DefaultRasterStore();
748
                store.setProvider(provider);
749
                
750
                RasterQuery query = RasterLocator.getManager().createQuery();
751
                query.setAreaOfInterest(parentQuery.getAdjustedRequestBoundingBox(), parentQuery.getBufWidth(), parentQuery.getBufHeight());
752
                int[] dBands = parentQuery.getDrawableBands().clone();
753
                if(!((AbstractRasterProvider)provider).getTransparency().existAlphaBand() && getTransparency().existAlphaBand()) {
754
                        dBands[getTransparency().getAlphaBandNumber()] = -1; 
755
                }
756
                if(((RasterQuery)parentQuery).isReadOnly())
757
                        query.setReadOnly(true);
758
                query.setDrawableBands(dBands);
759
                query.setAdjustToExtent(true);
760
                store.query(query);
761
                parentQuery.setBufferResult(((SpiRasterQuery)query).getBufferForProviders());
762
        }
763

    
764
        public int getBlockSize() {
765
                return 0;
766
        }
767

    
768
        public void setAffineTransform(AffineTransform t){
769
                
770
        }
771

    
772
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
773
                return getZoomLevels();
774
        }
775

    
776
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
777
                return provider.getTileServer().getStruct().getLayerWidthOfTileMatrixByLevel(overview) * 
778
                                provider.getTileServer().getStruct().getTileSizeByLevel(overview)[0];
779
        }
780

    
781
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
782
                return provider.getTileServer().getStruct().getLayerHeightOfTileMatrixByLevel(overview) * 
783
                                provider.getTileServer().getStruct().getTileSizeByLevel(overview)[0];
784
        }
785

    
786
        public boolean isOverviewsSupported() {
787
                return false;
788
        }
789

    
790
        public String getName() {
791
                return NAME;
792
        }
793
        
794
        /**
795
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
796
         * @param pt Punto a transformar
797
         * @return punto transformado en coordenadas del mundo
798
         */
799
        public Point2D rasterToWorld(Point2D pt) {
800
                Point2D p = new Point2D.Double();
801
                getAffineTransform().transform(pt, p);
802
                return p;
803
        }
804

    
805
        /**
806
         * Convierte un punto desde del mundo a coordenadas pixel.
807
         * @param pt Punto a transformar
808
         * @return punto transformado en coordenadas pixel
809
         */
810
        public Point2D worldToRaster(Point2D pt) {
811
                Point2D p = new Point2D.Double();
812
                try {
813
                        getAffineTransform().inverseTransform(pt, p);
814
                } catch (NoninvertibleTransformException e) {
815
                        return pt;
816
                }
817
                return p;
818
        }
819
        
820
        public void setStatus(RasterProvider provider) {
821
                if(provider instanceof TileProvider) {
822
                }
823
        }
824
        
825
        /**
826
         * ASigna el par?metro de inicializaci?n del driver.
827
         */
828
        @Override
829
        public void setParam(DataStoreProviderServices storeServices, DataStoreParameters param) {
830
                if(param instanceof RemoteStoreParameters)
831
                        this.uri = ((RasterDataParameters)param).getURI();
832
                this.param = param;
833
                this.storeServices = storeServices;
834
        }
835
        
836
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
837
                if(provider != null)
838
                        return provider.getInfoByPoint(x, y, cancellable);
839
                return "Not implemented";
840
        }
841
        
842
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
843
                if(provider != null)
844
                        return provider.getInfoByPoint(x, y, bbox, w, h, cancellable);
845
                return "Not implemented";
846
        }
847
        
848
        public int[] getTileSize(int level) {
849
                return provider.getTileServer().getStruct().getTileSizeByLevel(level);
850
        }
851
        
852
        public void deleteLayerFromCache() {
853
                TileCacheManager  manager = TileCacheLocator.getManager();
854
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
855
                if(tiledLayer != null)
856
                        tileCache.removeLayer(tiledLayer);
857
        }
858
        
859
        public TileServer getTileServer() {
860
                return secondLevelTileServer;
861
        }
862
        
863
        public void setSecondLevelTileServer(TileServer tileServer) {
864
                this.secondLevelTileServer = tileServer;
865
        }
866
        
867
        public void setTileServer(Class<?> tileServer) throws InitializeException {
868
                //TODO:Manejar excepciones
869
                //Crear par?metros
870
                TileDataParametersImpl par = new TileDataParametersImpl();
871
                par.setDataParameters(getDataParameters());
872
                par.setSecondLevelCache(true); //No crea un nuevo provider
873
                
874
                //Crea el proveedor de tiles de segundo nivel
875
                TileProvider newProvider = null;
876
                newProvider = new TileProvider(par, null);
877
                newProvider.setProvider(this.provider);
878

    
879
                //Instancia el TileServer pasado por el cliente con el TileProvider de segundo nivel
880
                Constructor<?> constructor;
881
                TileServer tServer = null;
882
                try {
883
                        constructor = tileServer.getConstructor(new Class<?>[]{AbstractRasterProvider.class});
884
                        Object [] args2 = {newProvider};
885
                        tServer = (TileServer)constructor.newInstance(args2);
886
                } catch (SecurityException e) {
887
                        e.printStackTrace();
888
                } catch (NoSuchMethodException e) {
889
                        e.printStackTrace();
890
                } catch (IllegalArgumentException e) {
891
                        e.printStackTrace();
892
                } catch (InstantiationException e) {
893
                        e.printStackTrace();
894
                } catch (IllegalAccessException e) {
895
                        e.printStackTrace();
896
                } catch (InvocationTargetException e) {
897
                        e.printStackTrace();
898
                }
899
                
900
                //Asigna el TileServer al nuevo provider de segundo nivel
901
                newProvider.setSecondLevelTileServer(tServer);
902
                
903
                //Asigna al provider de tiles de primer nivel el de segundo. 
904
                //Solo si las estructuras de cach? son diferentes
905
                if(!provider.getTileServer().getStruct().compare(tServer.getStruct())) {
906
                        this.setProvider(newProvider);
907
                        tiledLayer = null;
908
                }
909
        }
910
        
911
}