Statistics
| Revision:

gvsig-raster / org.gvsig.raster.tilecache / trunk / org.gvsig.raster.tilecache / org.gvsig.raster.tilecache.io / src / main / java / org / gvsig / raster / tilecache / io / TileProvider.java @ 2896

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

    
347
        /**
348
         * Calculates the data type of this provider
349
         * @return 
350
         */
351
        public void calculateDataType() {
352
                int[] datatype = null;
353
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
354
                        datatype = new int[provider.getBandCount() + 1];
355
                else
356
                        datatype = new int[provider.getBandCount()];
357
                for (int i = 0; i < provider.getDataType().length; i++) {
358
                        datatype[i] = provider.getDataType()[i];
359
                }
360
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
361
                        datatype[datatype.length - 1] = Buffer.TYPE_BYTE;
362
                setDataType(datatype);
363
        }
364
        
365
        /**
366
         * Calculates the number of bands
367
         */
368
        public void calculateBandCount() {
369
                bandCount = provider.getBandCount();
370
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
371
                        bandCount ++;
372
        }
373

    
374
        /**
375
         * Calculates the color interpretation
376
         */
377
        public void calculateColorInterpretation() {
378
                ColorInterpretation ci = provider.getColorInterpretation();
379
                if(ci != null) {
380
                        if(ci.isRGB() || ci.isBGR()) {
381
                                ci = DataStoreColorInterpretation.createRGBAInterpretation();
382
                        } else
383
                                ci = ci.cloneColorInterpretation();
384
                } else {
385
                        if(provider.getDataType()[0] == Buffer.TYPE_BYTE) {
386
                                if(provider.getBandCount() == 3)
387
                                        ci = DataStoreColorInterpretation.createRGBAInterpretation();
388
                                else
389
                                        ci = DataStoreColorInterpretation.createDefaultInterpretation(getBandCount());
390
                        } else {
391
                                if(getBandCount() == 1)
392
                                        ci = DataStoreColorInterpretation.createGrayInterpretation();
393
                                else 
394
                                        ci = DataStoreColorInterpretation.createDefaultInterpretation(getBandCount());
395
                        }
396
                }
397

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

    
527
        public RasterProvider load() {
528
                return this;
529
        }
530
        
531
        public boolean isOpen() {
532
                return open;
533
        }
534

    
535
        public boolean isTiled() {
536
                return true;
537
        }
538
        
539
        public void close() {
540
                open = false;
541
                if(provider != null)
542
                        provider.close();
543
        }
544
        
545
        public String translateFileName(String fileName) {
546
                return fileName;
547
        }
548

    
549
        public void setView(Extent e) {
550
                viewRequest = e;
551
        }
552

    
553
        public Extent getView() {
554
                return viewRequest;
555
        }
556

    
557
        public double getWidth() {
558
                return provider.getWidth();
559
        }
560

    
561
        public double getHeight() {
562
                return provider.getHeight();
563
        }
564

    
565
        public Object readCompleteLine(int line, int band)
566
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
567
                return null;
568
        }
569
        
570
        public File getFileLayer() throws RasterDriverException {
571
                return null;
572
        }
573

    
574
        @SuppressWarnings("deprecation")
575
        public Object readBlock(int pos, int blockHeight, double scale) 
576
        throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
577
                //TODO: temporal hasta que haya un generador de estad?sticas parciales para realce.
578
                //Pongo este m?todo deprecated porque el objetivo es eliminarlo de los proveedores.
579
                if(provider.getBandCount() < getBandCount()) {
580
                        switch (getDataType()[0]) {
581
                        case Buffer.TYPE_BYTE:
582
                                byte[][][] buf1 = (byte[][][])provider.readBlock(pos, blockHeight, scale);
583
                                byte[][][] b1 = new byte[buf1.length + 1][][];
584
                                for (int i = 0; i < buf1.length; i++) {
585
                                        b1[i] = buf1[i];
586
                                }
587
                                b1[b1.length - 1] = new byte[buf1[0].length][buf1[0][0].length];
588
                                return b1;
589
                        case Buffer.TYPE_SHORT:
590
                                short[][][] buf2 = (short[][][])provider.readBlock(pos, blockHeight, scale);
591
                                short[][][] b2 = new short[buf2.length + 1][][];
592
                                for (int i = 0; i < buf2.length; i++) {
593
                                        b2[i] = buf2[i];
594
                                }
595
                                b2[b2.length - 1] = new short[buf2[0].length][buf2[0][0].length];
596
                                return b2;
597
                        case Buffer.TYPE_FLOAT:
598
                                float[][][] buf3 = (float[][][])provider.readBlock(pos, blockHeight, scale);
599
                                float[][][] b3 = new float[buf3.length + 1][][];
600
                                for (int i = 0; i < buf3.length; i++) {
601
                                        b3[i] = buf3[i];
602
                                }
603
                                b3[b3.length - 1] = new float[buf3[0].length][buf3[0][0].length];
604
                                return b3;
605
                        case Buffer.TYPE_DOUBLE: 
606
                                double[][][] buf4 = (double[][][])provider.readBlock(pos, blockHeight, scale);
607
                                double[][][] b4 = new double[buf4.length + 1][][];
608
                                for (int i = 0; i < buf4.length; i++) {
609
                                        b4[i] = buf4[i];
610
                                }
611
                                b4[b4.length - 1] = new double[buf4[0].length][buf4[0][0].length];
612
                                return b4;
613
                        case Buffer.TYPE_INT:
614
                                int[][][] buf5 = (int[][][])provider.readBlock(pos, blockHeight, scale);
615
                                int[][][] b5 = new int[buf5.length + 1][][];
616
                                for (int i = 0; i < buf5.length; i++) {
617
                                        b5[i] = buf5[i];
618
                                }
619
                                b5[b5.length - 1] = new int[buf5[0].length][buf5[0][0].length];
620
                                return b5;
621
                        }
622
                        
623
                }
624
                return provider.readBlock(pos, blockHeight, scale);
625
        }
626

    
627
        public Object getData(int x, int y, int band)
628
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
629
                return provider.getData(x, y, band);
630
        }
631
        
632
        /**
633
         * Assigns the list of bands RGB and read a window of data
634
         * @param rasterBuf
635
         * @param bandList
636
         * @param lastFile
637
         * @param ulx
638
         * @param uly
639
         * @param lrx
640
         * @param lry
641
         * @return
642
         * @throws RasterDriverException
643
         * @throws ProcessInterruptedException
644
         */
645
        public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile, 
646
                        double ulx, double uly, double lrx, double lry) throws RasterDriverException, ProcessInterruptedException {
647
                return null;
648
        }
649
        
650
        /**
651
         * Calculates the extent of a zoom level using other extent as a reference. The new extent is 
652
         * calculated with the same coordinate at the center. 
653
         * @param level
654
         * @param extent
655
         * @param w
656
         * @param h
657
         * @return
658
         */
659
        public Extent getZoomLevelCoordinates(int level, Extent extent, int w, int h) {
660
                double centerX = extent.getCenterX();
661
                double centerY = extent.getCenterY();
662
                return getCoordsInLevel(new Point2D.Double(centerX, centerY), level, w, h);
663
        }
664
        
665
        public boolean isRasterEnclosed() {
666
                if(provider != null)
667
                        return provider.isRasterEnclosed();
668
                return super.isRasterEnclosed();
669
        }
670
        
671
        /**
672
         * Gets the tile list in a selected extent
673
         * @param ex
674
         * @param bandList
675
         * @param bufWidth
676
         * @param bufHeight
677
         * @return
678
         * @throws TileBuildException 
679
         */
680
        private List<Tile> getTileList(SpiRasterQuery q) throws TileBuildException {
681
                TileServer tileServer = provider.getTileServer();
682
                CacheStruct struct = tileServer.getStruct();
683
                tileServer.setFileSuffix(getFileSuffix());
684
                
685
                createTiledLayer(); //Creates a new layer when the file type changes
686
                
687
                double pixelSizeRequest = q.getRequestBoundingBox().width() / q.getBufWidth();
688
                
689
                List<Tile> tileList = struct.getTileList(
690
                                        q.getAdjustedRequestBoundingBox().getUL(), 
691
                                        q.getAdjustedRequestBoundingBox().getLR(), 
692
                                        pixelSizeRequest);
693

    
694
                for (int i = 0; i < tileList.size(); i++) {
695
                        loadTileTimeParameters(tileList.get(i));
696
                }
697
                
698
                for (int i = 0; i < tileList.size(); i++) {
699
                        tileList.get(i).setDownloaderParams("BandList", q.getBandList().clone());
700
                }
701
                return tileList;
702
        }
703
        
704
        /**
705
         * Loads the multidimensional parameters in a tile 
706
         * @param tile
707
         */
708
        private void loadTileTimeParameters(Tile tile) {
709
                if(provider.getDataParameters() instanceof MultiDimensionalStoreParameters) {
710
                        MultiDimensionalStoreParameters par = (MultiDimensionalStoreParameters)provider.getDataParameters();
711
                        tile.setVariable(par.getStringVariable());
712
                        tile.setZ(par.getStringLevel());
713
                        tile.setTimeInstant(par.getStringTime());
714
                }
715
        }
716
        
717
        public boolean needEnhanced() {
718
                return provider.needEnhanced();
719
        }
720
        
721
        public Tile getTile(SpiRasterQuery q) throws TileGettingException {
722
                if(q.getCacheStruct() == null)
723
                        q.setCacheStruct(provider.getTileServer().getStruct());
724
                else
725
                        provider.getTileServer().setStruct(q.getCacheStruct());
726
                
727
                Tile tile = null;
728
                try {
729
                        tile = q.getCacheStruct().getTileStructure(
730
                                        q.getResolutionLevel(), q.getTileCol(), q.getTileRow(), 
731
                                        q.getAdjustedRequestBoundingBox().getUL(), 
732
                                        q.getAdjustedRequestBoundingBox().getLR());
733
                } catch (TileBuildException e1) {
734
                        throw new TileGettingException(e1);
735
                }
736
                
737
                loadTileTimeParameters(tile);
738
                
739
                //Creamos un BandList con todas las bandas del fichero
740
                BandList bandList = new BandListImpl();
741
                for(int i = 0; i < provider.getBandCount(); i++) {
742
                        try {
743
                                DatasetBand band = new DatasetBandImpl(provider.getURIOfFirstProvider(), i, provider.getDataType()[i], provider.getBandCount());
744
                                bandList.addBand(band);
745
                        } catch(BandNotFoundInListException e) {
746
                                //No a?adimos la banda
747
                        }
748
                }
749
                bandList.setDrawableBands(new int[]{0, 1, 2});
750
                
751
                tile.setDownloaderParams("BandList", bandList);
752
                createTiledLayer();
753
                return tiledLayer.getTile(tile);
754
        }
755
        
756
        @Override
757
        public void loadBuffer(SpiRasterQuery q) 
758
                        throws ProcessInterruptedException, RasterDriverException {
759
                try {
760
                        
761
                        if(q.requestIsTiled()) {
762
                                List<Tile> tileList = getTileList(q);
763
                                tiledLayer.getTiles(tileList, q.getTileListener(), q.getTaskStatus());
764
                        } else {
765
                                if(provider.isTiled()) {
766
                                        queryToInternalTiledProvider(q);
767
                                } else {
768
                                        queryToInternalProvider(q);
769
                                }
770
                        }
771
                        
772
                } catch (TileGettingException e) {
773
                        throw new RasterDriverException("Error getting the tile list", e);
774
                } catch (TileBuildException e) {
775
                        throw new RasterDriverException("Error building the tile list", e);
776
                } catch (QueryException e) {
777
                        throw new RasterDriverException("Error querying to the internal provider", e);
778
                }
779
                
780
        }
781
        
782
        private void queryToInternalTiledProvider(SpiRasterQuery parentQuery) throws TileGettingException, TileBuildException {
783
                List<Tile> tileList = getTileList(parentQuery);
784
                for (int i = 0; i < tileList.size(); i++) {
785
                        tiledLayer.getTile(tileList.get(i));
786
                }
787
                MemoryTileMatrixBuffer matrixBuffer = new MemoryTileMatrixBuffer(tileList);
788
                Buffer buf = matrixBuffer.getWindow(parentQuery.getAdjustedRequestBoundingBox(), parentQuery.getBufWidth(), parentQuery.getBufHeight(), parentQuery.getBandList().getDrawableBandsCount());
789
                parentQuery.setBufferResult(buf);
790
        }
791
        
792
        private void queryToInternalProvider(SpiRasterQuery parentQuery) throws ProcessInterruptedException, QueryException {
793
                DefaultRasterStore store = new DefaultRasterStore();
794
                store.setProvider(provider);
795
                
796
                RasterQuery query = RasterLocator.getManager().createQuery();
797
                query.setAreaOfInterest(parentQuery.getAdjustedRequestBoundingBox(), parentQuery.getBufWidth(), parentQuery.getBufHeight());
798
                int[] dBands = null;
799
                if(parentQuery.getDrawableBands() != null) {
800
                        dBands = parentQuery.getDrawableBands().clone();
801
                        if(!((AbstractRasterProvider)provider).getTransparency().existAlphaBand() && getTransparency().existAlphaBand()) {
802
                                dBands[getTransparency().getAlphaBandNumber()] = -1; 
803
                        }
804
                }
805
                query.setReadOnly(((RasterQuery)parentQuery).isReadOnly());
806
                if(((RasterQuery)parentQuery).isforcingARGBRequest())
807
                        query.forceARGBRequest();
808
                if(((RasterQuery)parentQuery).isforcingRGBRequest())
809
                        query.forceRGBRequest();
810
                if(dBands == null)
811
                        query.setAllDrawableBands();
812
                else
813
                        query.setDrawableBands(dBands);
814
                query.setAdjustToExtent(true);
815
                store.query(query);
816
                parentQuery.setBufferResult(((SpiRasterQuery)query).getBufferForProviders());
817
        }
818

    
819
        public int getBlockSize() {
820
                return 0;
821
        }
822

    
823
        public void setAffineTransform(AffineTransform t){
824
                
825
        }
826

    
827
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
828
                return getZoomLevels();
829
        }
830

    
831
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
832
                return provider.getTileServer().getStruct().getLayerWidthOfTileMatrixByLevel(overview) * 
833
                                provider.getTileServer().getStruct().getTileSizeByLevel(overview)[0];
834
        }
835

    
836
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
837
                return provider.getTileServer().getStruct().getLayerHeightOfTileMatrixByLevel(overview) * 
838
                                provider.getTileServer().getStruct().getTileSizeByLevel(overview)[0];
839
        }
840

    
841
        public boolean isOverviewsSupported() {
842
                return false;
843
        }
844

    
845
        public String getProviderName() {
846
                return NAME;
847
        }
848
        
849
        /**
850
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
851
         * @param pt Punto a transformar
852
         * @return punto transformado en coordenadas del mundo
853
         */
854
        public Point2D rasterToWorld(Point2D pt) {
855
                Point2D p = new Point2D.Double();
856
                getAffineTransform().transform(pt, p);
857
                return p;
858
        }
859

    
860
        /**
861
         * Convierte un punto desde del mundo a coordenadas pixel.
862
         * @param pt Punto a transformar
863
         * @return punto transformado en coordenadas pixel
864
         */
865
        public Point2D worldToRaster(Point2D pt) {
866
                Point2D p = new Point2D.Double();
867
                try {
868
                        getAffineTransform().inverseTransform(pt, p);
869
                } catch (NoninvertibleTransformException e) {
870
                        return pt;
871
                }
872
                return p;
873
        }
874
        
875
        public void setStatus(RasterProvider provider) {
876
                if(provider instanceof TileProvider) {
877
                }
878
        }
879
        
880
        /**
881
         * ASigna el par?metro de inicializaci?n del driver.
882
         */
883
        @Override
884
        public void setParam(DataStoreProviderServices storeServices, DataStoreParameters param) {
885
                if(param instanceof RemoteStoreParameters)
886
                        this.uri = ((RasterDataParameters)param).getURI();
887
                this.param = param;
888
                this.storeServices = storeServices;
889
        }
890
        
891
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
892
                if(provider != null)
893
                        return provider.getInfoByPoint(x, y, cancellable);
894
                return "Not implemented";
895
        }
896
        
897
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
898
                if(provider != null)
899
                        return provider.getInfoByPoint(x, y, bbox, w, h, cancellable);
900
                return "Not implemented";
901
        }
902
        
903
        public int[] getTileSize(int level) {
904
                return provider.getTileServer().getStruct().getTileSizeByLevel(level);
905
        }
906
        
907
        public void deleteLayerFromCache() {
908
                TileCacheManager  manager = TileCacheLocator.getManager();
909
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
910
                if(tiledLayer != null)
911
                        tileCache.removeLayer(tiledLayer);
912
        }
913
        
914
        public TileServer getTileServer() {
915
                return secondLevelTileServer;
916
        }
917
        
918
        public void setSecondLevelTileServer(TileServer tileServer) {
919
                this.secondLevelTileServer = tileServer;
920
        }
921
        
922
        public void setTileServer(Class<?> tileServer) throws InitializeException {
923
                //TODO:Manejar excepciones
924
                //Crear par?metros
925
                TileDataParametersImpl par = new TileDataParametersImpl();
926
                par.setDataParameters(getDataParameters());
927
                par.setSecondLevelCache(true); //No crea un nuevo provider
928
                
929
                //Crea el proveedor de tiles de segundo nivel
930
                TileProvider newProvider = null;
931
                newProvider = new TileProvider(par, null);
932
                newProvider.setProvider(this.provider);
933

    
934
                //Instancia el TileServer pasado por el cliente con el TileProvider de segundo nivel
935
                Constructor<?> constructor;
936
                TileServer tServer = null;
937
                try {
938
                        constructor = tileServer.getConstructor(new Class<?>[]{AbstractRasterProvider.class});
939
                        Object [] args2 = {newProvider};
940
                        tServer = (TileServer)constructor.newInstance(args2);
941
                } catch (SecurityException e) {
942
                        e.printStackTrace();
943
                } catch (NoSuchMethodException e) {
944
                        e.printStackTrace();
945
                } catch (IllegalArgumentException e) {
946
                        e.printStackTrace();
947
                } catch (InstantiationException e) {
948
                        e.printStackTrace();
949
                } catch (IllegalAccessException e) {
950
                        e.printStackTrace();
951
                } catch (InvocationTargetException e) {
952
                        e.printStackTrace();
953
                }
954
                
955
                //Asigna el TileServer al nuevo provider de segundo nivel
956
                newProvider.setSecondLevelTileServer(tServer);
957
                
958
                //Asigna al provider de tiles de primer nivel el de segundo. 
959
                //Solo si las estructuras de cach? son diferentes
960
                if(!provider.getTileServer().getStruct().compare(tServer.getStruct())) {
961
                        this.setProvider(newProvider);
962
                        tiledLayer = null;
963
                }
964
        }
965
        
966
}