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

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.registerStoreProviderFactory(new TileProviderFactory(NAME, DESCRIPTION));
110
                }
111

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

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

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

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

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

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

    
170
                        return (RasterProvider)prov;
171
                }
172

    
173
                return null;
174
        }
175

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

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

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

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

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

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

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

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

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

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

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

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

    
246
        }
247

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

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

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

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

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

    
344
                createTiledLayer();
345

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

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

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

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

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

    
412
                super.setColorInterpretation(ci);
413
        }
414

    
415

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
765
                loadTileTimeParameters(tile);
766

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

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

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

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

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

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

    
813
        }
814

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

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

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

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

    
856
        public void setAffineTransform(AffineTransform t){
857

    
858
        }
859

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1023
}