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 @ 2241

History | View | Annotate | Download (28.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.ProcessInterruptedException;
32
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
33
import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException;
34
import org.gvsig.fmap.dal.coverage.store.parameter.MultiDimensionalStoreParameters;
35
import org.gvsig.fmap.dal.coverage.store.parameter.RasterDataParameters;
36
import org.gvsig.fmap.dal.coverage.store.parameter.RemoteStoreParameters;
37
import org.gvsig.fmap.dal.coverage.store.parameter.TileDataParameters;
38
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
39
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
40
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
41
import org.gvsig.fmap.dal.coverage.util.MathUtils;
42
import org.gvsig.fmap.dal.coverage.util.RasterUtils;
43
import org.gvsig.fmap.dal.exception.InitializeException;
44
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
45
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
46
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
47
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
48
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
49
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
50
import org.gvsig.fmap.dal.spi.DataStoreProvider;
51
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
52
import org.gvsig.metadata.MetadataLocator;
53
import org.gvsig.raster.cache.tile.Tile;
54
import org.gvsig.raster.cache.tile.TileCache;
55
import org.gvsig.raster.cache.tile.TileCacheLibrary;
56
import org.gvsig.raster.cache.tile.TileCacheLocator;
57
import org.gvsig.raster.cache.tile.TileCacheManager;
58
import org.gvsig.raster.cache.tile.exception.TileBuildException;
59
import org.gvsig.raster.cache.tile.exception.TileGettingException;
60
import org.gvsig.raster.cache.tile.layer.TiledLayer;
61
import org.gvsig.raster.cache.tile.provider.CacheStruct;
62
import org.gvsig.raster.cache.tile.provider.TileServer;
63
import org.gvsig.raster.impl.buffer.SpiRasterQuery;
64
import org.gvsig.raster.impl.datastruct.BandListImpl;
65
import org.gvsig.raster.impl.datastruct.DatasetBandImpl;
66
import org.gvsig.raster.impl.datastruct.ExtentImpl;
67
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
68
import org.gvsig.raster.impl.provider.RasterProvider;
69
import org.gvsig.raster.impl.provider.RemoteRasterProvider;
70
import org.gvsig.raster.impl.provider.TiledRasterProvider;
71
import org.gvsig.raster.impl.store.DefaultStoreFactory;
72
import org.gvsig.raster.impl.store.properties.RemoteDataStoreStatistics;
73
import org.gvsig.tools.ToolsLocator;
74
import org.gvsig.tools.locator.LocatorException;
75
import org.slf4j.Logger;
76
import org.slf4j.LoggerFactory;
77

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

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

    
161
                        return (RasterProvider)prov;
162
                }
163
                
164
                return null;
165
        }
166
        
167
        /**
168
         * Gets the internal provider used to feed the TileProvider
169
         * @return
170
         */
171
        public RasterProvider getInternalProvider() {
172
                return provider;
173
        }
174
        
175
        public Image getImageLegend() {
176
                return provider.getImageLegend();
177
        }
178
        
179
        public String getFileSuffix() {
180
                try {
181
                        return provider instanceof RemoteRasterProvider ? provider.getFileSuffix() : "tif";
182
                } catch(Throwable e) {
183
                        //if wmts doesn't exists in the classpath
184
                        return "tif";
185
                }
186
        }
187
        
188
        public String getRMFFile() {
189
                TileCacheManager  manager = TileCacheLocator.getManager();
190
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
191
                
192
                String path = tiledLayer.getBaseLayerDirectory().substring(0, tiledLayer.getBaseLayerDirectory().lastIndexOf(File.separator) + 1) + 
193
                                          tileCache.getConfigurationDirectory() + File.separator + 
194
                                          tiledLayer.getID() + ".rmf";
195
                
196
                try {
197
                        if(!new File(path).exists() && 
198
                                provider != null && 
199
                                provider.getRMFFile() != null &&
200
                                new File(provider.getRMFFile()).exists()) 
201
                                RasterLocator.getManager().getFileUtils().copyFile(provider.getRMFFile(), path);
202
                        
203
                        if(provider != null && provider.getColorTable() != null) {        
204
                                ColorTable colorTable = provider.getColorTable();
205
                                RasterLocator.getManager().getProviderServices().saveObjectToRmfFile(path, ColorTable.class, colorTable);
206
                        }
207
                } catch (LocatorException e) {
208
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
209
                } catch (FileNotFoundException e) {
210
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
211
                } catch (IOException e) {
212
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
213
                } catch (RmfSerializerException e) {
214
                        logger.info("No se ha podido copiar la tabla de color a la capa tileada", e);
215
                }
216
                return path;
217
        }
218
        
219
        public TileProvider() throws NotSupportedExtensionException {
220
                super();
221
        }
222
        
223
        public void registerTileProviderFormats(Class<RasterProvider> c) {
224
                
225
        }
226
        
227
        /**
228
         * Assigns the provider associated to this tile server
229
         * @param prov
230
         * @throws NotSupportedExtensionException 
231
         */
232
        public void setProvider(RasterProvider prov) throws InitializeException  {
233
                this.provider = prov;
234
                init(getDataStoreParameters(), getStoreServices());
235
        }
236
        
237
        public TileProvider(TileDataParametersImpl params,
238
                        DataStoreProviderServices storeServices) throws InitializeException {
239
                super(params, storeServices, ToolsLocator.getDynObjectManager()
240
                                .createDynObject(
241
                                                MetadataLocator.getMetadataManager().getDefinition(
242
                                                                DataStore.METADATA_DEFINITION_NAME)));
243
                if(!params.isSecondLevelCache()) {
244
                        try {
245
                                provider = loadProvider(params, storeServices);
246
                        } catch (ProviderNotRegisteredException e) {
247
                                throw new InitializeException("Provider not registered", e);
248
                        }
249
                        init(params, storeServices);
250
                        if(provider.getFileSizeByProvider() != null && provider.getFileSizeByProvider().length > 0)
251
                                fileSize = provider.getFileSizeByProvider()[0];
252
                }
253
        }
254
        
255
        /**
256
         * Creates the second level cache if the client has set a <code>TileServer</code> and the
257
         * <code>CacheStruct</code> is different that the old one. 
258
         * <UL>
259
         * <LI>First level cache without TileServer from the client: do nothing</LI>
260
         * <LI>First level cache with TileServer from the client and the structure is 
261
         * different to the old one: Builds a second level TileProvider</LI>
262
         * <LI>First level cache with TileServer from the client and the structure is 
263
         * equal to the old one: do nothing</LI>
264
         * <LI>Second level cache: sets the TileServer</LI>
265
         * </UL>
266
         * @param params
267
         * @param storeServices
268
         * @throws NotSupportedExtensionException
269
         */
270
        /*private void createsSecondLevelCache(TileDataParametersImpl params) throws NotSupportedExtensionException {
271
                //Se obtiene el TileServer que haya pasado el cliente en los par?metros si ha pasado alguno.
272
                TileServer tileServer = params.getTileServer();
273
                //Se obtiene el CacheStruct y se compara con el del provider
274
                CacheStruct cacheStruct = null;
275
                if(tileServer != null)
276
                        cacheStruct = tileServer.getStruct();
277
                
278
                if(params.isSecondLevelCache()) { //Cache de segundo nivel
279
                        this.secondLevelTileServer = tileServer;
280
                } else if(cacheStruct != null && !provider.getTileServer().getStruct().compare(cacheStruct)) { //Cache de primer nivel
281
                        //Si son distintos habr? que crear una cach? de segundo nivel por lo que creamos un nuevo TileProvider
282
                        //que tenga como par?metro el provider viejo
283
                        TileDataParametersImpl par = new TileDataParametersImpl();
284
                        par.setDataParameters(provider.getDataParameters());
285
                        par.setTileServer(tileServer);
286
                        par.setSecondLevelCache(true);
287
                        TileProvider newProvider = new TileProvider(par, null);
288
                        newProvider.setProvider(this.provider);
289
                        //Al TileProvider actual se le asigna como provider el TileProvider creado
290
                        this.provider = newProvider;
291
                }
292
        }*/
293
        
294
        /**
295
         * Crea las referencias al fichero y carga
296
         * las estructuras con la informaci?n y los metadatos.
297
         * @param proj Proyecci?n
298
         * @param param Parametros de carga
299
         * @throws NotSupportedExtensionException
300
         */
301
        public void init (DataStoreParameters params,
302
                        DataStoreProviderServices storeServices) throws InitializeException  {
303
                setParam(storeServices, params);
304
                open = true;
305
                setDataType(provider.getDataType());
306
                bandCount = provider.getBandCount();
307
                //if(getColorInterpretation() == null)
308
                        setColorInterpretation(provider.getColorInterpretation());
309
                /*else
310
                        getColorInterpretation().addColorInterpretation(provider.getColorInterpretation());*/
311
                setColorTable(provider.getColorTable());
312
                noData = provider.getNoDataValue();
313
                setFName(provider.getURIOfFirstProvider());
314
                proj = provider.getProjection();
315
                ownTransformation = provider.getAffineTransform();
316
                externalTransformation = (AffineTransform)ownTransformation.clone();
317
                
318
                createTiledLayer();
319
                
320
                //Force to deletes the layer if the flag is to true
321
                if(tiledLayer != null) {
322
                        if(param instanceof TileDataParameters) {
323
                                if(((TileDataParameters)param).isDeletingCache()) {
324
                                        TileCacheManager  manager = TileCacheLocator.getManager();
325
                                        TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
326
                                        tileCache.removeLayer(tiledLayer);
327
                                        ((TileDataParameters)param).deleteCache(false);
328
                                }
329
                        }
330
                }
331
                
332
                if(provider instanceof RemoteRasterProvider)
333
                        stats = new RemoteDataStoreStatistics(provider);
334
        }
335
        
336
        /**
337
         * Creates a new tiled layer if this hasn't been created yet or the ID has changed. 
338
         * An ID could changed because the file type has changed when the user uses WMTS properties.
339
         */
340
        private void createTiledLayer() {
341
                TileCacheManager  manager = TileCacheLocator.getManager();
342
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
343
                TiledLayer newLayer = tileCache.createLayer(provider.getTileServer(), TileCacheLibrary.DEFAULT_STRUCTURE);
344
                if(tiledLayer == null || newLayer.getID().compareTo(tiledLayer.getID()) != 0)
345
                        tiledLayer = newLayer;
346
        }
347
        
348
        public int getZoomLevels() {
349
                if(provider.getTileServer() != null)
350
                        return provider.getTileServer().getStruct().getNumberOfLevels();
351
                return 0;
352
        }
353
        
354
        public int getNearestLevel(double pixelSize) {
355
                double[] pixelSizes = getPixelSizeByLevel();
356
                for (int i = 0; i < pixelSizes.length - 1; i++) {
357
                        if(pixelSize <= pixelSizes[i] && pixelSize > pixelSizes[i + 1]) {
358
                                return i;
359
                        }
360
                }
361
                if(pixelSize < pixelSizes[getZoomLevels() - 1])
362
                        return getZoomLevels() - 1;
363
                return 0;
364
        }
365
        
366
        /**
367
         * Returns a list of pixel sizes by level
368
         * @return
369
         */
370
        public double[] getPixelSizeByLevel() {
371
                double[] list = new double[getZoomLevels()];
372
                CacheStruct struct = provider.getTileServer().getStruct();
373
                for (int i = 0; i < struct.getNumberOfLevels(); i++) {
374
                        list[i] = math.adjustDouble(struct.getPixelSizeByLevel(i));
375
                }
376
                return list;
377
        }
378
        
379
        public Extent getCoordsInTheNearestLevel(Extent extent, int w, int h) {
380
                double[] pixelSizes = getPixelSizeByLevel();
381
                double currentPixelSize = extent.width() / (double)w;
382
                
383
                int level = 0;
384
                for (int i = 0; i < (pixelSizes.length - 1); i++) {
385
                        if(currentPixelSize < pixelSizes[i] && currentPixelSize >= pixelSizes[i + 1]) {
386
                                level = i + 1;
387
                                break;
388
                        }
389
                }
390
                
391
                return getZoomLevelCoordinates(level, extent, w, h);
392
        }
393
        
394
        public Extent getCoordsInLevel(Point2D viewCenter, int level, int w, int h) {
395
                level = adjustLevel(level);
396
                double pixelSize = provider.getTileServer().getStruct().getPixelSizeByLevel(level);
397
                
398
                double ulx = viewCenter.getX() - ((w / 2) * pixelSize);
399
                double uly = viewCenter.getY() - ((h / 2) * pixelSize);
400
                double lrx = ulx + (w * pixelSize);
401
                double lry = uly + (h * pixelSize);
402
                return new ExtentImpl(ulx, uly, lrx, lry);
403
        }
404
        
405
        /**
406
         * Adjust de level to the range
407
         * @param level
408
         * @return
409
         */
410
        private int adjustLevel(int level) {
411
                if(level < 0)
412
                        level = 0;
413
                if(level > getZoomLevels())
414
                        level = getZoomLevels();
415
                return level;
416
        }
417
        
418
        public AffineTransform getAffineTransform() {
419
                return provider.getAffineTransform();
420
        }
421
        
422
        /**
423
         * Obtiene el objeto que contiene el estado de la transparencia
424
         */
425
        public Transparency getTransparency() {
426
                return provider.getTransparency();
427
        }
428
        
429
        /**
430
         * Gets the bounding box in world coordinates. If the layer has grid subsets (TileMatrixLimits) then
431
         * this will have a only extent but if the layer doesn't have grid subsets then this will have a different
432
         * extent in each level resolution. In this case we need to know the extent for each level.
433
         * @return Extent
434
         */
435
        public Extent getExtent() {
436
                return provider.getExtent();
437
        }
438

    
439
        public RasterProvider load() {
440
                return this;
441
        }
442
        
443
        public boolean isOpen() {
444
                return open;
445
        }
446

    
447
        public boolean isTiled() {
448
                return true;
449
        }
450
        
451
        public void close() {
452
                open = false;
453
                if(provider != null)
454
                        provider.close();
455
        }
456
        
457
        public String translateFileName(String fileName) {
458
                return fileName;
459
        }
460

    
461
        public void setView(Extent e) {
462
                viewRequest = e;
463
        }
464

    
465
        public Extent getView() {
466
                return viewRequest;
467
        }
468

    
469
        public double getWidth() {
470
                return provider.getWidth();
471
        }
472

    
473
        public double getHeight() {
474
                return provider.getHeight();
475
        }
476

    
477
        public Object readCompleteLine(int line, int band)
478
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
479
                return null;
480
        }
481
        
482
        public File getFileLayer() throws RasterDriverException {
483
                return null;
484
        }
485

    
486
        /**
487
         * Reads a complete block of data and returns an tridimensional array of the right type. This function is useful
488
         * to read a file very fast without setting a view. 
489
         * 
490
         * @param pos Posici?n donde se empieza  a leer
491
         * @param blockHeight Altura m?xima del bloque leido
492
         * @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
493
         * @throws InvalidSetViewException
494
         * @throws FileNotOpenException
495
         * @throws RasterDriverException
496
         */
497
        public Object readBlock(int pos, int blockHeight, double scale) 
498
        throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
499
                return provider.readBlock(pos, blockHeight, scale);
500
        }
501

    
502
        public Object getData(int x, int y, int band)
503
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
504
                return provider.getData(x, y, band);
505
        }
506
        
507
        /**
508
         * Assigns the list of bands RGB and read a window of data
509
         * @param rasterBuf
510
         * @param bandList
511
         * @param lastFile
512
         * @param ulx
513
         * @param uly
514
         * @param lrx
515
         * @param lry
516
         * @return
517
         * @throws RasterDriverException
518
         * @throws ProcessInterruptedException
519
         */
520
        public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile, 
521
                        double ulx, double uly, double lrx, double lry) throws RasterDriverException, ProcessInterruptedException {
522
                return null;
523
        }
524
        
525
        /**
526
         * Calculates the extent of a zoom level using other extent as a reference. The new extent is 
527
         * calculated with the same coordinate at the center. 
528
         * @param level
529
         * @param extent
530
         * @param w
531
         * @param h
532
         * @return
533
         */
534
        public Extent getZoomLevelCoordinates(int level, Extent extent, int w, int h) {
535
                double centerX = extent.getCenterX();
536
                double centerY = extent.getCenterY();
537
                return getCoordsInLevel(new Point2D.Double(centerX, centerY), level, w, h);
538
        }
539
        
540
        /**
541
         * Gets the tile list in a selected extent
542
         * @param ex
543
         * @param bandList
544
         * @param bufWidth
545
         * @param bufHeight
546
         * @return
547
         * @throws TileBuildException 
548
         */
549
        private List<Tile> getTileList(Extent ex, BandList bandList, int bufWidth, int bufHeight) throws TileBuildException {
550
                TileServer tileServer = provider.getTileServer();
551
                CacheStruct struct = tileServer.getStruct();
552
                tileServer.setFileSuffix(getFileSuffix());
553
                
554
                createTiledLayer(); //Creates a new layer when the file type changes
555
                
556
                Extent adjustedExtent = util.intersection(provider.getExtent(), ex);
557
                double newBufWidth = (adjustedExtent.width() * bufWidth) / ex.width();
558
                double pixelSizeRequest = adjustedExtent.width() / newBufWidth; 
559
                
560
                List<Tile> tileList = struct.getTileList(
561
                                adjustedExtent.getUL(), 
562
                                adjustedExtent.getLR(), 
563
                                pixelSizeRequest);
564
                
565
                for (int i = 0; i < tileList.size(); i++) {
566
                        loadTileTimeParameters(tileList.get(i));
567
                }
568
                
569
                for (int i = 0; i < tileList.size(); i++) {
570
                        tileList.get(i).setDownloaderParams("BandList", bandList.clone());
571
                }
572
                return tileList;
573
        }
574
        
575
        /**
576
         * Loads the multidimensional parameters in a tile 
577
         * @param tile
578
         */
579
        private void loadTileTimeParameters(Tile tile) {
580
                if(provider.getDataParameters() instanceof MultiDimensionalStoreParameters) {
581
                        MultiDimensionalStoreParameters par = (MultiDimensionalStoreParameters)provider.getDataParameters();
582
                        tile.setVariable(par.getStringVariable());
583
                        tile.setZ(par.getStringLevel());
584
                        tile.setTimeInstant(par.getStringTime());
585
                }
586
        }
587
        
588
        public boolean needEnhanced() {
589
                return provider.needEnhanced();
590
        }
591
        
592
        public Tile getTile(SpiRasterQuery q) throws TileGettingException {
593
                if(q.getCacheStruct() == null)
594
                        q.setCacheStruct(provider.getTileServer().getStruct());
595
                else
596
                        provider.getTileServer().setStruct(q.getCacheStruct());
597
                
598
                Tile tile = null;
599
                try {
600
                        tile = q.getCacheStruct().getTileStructure(
601
                                        q.getResolutionLevel(), q.getTileCol(), q.getTileRow(), 
602
                                        q.getAdjustedRequestBoundingBox().getUL(), 
603
                                        q.getAdjustedRequestBoundingBox().getLR());
604
                } catch (TileBuildException e1) {
605
                        throw new TileGettingException(e1);
606
                }
607
                
608
                loadTileTimeParameters(tile);
609
                
610
                //Creamos un BandList con todas las bandas del fichero
611
                BandList bandList = new BandListImpl();
612
                for(int i = 0; i < provider.getBandCount(); i++) {
613
                        try {
614
                                DatasetBand band = new DatasetBandImpl(provider.getURIOfFirstProvider(), i, provider.getDataType()[i], provider.getBandCount());
615
                                bandList.addBand(band);
616
                        } catch(BandNotFoundInListException e) {
617
                                //No a?adimos la banda
618
                        }
619
                }
620
                bandList.setDrawableBands(new int[]{0, 1, 2});
621
                
622
                tile.setDownloaderParams("BandList", bandList);
623
                createTiledLayer();
624
                return tiledLayer.getTile(tile);
625
        }
626
        
627
        @Override
628
        public void loadBuffer(SpiRasterQuery q) 
629
                        throws ProcessInterruptedException, RasterDriverException {
630
                try {
631
                        List<Tile> tileList = getTileList(
632
                                        q.getAdjustedRequestBoundingBox(), 
633
                                        q.getBandList(), 
634
                                        q.getAdjustedBufWidth(), 
635
                                        q.getAdjustedBufHeight());
636
                        if(q.requestIsTiled())
637
                                tiledLayer.getTiles(tileList, q.getTileListener(), q.getTaskStatus());
638
                        else {
639
                                /* TODO: De esta forma las peticiones no tileadas se hacen a los tiles.
640
                                 * Funciona bien pero habr?a que revisar la memoria que consume MemoryTileMatrixBuffer
641
                                 * En cualquier caso parece que llamar directamente al proveedor que se est? tileando
642
                                 * No da problemas y el resultado de los procesos ser?a el mismo que en la capa sin tilear.
643
                                 for (int i = 0; i < tileList.size(); i++) {
644
                                        tiledLayer.getTile(tileList.get(i));
645
                                }
646
                                MemoryTileMatrixBuffer matrixBuffer = new MemoryTileMatrixBuffer(tileList);
647
                                Buffer buf = matrixBuffer.getWindow(q.getAdjustedRequestBoundingBox(), q.getBufferForProviders());
648
                                q.setBufferResult(buf);*/
649
                                ((AbstractRasterProvider)provider).loadBuffer(q);
650
                        }
651
                        
652
                } catch (TileGettingException e) {
653
                        throw new RasterDriverException("Error getting the tile list", e);
654
                } catch (TileBuildException e) {
655
                        throw new RasterDriverException("Error building the tile list", e);
656
                }
657
                
658
        }
659

    
660
        public int getBlockSize() {
661
                return 0;
662
        }
663

    
664
        public void setAffineTransform(AffineTransform t){
665
                
666
        }
667

    
668
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
669
                return getZoomLevels();
670
        }
671

    
672
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
673
                return provider.getTileServer().getStruct().getLayerWidthOfTileMatrixByLevel(overview) * 
674
                                provider.getTileServer().getStruct().getTileSizeByLevel(overview)[0];
675
        }
676

    
677
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
678
                return provider.getTileServer().getStruct().getLayerHeightOfTileMatrixByLevel(overview) * 
679
                                provider.getTileServer().getStruct().getTileSizeByLevel(overview)[0];
680
        }
681

    
682
        public boolean isOverviewsSupported() {
683
                return false;
684
        }
685

    
686
        public String getName() {
687
                return NAME;
688
        }
689
        
690
        /**
691
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
692
         * @param pt Punto a transformar
693
         * @return punto transformado en coordenadas del mundo
694
         */
695
        public Point2D rasterToWorld(Point2D pt) {
696
                Point2D p = new Point2D.Double();
697
                getAffineTransform().transform(pt, p);
698
                return p;
699
        }
700

    
701
        /**
702
         * Convierte un punto desde del mundo a coordenadas pixel.
703
         * @param pt Punto a transformar
704
         * @return punto transformado en coordenadas pixel
705
         */
706
        public Point2D worldToRaster(Point2D pt) {
707
                Point2D p = new Point2D.Double();
708
                try {
709
                        getAffineTransform().inverseTransform(pt, p);
710
                } catch (NoninvertibleTransformException e) {
711
                        return pt;
712
                }
713
                return p;
714
        }
715
        
716
        public void setStatus(RasterProvider provider) {
717
                if(provider instanceof TileProvider) {
718
                }
719
        }
720
        
721
        /**
722
         * ASigna el par?metro de inicializaci?n del driver.
723
         */
724
        @Override
725
        public void setParam(DataStoreProviderServices storeServices, DataStoreParameters param) {
726
                if(param instanceof RemoteStoreParameters)
727
                        this.uri = ((RasterDataParameters)param).getURI();
728
                this.param = param;
729
                this.storeServices = storeServices;
730
        }
731
        
732
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
733
                if(provider != null)
734
                        return provider.getInfoByPoint(x, y, cancellable);
735
                return "Not implemented";
736
        }
737
        
738
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
739
                if(provider != null)
740
                        return provider.getInfoByPoint(x, y, bbox, w, h, cancellable);
741
                return "Not implemented";
742
        }
743
        
744
        public ColorInterpretation getColorInterpretation() {
745
                return provider.getColorInterpretation();
746
        }
747

    
748
        /**
749
         * Asigna el objeto que contiene que contiene la interpretaci?n de
750
         * color por banda
751
         * @param DataStoreColorInterpretation
752
         */
753
        public void setColorInterpretation(ColorInterpretation colorInterpretation) {
754
                provider.setColorInterpretation(colorInterpretation);
755
        }
756
        
757
        public int[] getTileSize(int level) {
758
                return provider.getTileServer().getStruct().getTileSizeByLevel(level);
759
        }
760
        
761
        public void deleteLayerFromCache() {
762
                TileCacheManager  manager = TileCacheLocator.getManager();
763
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
764
                if(tiledLayer != null)
765
                        tileCache.removeLayer(tiledLayer);
766
        }
767
        
768
        public TileServer getTileServer() {
769
                return secondLevelTileServer;
770
        }
771
        
772
        public void setSecondLevelTileServer(TileServer tileServer) {
773
                this.secondLevelTileServer = tileServer;
774
        }
775
        
776
        public void setTileServer(Class<?> tileServer) throws InitializeException {
777
                //TODO:Manejar excepciones
778
                //Crear par?metros
779
                TileDataParametersImpl par = new TileDataParametersImpl();
780
                par.setDataParameters(getDataParameters());
781
                par.setSecondLevelCache(true); //No crea un nuevo provider
782
                
783
                //Crea el proveedor de tiles de segundo nivel
784
                TileProvider newProvider = null;
785
                newProvider = new TileProvider(par, null);
786
                newProvider.setProvider(this.provider);
787

    
788
                //Instancia el TileServer pasado por el cliente con el TileProvider de segundo nivel
789
                Constructor<?> constructor;
790
                TileServer tServer = null;
791
                try {
792
                        constructor = tileServer.getConstructor(new Class<?>[]{AbstractRasterProvider.class});
793
                        Object [] args2 = {newProvider};
794
                        tServer = (TileServer)constructor.newInstance(args2);
795
                } catch (SecurityException e) {
796
                        e.printStackTrace();
797
                } catch (NoSuchMethodException e) {
798
                        e.printStackTrace();
799
                } catch (IllegalArgumentException e) {
800
                        e.printStackTrace();
801
                } catch (InstantiationException e) {
802
                        e.printStackTrace();
803
                } catch (IllegalAccessException e) {
804
                        e.printStackTrace();
805
                } catch (InvocationTargetException e) {
806
                        e.printStackTrace();
807
                }
808
                
809
                //Asigna el TileServer al nuevo provider de segundo nivel
810
                newProvider.setSecondLevelTileServer(tServer);
811
                
812
                //Asigna al provider de tiles de primer nivel el de segundo. 
813
                //Solo si las estructuras de cach? son diferentes
814
                if(!provider.getTileServer().getStruct().compare(tServer.getStruct())) {
815
                        this.setProvider(newProvider);
816
                        tiledLayer = null;
817
                }
818
        }
819
        
820
}