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

History | View | Annotate | Download (34.5 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.net.URI;
13
import java.util.List;
14

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

    
83
import org.slf4j.Logger;
84
import org.slf4j.LoggerFactory;
85

    
86
/**
87
 * Provider for WMTS service
88
 *
89
 * @author Nacho Brodin (nachobrodin@gmail.com)
90
 */
91
public class TileProvider extends AbstractRasterProvider implements TiledRasterProvider {
92
        public static String                NAME                     = "Tile Store";
93
        public static String                DESCRIPTION              = "Raster Tiled Source";
94
        public static final String          METADATA_DEFINITION_NAME = "TileStore";
95
        private static final Logger         logger                   = LoggerFactory.getLogger(TileProvider.class);
96
        private RasterProvider              provider                 = null;
97
        private boolean                     open                     = false;
98
        private Extent                      viewRequest              = null;
99
        private TiledLayer                  tiledLayer               = null;
100
        private MathUtils                   math                     = RasterLocator.getManager().getMathUtils();
101
        private TileServer                  secondLevelTileServer    = null;
102

    
103
        /**
104
         * Register in data manager
105
         */
106
        public static void register() {
107
                DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
108
                if (dataman != null && !dataman.getStoreProviders().contains(NAME)) {
109
                        dataman.registerStoreProvider(NAME,
110
                                        TileProvider.class, TileDataParametersImpl.class);
111
                }
112

    
113
                /*if(DALFileLocator.getFilesystemServerExplorerManager() != null)
114
                        DALFileLocator.getFilesystemServerExplorerManager().registerProvider(
115
                                        NAME, DESCRIPTION,
116
                                        TileServerExplorer.class);*/
117

    
118
                if (!dataman.getExplorerProviders().contains(TileServerExplorer.NAME)) {
119
                        dataman.registerExplorerProvider(TileServerExplorer.NAME, TileServerExplorer.class, TileServerExplorerParameters.class);
120
                }
121
                dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
122
        }
123

    
124
        /**
125
         * Loads the specific provider to download data
126
         * @param file
127
         * @return
128
         * @throws NotSupportedExtensionException
129
         * @throws FileNotSupportedException
130
         */
131
        @SuppressWarnings("unchecked")
132
        private RasterProvider loadProvider(TileDataParametersImpl params, DataStoreProviderServices storeServices) throws ProviderNotRegisteredException, InitializeException {
133
                Object obj = params.getDataParameters();
134
                DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
135
                DataStoreProvider prov = null;
136

    
137
                if(obj != null && obj instanceof DataStoreParameters) //Remote
138
                        prov = dataManager.createProvider(storeServices, (DataStoreParameters)obj);
139
                else { //File
140
                        if(params.getFile() != null) {
141
                                //We have to locate a provider's name which manages the selected file
142
                                //A FilesystemServerExplorer will give a getProviderNames service
143
                                FilesystemServerExplorerParameters paramsExplorer = (FilesystemServerExplorerParameters)dataManager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
144
                                FilesystemServerExplorer serverExplorer = null;
145
                                try {
146
                                        paramsExplorer.setRoot(File.separator);
147
                                        serverExplorer = (FilesystemServerExplorer)dataManager.openServerExplorer(FilesystemServerExplorer.NAME, paramsExplorer);
148
                                } catch (ValidateDataParametersException e) {
149
                                        throw new InitializeException(e);
150
                                }
151

    
152
                                //Gets the list of provider's name to manage the file
153
                                List<String> provName = serverExplorer.getProviderNameList(params.getFile());
154
                                if(provName.size() > 0) {
155
                                        for (int i = 0; i < provName.size(); i++) {
156
                                                //Gets the first provider what is not a TileProvider
157
                                                if(provName.get(i).compareTo(NAME) != 0) {
158
                                                        DataStoreParameters newparams = dataManager.createStoreParameters(provName.get(i));
159
                                                        ((FilesystemStoreParameters)newparams).setFile(params.getFile());
160
                                                        prov = dataManager.createProvider(storeServices, newparams);
161
                                                }
162
                                        }
163
                                }
164
                        }
165
                }
166

    
167
                if(prov != null && prov instanceof RasterProvider) {
168
                        if(((RasterProvider)prov).isRotated())
169
                                throw new InitializeException("Rotation not supported tiling files", new Throwable());
170

    
171
                        return (RasterProvider)prov;
172
                }
173

    
174
                return null;
175
        }
176

    
177
        /**
178
         * @return the internal provider used to feed the TileProvider
179
         */
180
        public RasterProvider getInternalProvider() {
181
                return provider;
182
        }
183

    
184
        public Image getImageLegend() {
185
                return provider.getImageLegend();
186
        }
187

    
188
        public ColorInterpretation getColorInterpretation() {
189
                return provider.getColorInterpretation();
190
        }
191

    
192
        public String getFileSuffix() {
193
                try {
194
            return provider.getFileSuffix();
195
                } catch(Throwable e) {
196
                        return "tif";
197
                }
198
        }
199

    
200
        public File getRMFFile() {
201
                TileCacheManager  manager = TileCacheLocator.getManager();
202
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
203

    
204
                String metadataDir = tiledLayer.getBaseLayerDirectory().substring(0, tiledLayer.getBaseLayerDirectory().lastIndexOf(File.separator) + 1) +
205
                                                          tileCache.getConfigurationDirectory();
206

    
207
                File metadaDirFile = new File(metadataDir);
208
                if(!metadaDirFile.exists())
209
                        metadaDirFile.mkdir();
210

    
211
                String path = metadataDir + File.separator + tiledLayer.getID() + ".rmf";
212

    
213
                try {
214
            if (!new File(path).exists() && provider != null && provider.getRMFFile() != null
215
                && provider.getRMFFile().exists()) {
216
                RasterLocator.getManager().getFileUtils().copyFile(provider.getRMFFile().getAbsolutePath(), path);
217
            }
218

    
219
                        if(provider != null && provider.getColorTable() != null) {
220
                                ColorTable colorTable = provider.getColorTable();
221
                                RasterLocator.getManager().getProviderServices().saveObjectToRmfFile(path, ColorTable.class, colorTable);
222
                        }
223
                } catch (LocatorException e) {
224
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
225
                } catch (FileNotFoundException e) {
226
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
227
                } catch (IOException e) {
228
                        logger.info("No se ha podido copiar el fichero RMF a la capa tileada", e);
229
                } catch (RmfSerializerException e) {
230
                        logger.info("No se ha podido copiar la tabla de color a la capa tileada", e);
231
                }
232
                return new File(path);
233
        }
234

    
235
        /**
236
         * @throws NotSupportedExtensionException
237
         */
238
        public TileProvider() throws NotSupportedExtensionException {
239
                super();
240
        }
241

    
242
        /**
243
         * @param c
244
         */
245
        public void registerTileProviderFormats(Class<RasterProvider> c) {
246

    
247
        }
248

    
249
        /**
250
         * Assigns the provider associated to this tile server
251
         * @param prov
252
         * @throws InitializeException
253
         * @throws NotSupportedExtensionException
254
         */
255
        public void setProvider(RasterProvider prov) throws InitializeException  {
256
                this.provider = prov;
257
                init(getDataStoreParameters(), getStoreServices());
258
        }
259

    
260
        /**
261
         * @param params
262
         * @param storeServices
263
         * @throws InitializeException
264
         */
265
        public TileProvider(TileDataParametersImpl params,
266
                        DataStoreProviderServices storeServices) throws InitializeException {
267
                super(params, storeServices, ToolsLocator.getDynObjectManager()
268
                                .createDynObject(
269
                                                MetadataLocator.getMetadataManager().getDefinition(
270
                                                                DataStore.METADATA_DEFINITION_NAME)));
271
                if(!params.isSecondLevelCache()) {
272
                        try {
273
                                provider = loadProvider(params, storeServices);
274
                        } catch (ProviderNotRegisteredException e) {
275
                                throw new InitializeException("Provider not registered", e);
276
                        }
277
                        init(params, storeServices);
278
                        if(provider.getFileSizeByProvider() != null && provider.getFileSizeByProvider().length > 0)
279
                                fileSize = provider.getFileSizeByProvider()[0];
280
                }
281
        }
282

    
283
        /**
284
         * Creates the second level cache if the client has set a <code>TileServer</code> and the
285
         * <code>CacheStruct</code> is different that the old one.
286
         * <UL>
287
         * <LI>First level cache without TileServer from the client: do nothing</LI>
288
         * <LI>First level cache with TileServer from the client and the structure is
289
         * different to the old one: Builds a second level TileProvider</LI>
290
         * <LI>First level cache with TileServer from the client and the structure is
291
         * equal to the old one: do nothing</LI>
292
         * <LI>Second level cache: sets the TileServer</LI>
293
         * </UL>
294
         * @param params
295
         * @param storeServices
296
         * @throws NotSupportedExtensionException
297
         */
298
        /*private void createsSecondLevelCache(TileDataParametersImpl params) throws NotSupportedExtensionException {
299
                //Se obtiene el TileServer que haya pasado el cliente en los par?metros si ha pasado alguno.
300
                TileServer tileServer = params.getTileServer();
301
                //Se obtiene el CacheStruct y se compara con el del provider
302
                CacheStruct cacheStruct = null;
303
                if(tileServer != null)
304
                        cacheStruct = tileServer.getStruct();
305

306
                if(params.isSecondLevelCache()) { //Cache de segundo nivel
307
                        this.secondLevelTileServer = tileServer;
308
                } else if(cacheStruct != null && !provider.getTileServer().getStruct().compare(cacheStruct)) { //Cache de primer nivel
309
                        //Si son distintos habr? que crear una cach? de segundo nivel por lo que creamos un nuevo TileProvider
310
                        //que tenga como par?metro el provider viejo
311
                        TileDataParametersImpl par = new TileDataParametersImpl();
312
                        par.setDataParameters(provider.getDataParameters());
313
                        par.setTileServer(tileServer);
314
                        par.setSecondLevelCache(true);
315
                        TileProvider newProvider = new TileProvider(par, null);
316
                        newProvider.setProvider(this.provider);
317
                        //Al TileProvider actual se le asigna como provider el TileProvider creado
318
                        this.provider = newProvider;
319
                }
320
        }*/
321

    
322
        /**
323
         * Crea las referencias al fichero y carga
324
         * las estructuras con la informaci?n y los metadatos.
325
         * @param params
326
         * @param storeServices
327
         * @throws InitializeException
328
         * @throws NotSupportedExtensionException
329
         */
330
        public void init (DataStoreParameters params,
331
                        DataStoreProviderServices storeServices) throws InitializeException  {
332
                setParam(storeServices, params);
333
                open = true;
334
                calculateDataType();
335
                calculateBandCount();
336
                calculateColorInterpretation();
337
                calculateTransparency();
338
                setColorTable(provider.getColorTable());
339
                noData = provider.getNoDataValue();
340
                uri = provider.getURIOfFirstProvider();
341
                proj = provider.getProjection();
342
                ownTransformation = provider.getAffineTransform();
343
                externalTransformation = (AffineTransform)ownTransformation.clone();
344

    
345
                createTiledLayer();
346

    
347
                //Force to deletes the layer if the flag is to true
348
                if(tiledLayer != null) {
349
                        if(param instanceof TileDataParameters) {
350
                                if(((TileDataParameters)param).isDeletingCache()) {
351
                                        TileCacheManager  manager = TileCacheLocator.getManager();
352
                                        TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
353
                                        tileCache.removeLayer(tiledLayer);
354
                                        ((TileDataParameters)param).deleteCache(false);
355
                                }
356
                        }
357
                }
358

    
359
                if(provider instanceof RemoteRasterProvider)
360
                        stats = new RemoteDataStoreStatistics(provider);
361
        }
362

    
363
        /**
364
         * Calculates the data type of this provider
365
         */
366
        public void calculateDataType() {
367
                int[] datatype = null;
368
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
369
                        datatype = new int[provider.getBandCount() + 1];
370
                else
371
                        datatype = new int[provider.getBandCount()];
372
                for (int i = 0; i < provider.getDataType().length; i++) {
373
                        datatype[i] = provider.getDataType()[i];
374
                }
375
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
376
                        datatype[datatype.length - 1] = Buffer.TYPE_BYTE;
377
                setDataType(datatype);
378
        }
379

    
380
        /**
381
         * Calculates the number of bands
382
         */
383
        public void calculateBandCount() {
384
                bandCount = provider.getBandCount();
385
                if(provider.getDataType()[0] == Buffer.TYPE_BYTE && provider.getBandCount() == 3)
386
                        bandCount ++;
387
        }
388

    
389
        /**
390
         * Calculates the color interpretation
391
         */
392
        public void calculateColorInterpretation() {
393
                ColorInterpretation ci = provider.getColorInterpretation();
394
                if(ci != null) {
395
                        if(ci.isRGB() || ci.isBGR()) {
396
                                ci = DataStoreColorInterpretation.createRGBAInterpretation();
397
                        } else
398
                                ci = ci.cloneColorInterpretation();
399
                } else {
400
                        if(provider.getDataType()[0] == Buffer.TYPE_BYTE) {
401
                                if(provider.getBandCount() == 3)
402
                                        ci = DataStoreColorInterpretation.createRGBAInterpretation();
403
                                else
404
                                        ci = DataStoreColorInterpretation.createDefaultInterpretation(getBandCount());
405
                        } else {
406
                                if(getBandCount() == 1)
407
                                        ci = DataStoreColorInterpretation.createGrayInterpretation();
408
                                else
409
                                        ci = DataStoreColorInterpretation.createDefaultInterpretation(getBandCount());
410
                        }
411
                }
412

    
413
                super.setColorInterpretation(ci);
414
        }
415

    
416

    
417
        /**
418
     * Calculates the transparency
419
         */
420
        public void calculateTransparency() {
421
                if(provider.getTransparency() != null)
422
                        transparency = provider.getTransparency().cloneTransparency();
423
                else
424
                        transparency = new DataStoreTransparency(getColorInterpretation());
425
                if(getColorInterpretation() != null) {
426
                        transparency.setColorInterpretation(getColorInterpretation());
427
                        transparency.setTransparencyBand(getColorInterpretation().getAlphaBand());
428
                        transparency.activeTransparency();
429
                }
430
        }
431

    
432
        /**
433
         * Creates a new tiled layer if this hasn't been created yet or the ID has changed.
434
         * An ID could changed because the file type has changed when the user uses WMTS properties.
435
         */
436
        private void createTiledLayer() {
437
                TileCacheManager  manager = TileCacheLocator.getManager();
438
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
439
                TiledLayer newLayer = tileCache.createLayer(provider.getTileServer(), TileCacheLibrary.DEFAULT_STRUCTURE);
440
                if(tiledLayer == null || newLayer.getID().compareTo(tiledLayer.getID()) != 0)
441
                        tiledLayer = newLayer;
442
        }
443

    
444
        public void reload() {
445
                try {
446
                        loadFromRmf(getRmfBlocksManager());
447
                        calculateColorInterpretation();
448
                        calculateTransparency();
449
                } catch (ParsingException e) {
450
                        logger.debug("No se ha podido leer el RMF", e);
451
                }
452
        }
453

    
454
        public int getZoomLevels() {
455
                if(provider.getTileServer() != null)
456
                        return provider.getTileServer().getStruct().getNumberOfLevels();
457
                return 0;
458
        }
459

    
460
        public int getNearestLevel(double pixelSize) {
461
                double[] pixelSizes = getPixelSizeByLevel();
462
                for (int i = 0; i < pixelSizes.length - 1; i++) {
463
                        if(pixelSize <= pixelSizes[i] && pixelSize > pixelSizes[i + 1]) {
464
                                return i;
465
                        }
466
                }
467
                if(pixelSize < pixelSizes[getZoomLevels() - 1])
468
                        return getZoomLevels() - 1;
469
                return 0;
470
        }
471

    
472
        /**
473
         * @return a list of pixel sizes by level
474
         */
475
        public double[] getPixelSizeByLevel() {
476
                double[] list = new double[getZoomLevels()];
477
                CacheStruct struct = provider.getTileServer().getStruct();
478
                for (int i = 0; i < struct.getNumberOfLevels(); i++) {
479
                        list[i] = math.adjustDouble(struct.getPixelSizeByLevel(i));
480
                }
481
                return list;
482
        }
483

    
484
        public Extent getCoordsInTheNearestLevel(Extent extent, int w, int h) {
485
                double[] pixelSizes = getPixelSizeByLevel();
486
                double currentPixelSize = extent.width() / (double)w;
487

    
488
                int level = 0;
489
                for (int i = 0; i < (pixelSizes.length - 1); i++) {
490
                        if(currentPixelSize < pixelSizes[i] && currentPixelSize >= pixelSizes[i + 1]) {
491
                                level = i + 1;
492
                                break;
493
                        }
494
                }
495

    
496
                return getZoomLevelCoordinates(level, extent, w, h);
497
        }
498

    
499
        public Extent getCoordsInLevel(Point2D viewCenter, int level, int w, int h) {
500
                level = adjustLevel(level);
501
                double pixelSize = provider.getTileServer().getStruct().getPixelSizeByLevel(level);
502

    
503
                /*Rectangle2D worldExtent = provider.getTileServer().getStruct().getWorldExtent();
504
                int nTiles = provider.getTileServer().getStruct().getLayerWidthOfTileMatrixByLevel(level);
505
                int[] nPixelsByTile = provider.getTileServer().getStruct().getTileSizeByLevel(level);
506

507
                double sizeWCByTile = worldExtent.getWidth() / (double)nTiles;
508
                double pixelSize = sizeWCByTile / (double)nPixelsByTile[0];*/
509

    
510
                double ulx = viewCenter.getX() - ((w / 2) * pixelSize);
511
                double uly = viewCenter.getY() - ((h / 2) * pixelSize);
512
                double lrx = ulx + (w * pixelSize);
513
                double lry = uly + (h * pixelSize);
514
                return new ExtentImpl(ulx, uly, lrx, lry);
515
        }
516

    
517
        /**
518
         * Adjust de level to the range
519
         * @param level
520
         * @return
521
         */
522
        private int adjustLevel(int level) {
523
                if(level < 0)
524
                        level = 0;
525
                if(level > getZoomLevels())
526
                        level = getZoomLevels();
527
                return level;
528
        }
529

    
530
        public AffineTransform getAffineTransform() {
531
                return provider.getAffineTransform();
532
        }
533

    
534
        /**
535
         * Gets the bounding box in world coordinates. If the layer has grid subsets (TileMatrixLimits) then
536
         * this will have a only extent but if the layer doesn't have grid subsets then this will have a different
537
         * extent in each level resolution. In this case we need to know the extent for each level.
538
         * @return Extent
539
         */
540
        public Extent getExtent() {
541
                return provider.getExtent();
542
        }
543

    
544
        public RasterProvider load() {
545
                return this;
546
        }
547

    
548
        public boolean isOpen() {
549
                return open;
550
        }
551

    
552
        public boolean isTiled() {
553
                return true;
554
        }
555

    
556
        public void close() {
557
                open = false;
558
                if(provider != null)
559
                        provider.close();
560
        }
561

    
562
        public URI translateURI(URI uri) {
563
                return uri;
564
        }
565

    
566
        public void setView(Extent e) {
567
                viewRequest = e;
568
        }
569

    
570
        public Extent getView() {
571
                return viewRequest;
572
        }
573

    
574
        public double getWidth() {
575
                return provider.getWidth();
576
        }
577

    
578
        public double getHeight() {
579
                return provider.getHeight();
580
        }
581

    
582
        /**
583
         * @param line
584
         * @param band
585
         * @return a complete line
586
         * @throws InvalidSetViewException
587
         * @throws FileNotOpenException
588
         * @throws RasterDriverException
589
         */
590
        public Object readCompleteLine(int line, int band)
591
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
592
                return null;
593
        }
594

    
595
        /**
596
         * @return the file
597
         * @throws RasterDriverException
598
         */
599
        public File getFileLayer() throws RasterDriverException {
600
                return null;
601
        }
602

    
603
        @SuppressWarnings("deprecation")
604
        public Object readBlock(int pos, int blockHeight, double scale)
605
        throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
606
                //TODO: temporal hasta que haya un generador de estad?sticas parciales para realce.
607
                //Pongo este m?todo deprecated porque el objetivo es eliminarlo de los proveedores.
608
                if(provider.getBandCount() < getBandCount()) {
609
                        switch (getDataType()[0]) {
610
                        case Buffer.TYPE_BYTE:
611
                                byte[][][] buf1 = (byte[][][])provider.readBlock(pos, blockHeight, scale);
612
                                byte[][][] b1 = new byte[buf1.length + 1][][];
613
                                for (int i = 0; i < buf1.length; i++) {
614
                                        b1[i] = buf1[i];
615
                                }
616
                                b1[b1.length - 1] = new byte[buf1[0].length][buf1[0][0].length];
617
                                return b1;
618
                        case Buffer.TYPE_SHORT:
619
                                short[][][] buf2 = (short[][][])provider.readBlock(pos, blockHeight, scale);
620
                                short[][][] b2 = new short[buf2.length + 1][][];
621
                                for (int i = 0; i < buf2.length; i++) {
622
                                        b2[i] = buf2[i];
623
                                }
624
                                b2[b2.length - 1] = new short[buf2[0].length][buf2[0][0].length];
625
                                return b2;
626
                        case Buffer.TYPE_FLOAT:
627
                                float[][][] buf3 = (float[][][])provider.readBlock(pos, blockHeight, scale);
628
                                float[][][] b3 = new float[buf3.length + 1][][];
629
                                for (int i = 0; i < buf3.length; i++) {
630
                                        b3[i] = buf3[i];
631
                                }
632
                                b3[b3.length - 1] = new float[buf3[0].length][buf3[0][0].length];
633
                                return b3;
634
                        case Buffer.TYPE_DOUBLE:
635
                                double[][][] buf4 = (double[][][])provider.readBlock(pos, blockHeight, scale);
636
                                double[][][] b4 = new double[buf4.length + 1][][];
637
                                for (int i = 0; i < buf4.length; i++) {
638
                                        b4[i] = buf4[i];
639
                                }
640
                                b4[b4.length - 1] = new double[buf4[0].length][buf4[0][0].length];
641
                                return b4;
642
                        case Buffer.TYPE_INT:
643
                                int[][][] buf5 = (int[][][])provider.readBlock(pos, blockHeight, scale);
644
                                int[][][] b5 = new int[buf5.length + 1][][];
645
                                for (int i = 0; i < buf5.length; i++) {
646
                                        b5[i] = buf5[i];
647
                                }
648
                                b5[b5.length - 1] = new int[buf5[0].length][buf5[0][0].length];
649
                                return b5;
650
                        }
651

    
652
                }
653
                return provider.readBlock(pos, blockHeight, scale);
654
        }
655

    
656
        public Object getData(int x, int y, int band)
657
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
658
                return provider.getData(x, y, band);
659
        }
660

    
661
        /**
662
         * Assigns the list of bands RGB and read a window of data
663
         * @param rasterBuf
664
         * @param bandList
665
         * @param lastFile
666
         * @param ulx
667
         * @param uly
668
         * @param lrx
669
         * @param lry
670
         * @return the buffer
671
         * @throws RasterDriverException
672
         * @throws ProcessInterruptedException
673
         */
674
        public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile,
675
                        double ulx, double uly, double lrx, double lry) throws RasterDriverException, ProcessInterruptedException {
676
                return null;
677
        }
678

    
679
        /**
680
         * Calculates the extent of a zoom level using other extent as a reference. The new extent is
681
         * calculated with the same coordinate at the center.
682
         *
683
         * @param level
684
         * @param extent
685
         * @param w
686
         * @param h
687
         * @return the calculated extent
688
         */
689
        public Extent getZoomLevelCoordinates(int level, Extent extent, int w, int h) {
690
                double centerX = extent.getCenterX();
691
                double centerY = extent.getCenterY();
692
                return getCoordsInLevel(new Point2D.Double(centerX, centerY), level, w, h);
693
        }
694

    
695
        public boolean isRasterEnclosed() {
696
                if(provider != null)
697
                        return provider.isRasterEnclosed();
698
                return super.isRasterEnclosed();
699
        }
700

    
701
        /**
702
         * Gets the tile list in a selected extent
703
         * @param ex
704
         * @param bandList
705
         * @param bufWidth
706
         * @param bufHeight
707
         * @return
708
         * @throws TileBuildException
709
         */
710
        private List<Tile> getTileList(SpiRasterQuery q) throws TileBuildException {
711
                TileServer tileServer = provider.getTileServer();
712
                CacheStruct struct = tileServer.getStruct();
713

    
714
                createTiledLayer(); //Creates a new layer when the file type changes
715

    
716
                double pixelSizeRequest = q.getRequestBoundingBox().width() / q.getBufWidth();
717

    
718
                List<Tile> tileList = struct.getTileList(
719
                                        q.getAdjustedRequestBoundingBox().getUL(),
720
                                        q.getAdjustedRequestBoundingBox().getLR(),
721
                                        pixelSizeRequest);
722

    
723
                for (int i = 0; i < tileList.size(); i++) {
724
                        loadTileTimeParameters(tileList.get(i));
725
                }
726

    
727
                for (int i = 0; i < tileList.size(); i++) {
728
                        tileList.get(i).setDownloaderParams("BandList", q.getBandList().clone());
729
                }
730
                return tileList;
731
        }
732

    
733
        /**
734
         * Loads the multidimensional parameters in a tile
735
         * @param tile
736
         */
737
        private void loadTileTimeParameters(Tile tile) {
738
                if(provider.getDataParameters() instanceof MultiDimensionalStoreParameters) {
739
                        MultiDimensionalStoreParameters par = (MultiDimensionalStoreParameters)provider.getDataParameters();
740
                        tile.setVariable(par.getStringVariable());
741
                        tile.setZ(par.getStringLevel());
742
                        tile.setTimeInstant(par.getStringTime());
743
                }
744
        }
745

    
746
        public boolean needEnhanced() {
747
                return provider.needEnhanced();
748
        }
749

    
750
        public Tile getTile(SpiRasterQuery q) throws TileGettingException {
751
                if(q.getCacheStruct() == null)
752
                        q.setCacheStruct(provider.getTileServer().getStruct());
753
                else
754
                        provider.getTileServer().setStruct(q.getCacheStruct());
755

    
756
                Tile tile = null;
757
                try {
758
                        tile = q.getCacheStruct().getTileStructure(
759
                                        q.getResolutionLevel(), q.getTileCol(), q.getTileRow(),
760
                                        q.getAdjustedRequestBoundingBox().getUL(),
761
                                        q.getAdjustedRequestBoundingBox().getLR());
762
                } catch (TileBuildException e1) {
763
                        throw new TileGettingException(e1);
764
                }
765

    
766
                loadTileTimeParameters(tile);
767

    
768
                //Creamos un BandList con todas las bandas del fichero
769
                BandList bandList = new BandListImpl();
770
                for(int i = 0; i < provider.getBandCount(); i++) {
771
                        try {
772
                                DatasetBand band = new DatasetBandImpl(
773
                                    provider.getURIOfFirstProvider(),
774
                                    i,
775
                                    provider.getDataType()[i],
776
                                    provider.getBandCount());
777

    
778
                                bandList.addBand(band);
779
                        } catch(BandNotFoundInListException e) {
780
                                //No a?adimos la banda
781
                        }
782
                }
783
                bandList.setDrawableBands(new int[]{0, 1, 2});
784

    
785
                tile.setDownloaderParams("BandList", bandList);
786
                createTiledLayer();
787
                return tiledLayer.getTile(tile);
788
        }
789

    
790
        @Override
791
        public void loadBuffer(SpiRasterQuery q)
792
                        throws ProcessInterruptedException, RasterDriverException {
793
                try {
794

    
795
                        if(q.requestIsTiled()) {
796
                                List<Tile> tileList = getTileList(q);
797
                                tiledLayer.getTiles(tileList, q.getTileListener(), q.getTaskStatus());
798
                        } else {
799
                                if(provider.isTiled()) {
800
                                        queryToInternalTiledProvider(q);
801
                                } else {
802
                                        queryToInternalProvider(q);
803
                                }
804
                        }
805

    
806
                } catch (TileGettingException e) {
807
                        throw new RasterDriverException("Error getting the tile list", e);
808
                } catch (TileBuildException e) {
809
                        throw new RasterDriverException("Error building the tile list", e);
810
                } catch (QueryException e) {
811
                        throw new RasterDriverException("Error querying to the internal provider", e);
812
                }
813

    
814
        }
815

    
816
        private void queryToInternalTiledProvider(SpiRasterQuery parentQuery) throws TileGettingException, TileBuildException {
817
                List<Tile> tileList = getTileList(parentQuery);
818
                for (int i = 0; i < tileList.size(); i++) {
819
                        tiledLayer.getTile(tileList.get(i));
820
                }
821
                MemoryTileMatrixBuffer matrixBuffer = new MemoryTileMatrixBuffer(tileList);
822
                Buffer buf = matrixBuffer.getWindow(parentQuery.getAdjustedRequestBoundingBox(), parentQuery.getBufWidth(), parentQuery.getBufHeight(), parentQuery.getBandList().getDrawableBandsCount());
823
                parentQuery.setBufferResult(buf);
824
        }
825

    
826
        private void queryToInternalProvider(SpiRasterQuery parentQuery) throws ProcessInterruptedException, QueryException {
827
                DefaultRasterStore store = new DefaultRasterStore();
828
                store.setProvider(provider);
829

    
830
                RasterQuery query = RasterLocator.getManager().createQuery();
831
                query.setAreaOfInterest(parentQuery.getAdjustedRequestBoundingBox(), parentQuery.getBufWidth(), parentQuery.getBufHeight());
832
                int[] dBands = null;
833
                if(parentQuery.getDrawableBands() != null) {
834
                        dBands = parentQuery.getDrawableBands().clone();
835
                        if(!((AbstractRasterProvider)provider).getTransparency().existAlphaBand() && getTransparency().existAlphaBand()) {
836
                                dBands[getTransparency().getAlphaBandNumber()] = -1;
837
                        }
838
                }
839
                query.setReadOnly(((RasterQuery)parentQuery).isReadOnly());
840
                if(((RasterQuery)parentQuery).isforcingARGBRequest())
841
                        query.forceARGBRequest();
842
                if(((RasterQuery)parentQuery).isforcingRGBRequest())
843
                        query.forceRGBRequest();
844
                if(dBands == null)
845
                        query.setAllDrawableBands();
846
                else
847
                        query.setDrawableBands(dBands);
848
                query.setAdjustToExtent(true);
849
                store.query(query);
850
                parentQuery.setBufferResult(((SpiRasterQuery)query).getBufferForProviders());
851
        }
852

    
853
        public int getBlockSize() {
854
                return 0;
855
        }
856

    
857
        public void setAffineTransform(AffineTransform t){
858

    
859
        }
860

    
861
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
862
                return getZoomLevels();
863
        }
864

    
865
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
866
                return provider.getTileServer().getStruct().getLayerWidthOfTileMatrixByLevel(overview) *
867
                                provider.getTileServer().getStruct().getTileSizeByLevel(overview)[0];
868
        }
869

    
870
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
871
                return provider.getTileServer().getStruct().getLayerHeightOfTileMatrixByLevel(overview) *
872
                                provider.getTileServer().getStruct().getTileSizeByLevel(overview)[0];
873
        }
874

    
875
        public boolean isOverviewsSupported() {
876
                return false;
877
        }
878

    
879
        public String getProviderName() {
880
                return NAME;
881
        }
882

    
883
        /**
884
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
885
         * @param pt Punto a transformar
886
         * @return punto transformado en coordenadas del mundo
887
         */
888
        public Point2D rasterToWorld(Point2D pt) {
889
                Point2D p = new Point2D.Double();
890
                getAffineTransform().transform(pt, p);
891
                return p;
892
        }
893

    
894
        /**
895
         * Convierte un punto desde del mundo a coordenadas pixel.
896
         * @param pt Punto a transformar
897
         * @return punto transformado en coordenadas pixel
898
         */
899
        public Point2D worldToRaster(Point2D pt) {
900
                Point2D p = new Point2D.Double();
901
                try {
902
                        getAffineTransform().inverseTransform(pt, p);
903
                } catch (NoninvertibleTransformException e) {
904
                        return pt;
905
                }
906
                return p;
907
        }
908

    
909
        public void setStatus(RasterProvider provider) {
910
                if(provider instanceof TileProvider) {
911
                }
912
        }
913

    
914
        /**
915
         * ASigna el par?metro de inicializaci?n del driver.
916
         */
917
        @Override
918
        public void setParam(DataStoreProviderServices storeServices, DataStoreParameters param) {
919
                if(param instanceof RemoteStoreParameters)
920
                        this.uri = ((RasterDataParameters)param).getURI();
921
                this.param = param;
922
                this.storeServices = storeServices;
923
        }
924

    
925
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
926
                if(provider != null)
927
                        return provider.getInfoByPoint(x, y, cancellable);
928
                return "Not implemented";
929
        }
930

    
931
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
932
                if(provider != null)
933
                        return provider.getInfoByPoint(x, y, bbox, w, h, cancellable);
934
                return "Not implemented";
935
        }
936

    
937
        public int[] getTileSize(int level) {
938
                return provider.getTileServer().getStruct().getTileSizeByLevel(level);
939
        }
940

    
941
        public void deleteLayerFromCache() {
942
                TileCacheManager  manager = TileCacheLocator.getManager();
943
                TileCache tileCache = manager.getTileCache(RasterLibrary.pathTileCache);
944
                if(tiledLayer != null)
945
                        tileCache.removeLayer(tiledLayer);
946
        }
947

    
948
        public TileServer getTileServer() {
949
                return secondLevelTileServer;
950
        }
951

    
952
        /**
953
         * @param tileServer
954
         */
955
        public void setSecondLevelTileServer(TileServer tileServer) {
956
                this.secondLevelTileServer = tileServer;
957
        }
958

    
959
        public void setTileServer(Class<?> tileServer) throws InitializeException {
960
                //TODO:Manejar excepciones
961
                //Crear par?metros
962
                TileDataParametersImpl par = new TileDataParametersImpl();
963
                par.setDataParameters(getDataParameters());
964
                par.setSecondLevelCache(true); //No crea un nuevo provider
965

    
966
                //Crea el proveedor de tiles de segundo nivel
967
                TileProvider newProvider = null;
968
                newProvider = new TileProvider(par, null);
969
                newProvider.setProvider(this.provider);
970

    
971
                //Instancia el TileServer pasado por el cliente con el TileProvider de segundo nivel
972
                Constructor<?> constructor;
973
                TileServer tServer = null;
974
                try {
975
                        constructor = tileServer.getConstructor(new Class<?>[]{AbstractRasterProvider.class});
976
                        Object [] args2 = {newProvider};
977
                        tServer = (TileServer)constructor.newInstance(args2);
978
                } catch (SecurityException e) {
979
                        e.printStackTrace();
980
                } catch (NoSuchMethodException e) {
981
                        e.printStackTrace();
982
                } catch (IllegalArgumentException e) {
983
                        e.printStackTrace();
984
                } catch (InstantiationException e) {
985
                        e.printStackTrace();
986
                } catch (IllegalAccessException e) {
987
                        e.printStackTrace();
988
                } catch (InvocationTargetException e) {
989
                        e.printStackTrace();
990
                }
991

    
992
                //Asigna el TileServer al nuevo provider de segundo nivel
993
                newProvider.setSecondLevelTileServer(tServer);
994

    
995
                //Asigna al provider de tiles de primer nivel el de segundo.
996
                //Solo si las estructuras de cach? son diferentes
997
                if(!provider.getTileServer().getStruct().compare(tServer.getStruct())) {
998
                        this.setProvider(newProvider);
999
                        tiledLayer = null;
1000
                }
1001
        }
1002

    
1003
        /* (non-Javadoc)
1004
         * @see org.gvsig.raster.impl.provider.RasterProvider#addFile(java.io.File)
1005
         */
1006
        @Override
1007
        public void addFile(File file) throws InvalidSourceException {
1008
            // DO Nothing
1009
        }
1010

    
1011
        /* (non-Javadoc)
1012
         * @see org.gvsig.raster.impl.provider.RasterProvider#removeFile(java.io.File)
1013
         */
1014
        @Override
1015
        public void removeFile(File file) {
1016
            // DO nothing
1017
        }
1018

    
1019
        @Override
1020
        public String getFullName() {
1021
        return provider.getFullName();
1022
    }
1023

    
1024
}