Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / provider / AbstractRasterProvider.java @ 2888

History | View | Annotate | Download (37.7 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.impl.provider;
23

    
24
import java.awt.Image;
25
import java.awt.geom.AffineTransform;
26
import java.awt.geom.NoninvertibleTransformException;
27
import java.awt.geom.Point2D;
28
import java.io.File;
29
import java.net.URI;
30
import java.net.URISyntaxException;
31
import java.security.NoSuchAlgorithmException;
32
import java.util.Collection;
33
import java.util.Date;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.logging.Level;
37
import org.apache.commons.io.FilenameUtils;
38

    
39
import org.cresques.cts.IProjection;
40
import org.gvsig.compat.net.ICancellable;
41
import org.gvsig.fmap.dal.DALLocator;
42
import org.gvsig.fmap.dal.DataServerExplorer;
43
import org.gvsig.fmap.dal.DataStoreParameters;
44
import org.gvsig.fmap.dal.coverage.RasterLibrary;
45
import org.gvsig.fmap.dal.coverage.RasterLocator;
46
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
47
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
48
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
49
import org.gvsig.fmap.dal.coverage.datastruct.GeoPointList;
50
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
51
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
52
import org.gvsig.fmap.dal.coverage.exception.BandNotFoundInListException;
53
import org.gvsig.fmap.dal.coverage.exception.CloneException;
54
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
55
import org.gvsig.fmap.dal.coverage.exception.InfoByPointException;
56
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
57
import org.gvsig.fmap.dal.coverage.exception.InvalidSourceException;
58
import org.gvsig.fmap.dal.coverage.exception.ParsingException;
59
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
60
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
61
import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException;
62
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
63
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
64
import org.gvsig.fmap.dal.coverage.store.parameter.RasterDataParameters;
65
import org.gvsig.fmap.dal.coverage.store.parameter.RasterFileStoreParameters;
66
import org.gvsig.fmap.dal.coverage.store.parameter.RemoteStoreParameters;
67
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
68
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
69
import org.gvsig.fmap.dal.coverage.store.props.HistogramComputer;
70
import org.gvsig.fmap.dal.coverage.store.props.Metadata;
71
import org.gvsig.fmap.dal.coverage.store.props.Statistics;
72
import org.gvsig.fmap.dal.coverage.store.props.TimeSeries;
73
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
74
import org.gvsig.fmap.dal.coverage.util.FileUtils;
75
import org.gvsig.fmap.dal.coverage.util.RasterUtils;
76
import org.gvsig.fmap.dal.exception.InitializeException;
77
import org.gvsig.fmap.dal.exception.OpenException;
78
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
79
import org.gvsig.fmap.dal.exception.ReadException;
80
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
81
import org.gvsig.fmap.dal.raster.spi.AbstractCoverageStoreProvider;
82
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
83
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
84
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
85
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
86
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
87
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
88
import org.gvsig.raster.cache.tile.provider.TileServer;
89
import org.gvsig.raster.impl.buffer.SpiRasterQuery;
90
import org.gvsig.raster.impl.datastruct.BandListImpl;
91
import org.gvsig.raster.impl.datastruct.DatasetBandImpl;
92
import org.gvsig.raster.impl.datastruct.DefaultNoData;
93
import org.gvsig.raster.impl.datastruct.ExtentImpl;
94
import org.gvsig.raster.impl.datastruct.serializer.ColorTableRmfSerializer;
95
import org.gvsig.raster.impl.datastruct.serializer.NoDataRmfSerializer;
96
import org.gvsig.raster.impl.store.AbstractRasterDataParameters;
97
import org.gvsig.raster.impl.store.DefaultRasterStore;
98
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
99
import org.gvsig.raster.impl.store.properties.SimpleProviderHistogramComputer;
100
import org.gvsig.raster.impl.store.properties.SimpleProviderStatistics;
101
import org.gvsig.raster.impl.store.rmf.ClassSerializer;
102
import org.gvsig.raster.impl.store.rmf.RmfBlocksManager;
103
import org.gvsig.raster.impl.store.serializer.ColorInterpretationRmfSerializer;
104
import org.gvsig.raster.impl.store.serializer.GeoInfoRmfSerializer;
105
import org.gvsig.raster.impl.store.serializer.GeoPointListRmfSerializer;
106
import org.gvsig.raster.impl.store.serializer.ProjectionRmfSerializer;
107
import org.gvsig.raster.impl.store.serializer.StatisticsRmfSerializer;
108
import org.gvsig.raster.util.DefaultProviderServices;
109
import org.gvsig.timesupport.Interval;
110
import org.gvsig.timesupport.Time;
111
import org.gvsig.tools.dynobject.DynObject;
112
import org.gvsig.tools.locator.LocatorException;
113
import org.slf4j.Logger;
114
import org.slf4j.LoggerFactory;
115

    
116
/**
117
 * Base class for all raster providers. 
118
 * @author Nacho Brodin (nachobrodin@gmail.com)
119
 */
120
public abstract class AbstractRasterProvider extends AbstractCoverageStoreProvider implements RasterProvider {
121
        /**
122
         * Flags que representan a las bandas visualizables
123
         */
124
        public static final int                   RED_BAND               = 0x01;
125
        public static final int                   GREEN_BAND             = 0x02;
126
        public static final int                   BLUE_BAND              = 0x04;
127
        public static final int                   ALPHA_BAND             = 0x08;
128
        
129
        protected int                             bandCount              = 1;
130
        private int[]                             dataType               = null;
131
        protected NoData                          noData                 = null;
132

    
133
        protected Statistics                      stats                  = null;
134
        protected HistogramComputer               histogram              = null;
135
        protected DataStoreParameters             param                  = null;
136
        protected DataStoreProviderServices       storeServices          = null;
137
        protected RmfBlocksManager                rmfBlocksManager       = null;
138
        protected ColorTable                      colorTable             = null;
139
        private ColorInterpretation               colorInterpretation    = null;
140
        protected TimeSeries                      serialInfo             = null;
141
        protected Transparency                    transparency           = null;
142
        protected TileServer                      tileServer             = null;
143
        protected GeoPointList                    geoPointList           = null;
144
        
145
        protected FileUtils                       fileUtil               = RasterLocator.getManager().getFileUtils();
146
        protected RasterUtils                     rasterUtil             = RasterLocator.getManager().getRasterUtils();
147
        
148
        protected IProjection                     proj                   = null;
149
        protected long                            fileSize               = 0;
150
        protected long                            bytesReaded            = 0;
151
        protected long                            lineCnt                = 0;
152
        protected String                          uri;
153
        protected String                          selectedSubdatasetID   = null;
154
        /**
155
         * Transformaci?n creada a partir de la informaci?n de georreferencia de la
156
         * propia imagen. Esta informaci?n est? en la cabecera o en ficheros
157
         * worldfile.
158
         */
159
        protected AffineTransform                 ownTransformation      = null;
160
        /**
161
         * Transformaci?n asignada de forma externa, bien desde el fichero rmf o
162
         * asignada directamente por el usuario.
163
         */
164
        protected AffineTransform                 externalTransformation = null;
165
        private static Logger                     logger                 = LoggerFactory.getLogger(AbstractRasterProvider.class.getName());
166
        
167
        public AbstractRasterProvider(AbstractRasterDataParameters params,
168
                        DataStoreProviderServices storeServices, DynObject metadata) {
169
                super(params, storeServices, metadata);
170
                if(params.getURI() != null) {
171
                        File f = new File(params.getURI());
172
                        if(f.exists())
173
                                setFileSize(f.length());
174
                }
175
                
176
                if(params.getURI() != null)
177
                        uri = translateFileName(params.getURI());
178
                
179
                ownTransformation = new AffineTransform();
180
                externalTransformation = new AffineTransform();
181
        }
182
        
183
        public AbstractRasterProvider(DataStoreParameters params,
184
                        DataStoreProviderServices storeServices, DynObject metadata) {
185
                super(params, storeServices, metadata);
186
                if(((RasterDataParameters)params).getURI() != null) {
187
                        File f = new File(((RasterDataParameters)params).getURI());
188
                        if(f.exists())
189
                                setFileSize(f.length());
190
                        if(params instanceof RemoteStoreParameters)
191
                                uri = translateFileName(((RasterDataParameters)params).getURI());
192
                }
193
                
194
                ownTransformation = new AffineTransform();
195
                externalTransformation = new AffineTransform();
196
        }
197
        
198
        public AbstractRasterProvider(String params) {
199
                super();
200
        }
201
        
202
        public AbstractRasterProvider() {
203
                super(null, null, null);
204
        }
205
        
206
        public String[] getFormatList() {
207
                return null;
208
        }
209
        
210
        /**
211
         * Acciones de inicilizaci?n comunes a todos los drivers.
212
         * Este m?todo debe ser llamado explicitamente por el constructor de cada driver.
213
         * Estas son acciones de inicializaci?n que se ejecutan despu?s del constructor de cada driver.
214
         * Las acciones que hayan de ser realizadas antes se definen en el constructor de RasterDataset.
215
         */
216
        protected void init() {
217
        }
218
        
219
        public boolean isRGB() {
220
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
221
                        ColorInterpretation ci = getColorInterpretation();
222
                        return ci.isRGB();
223
                }
224
                return false;
225
        }
226
        
227
        public boolean isARGB() {
228
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
229
                        ColorInterpretation ci = getColorInterpretation();
230
                        return ci.isRGBA();
231
                }
232
                return false;
233
        }
234
        
235
        public boolean isTiled() {
236
                return false;
237
        }
238
        
239
        public boolean isTimeSupported() {
240
                return false;
241
        }
242
        
243
        public RasterProvider cloneProvider() throws CloneException {
244
                try {
245
                        DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
246
                        AbstractRasterProvider provider = (AbstractRasterProvider)dataManager.createProvider(storeServices, param);
247
                        //DefaultRasterProvider provider = singleDatasetInstance(storeServices, param);
248
                        // Estas van por referencia
249
                        provider.histogram = histogram;
250
                        provider.stats = stats;
251
                        return provider;
252
                } catch (ProviderNotRegisteredException e) {
253
                        e.printStackTrace();
254
                } catch (InitializeException e) {
255
                        e.printStackTrace();
256
                }
257
                return null;
258
        }
259
        
260
        /**
261
         * Factoria para abrir distintos tipos de raster.
262
         * @param fName Nombre del fichero.
263
         *
264
         * @return SingleDataset, o null si hay problemas.
265
         */
266
        @SuppressWarnings("unchecked")
267
        public static AbstractRasterProvider singleDatasetInstance(DataStoreProviderServices storeServices, String param) throws RasterDriverException {
268
                DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
269
                //We have to locate a provider's name which manages the selected file
270
                //A FilesystemServerExplorer will give a getProviderNames service
271
                
272
                FilesystemServerExplorer serverExplorer = null;
273
                try {
274
                        FilesystemServerExplorerParameters paramsExplorer = (FilesystemServerExplorerParameters)dataManager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
275
                        paramsExplorer.setRoot(File.separator);
276
                        serverExplorer = (FilesystemServerExplorer)dataManager.openServerExplorer(FilesystemServerExplorer.NAME, paramsExplorer);
277
                } catch (ValidateDataParametersException e) {
278
                        throw new RasterDriverException("Error validating parameters", e);
279
                } catch (InitializeException e) {
280
                        throw new RasterDriverException("Error creating a server explorer ", e);
281
                } catch (ProviderNotRegisteredException e) {
282
                        throw new RasterDriverException("Provider not registered", e);
283
                }
284
                
285
                //Gets the list of provider's name to manage the file
286
                File file = new File(param);
287
                List<String> provName = serverExplorer.getProviderNameList(file);
288
                if(provName.size() > 0) {
289
                        for (int i = 0; i < provName.size(); i++) {
290
                                //Gets the first provider what is not a TileProvider
291
                                if(provName.get(i).compareTo("Tile Store") != 0) {
292
                                        DataStoreParameters newparams;
293
                                        try {
294
                                                newparams = dataManager.createStoreParameters(provName.get(i));
295
                                                ((FilesystemStoreParameters)newparams).setFile(file); 
296
                                                if(storeServices == null)
297
                                                        storeServices = new DefaultRasterStore();
298
                                                return (AbstractRasterProvider)dataManager.createProvider(storeServices, newparams);
299
                                        } catch (InitializeException e) {
300
                                                throw new RasterDriverException("Error creating a server explorer ", e);
301
                                        } catch (ProviderNotRegisteredException e) {
302
                                                throw new RasterDriverException("Provider not registered", e);
303
                                        }
304
                                }
305
                        }
306
                }
307
                return null;
308
        }
309

    
310
        /**
311
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar
312
         * un objeto de este tipo.
313
         */
314
        abstract public RasterProvider load();
315

    
316
        /**
317
         * Obtiene el ancho de la imagen
318
         * @return Ancho de la imagen
319
         */
320
        abstract public double getWidth();
321

    
322
        /**
323
         * Obtiene el ancho de la imagen
324
         * @return Ancho de la imagen
325
         */
326
        abstract public double getHeight();
327

    
328
        /**
329
         * Asigna un nuevo Extent
330
         * @param e        Extent
331
         */
332
        public abstract void setView(Extent e);
333

    
334
        /**
335
         * Obtiene el extent asignado
336
         * @return        Extent
337
         */
338
        public abstract Extent getView();
339

    
340
        /**
341
         * Obtiene el valor del raster en la coordenada que se le pasa.
342
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
343
         * raster.
344
         * @param x        coordenada X
345
         * @param y coordenada Y
346
         * @return
347
         */
348
        abstract public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
349

    
350
        /**
351
         * Gets the set of data selected in the {@link RasterQuery}
352
         * @param q
353
         * @return
354
         * @throws RasterDriverException 
355
         * @throws ProcessInterruptedException 
356
         */
357
        public Buffer getDataSet(SpiRasterQuery query) throws ProcessInterruptedException, RasterDriverException {
358
                SpiRasterQuery q = (SpiRasterQuery)query;
359
                loadBuffer(q);
360
                return q.getBufferForProviders();
361
        }
362
        
363
        /**
364
         * Load a buffer with the parameters. The buffer should already have been created 
365
         * inside the query structure <code>SpiRasterQuery</code> by the <code>RasterDataStore</code>. The other
366
         * parameters have been calculated too, all of them adjusted to the raster limits. The provider only 
367
         * have to read the parameters and load the buffer.
368
         * 
369
         * @param query
370
         * @throws ProcessInterruptedException
371
         * @throws RasterDriverException
372
         */
373
        abstract public void loadBuffer(SpiRasterQuery query) throws ProcessInterruptedException, RasterDriverException;
374

    
375
        abstract public int getBlockSize();
376
        
377
        abstract public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException;
378

    
379
        /**
380
         * Informa de si el dataset soporta overviews o no.
381
         * @return true si soporta overviews y false si no las soporta.
382
         */
383
        abstract public boolean isOverviewsSupported();
384
        
385
        public void reload() {
386
                try {
387
                        loadFromRmf(getRmfBlocksManager());
388
                } catch (ParsingException e) {
389
                        logger.debug("No se ha podido leer el RMF", e);
390
                }
391
        }
392
        
393
        /**
394
         * Carga metadatos desde el fichero Rmf si estos existen
395
         * @param fName Nombre del fichero
396
         * @throws ParsingException
397
         */
398
        protected void loadFromRmf(RmfBlocksManager manager) throws ParsingException {
399
                if (!manager.checkRmf())
400
                        return;
401

    
402
                if (!new File(manager.getPath()).exists())
403
                        return;
404
                
405
                GeoInfoRmfSerializer geoInfoSerializer = new GeoInfoRmfSerializer(this);
406
                ColorTableRmfSerializer colorTableSerializer = new ColorTableRmfSerializer();
407
                GeoPointListRmfSerializer gcpSerializer = new GeoPointListRmfSerializer();
408
                NoDataRmfSerializer noDataSerializer = null;
409
                if(noData == null)
410
                        noData = new DefaultNoData(null, null, manager.getPath(), getBandCount());
411
                noDataSerializer = new NoDataRmfSerializer((DefaultNoData)noData);                        
412
                ColorInterpretationRmfSerializer colorInterpSerializer = new ColorInterpretationRmfSerializer();
413
                ProjectionRmfSerializer projectionRmfSerializer = new ProjectionRmfSerializer();
414
                StatisticsRmfSerializer statsRmfSerializer = new StatisticsRmfSerializer(getStatistics());
415

    
416
                manager.addClient(geoInfoSerializer);
417
                manager.addClient(colorTableSerializer);
418
                manager.addClient(gcpSerializer);
419
                manager.addClient(noDataSerializer);
420
                manager.addClient(colorInterpSerializer);
421
                manager.addClient(projectionRmfSerializer);
422
                manager.addClient(statsRmfSerializer);
423

    
424
                manager.read(null);
425

    
426
                manager.removeAllClients();
427

    
428
                if (colorTableSerializer.getResult() != null)
429
                        setColorTable((ColorTable) colorTableSerializer.getResult());
430

    
431
                if (colorInterpSerializer.getResult() != null) {
432
                        DataStoreColorInterpretation ci = (DataStoreColorInterpretation) colorInterpSerializer.getResult();
433
                        setColorInterpretation(ci);
434
                        getTransparency().setColorInterpretation(ci);
435
                        getTransparency().setTransparencyBand(ci.getBand(DataStoreColorInterpretation.ALPHA_BAND));
436
                }
437

    
438
                if (projectionRmfSerializer.getResult() != null) {
439
                        proj = (IProjection) projectionRmfSerializer.getResult();
440
                }
441
                
442
                if( gcpSerializer.getResult() != null && 
443
                        gcpSerializer.getResult() instanceof GeoPointList && 
444
                        ((GeoPointList)gcpSerializer.getResult()).size() > 0) {
445
                        setGeoPointList((GeoPointList)gcpSerializer.getResult());
446
                }
447
        }
448

    
449
        /**
450
         * Obtiene el n?nero de bandas del fichero
451
         * @return Entero que representa el n?mero de bandas
452
         */
453
        public int getBandCount() {
454
                return bandCount;
455
        }
456

    
457
        /**
458
         * @return Returns the dataType.
459
         */
460
        public int[] getDataType() {
461
                return dataType;
462
        }
463

    
464
        /**
465
         * @param dataType The dataType to set.
466
         */
467
        public void setDataType(int[] dataType) {
468
                this.dataType = dataType;
469
        }
470

    
471
        public double getPixelSizeX() {
472
                return externalTransformation.getScaleX();
473
        }
474

    
475
        public double getPixelSizeY() {
476
                return externalTransformation.getScaleY();
477
        }
478

    
479
        public NoData getNoDataValue() {
480
                if(noData == null) {
481
                        noData = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(getBandCount(), getDataType()[0]);
482
                        noData.setNoDataTransparent(false);
483
                        noData.setFileName(getRMFFile());
484
                }
485
                return noData;
486
        }
487
        
488
        public void setNoDataValue(NoData value) {
489
                this.noData = value;
490
        }
491

    
492
        /**
493
         * Dice si el fichero tiene georreferenciaci?n o no.
494
         * @return true si tiene georreferenciaci?n y false si no la tiene
495
         */
496
        public boolean isGeoreferenced() {
497
                return true;
498
        }
499

    
500
        /**
501
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
502
         * @param pt Punto a transformar
503
         * @return punto transformado en coordenadas del mundo
504
         */
505
        public Point2D rasterToWorld(Point2D pt) {
506
                Point2D p = new Point2D.Double();
507
                externalTransformation.transform(pt, p);
508
                return p;
509
        }
510

    
511
        /**
512
         * Convierte un punto desde del mundo a coordenadas pixel.
513
         * @param pt Punto a transformar
514
         * @return punto transformado en coordenadas pixel
515
         */
516
        public Point2D worldToRaster(Point2D pt) {
517
                Point2D p = new Point2D.Double();
518
                try {
519
                        externalTransformation.inverseTransform(pt, p);
520
                } catch (NoninvertibleTransformException e) {
521
                        return pt;
522
                }
523
                return p;
524
        }
525

    
526
        /**
527
         * Calcula el extent en coordenadas del mundo real
528
         * @return Extent
529
         */
530
        public Extent getExtent() {
531
                return new ExtentImpl(        rasterToWorld(new Point2D.Double(0, 0)),
532
                                                        rasterToWorld(new Point2D.Double(getWidth(), getHeight())),
533
                                                        rasterToWorld(new Point2D.Double(getWidth(), 0)),
534
                                                        rasterToWorld(new Point2D.Double(0, getHeight())));
535
        }
536

    
537
        /**
538
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
539
         * @return Extent
540
         */
541
        public Extent getExtentWithoutRot() {
542
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0,
543
                                                                                                        0, externalTransformation.getScaleY(),
544
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
545
                Point2D p1 = new Point2D.Double(0, 0);
546
                Point2D p2 = new Point2D.Double(getWidth(), getHeight());
547
                at.transform(p1, p1);
548
                at.transform(p2, p2);
549
                return new ExtentImpl(p1, p2);
550
        }
551

    
552
        /**
553
         * ASigna el par?metro de inicializaci?n del driver.
554
         */
555
        public void setParam(DataStoreProviderServices provServices, DataStoreParameters param) {
556
                if(param instanceof RasterDataParameters)
557
                        this.uri = ((RasterDataParameters)param).getURI();
558
                this.param = param;
559
                this.storeServices = provServices;
560
        }
561

    
562
        abstract public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException;
563
        
564
        public void selectSubdataset() {}
565
        
566
        /**
567
         * Selects the subdataset. This method will select
568
         * the rmf file. 
569
         */
570
        protected void selectSubdataset(String subdataset) {
571
                selectedSubdatasetID = subdataset;
572
                getRmfBlocksManager().setPath(getRMFFile());
573
        }
574

    
575
        /**
576
         * Obtiene el gestor de ficheros RMF
577
         * @return RmfBloksManager
578
         */
579
        public RmfBlocksManager getRmfBlocksManager() {
580
                String fileRMF = getRMFFile();
581
                if(fileRMF != null) {
582
                        if (rmfBlocksManager == null || fileRMF.compareTo(rmfBlocksManager.getPath()) != 0) {
583
                                rmfBlocksManager = new RmfBlocksManager(fileRMF);
584
                        }
585
                }
586
                return rmfBlocksManager;
587
        }
588
        
589
        public String getRMFFile() {
590
                String tail = selectedSubdatasetID == null ? ".rmf" : "-sd" + selectedSubdatasetID + ".rmf";
591
                File rmfFolder = (getDataParameters() != null && getDataParameters() instanceof RasterDataParameters) ? 
592
                                                ((RasterDataParameters)getDataParameters()).getRMFFolder() : 
593
                                                null;
594
                        
595
                String fileName = getURI();
596
                if(fileName.contains(File.separator)) {
597
                        if(!fileName.endsWith(File.separator)) {
598
                                fileName = fileName.substring(fileName.lastIndexOf(File.separator) + 1);
599
                                fileName = fileUtil.getNameWithoutExtension(fileName);
600
                        }
601
                }
602
                
603
                if(rmfFolder == null) {
604
                        if(getURI().contains(File.separator)) {
605
                                if(!getURI().endsWith(File.separator)) {
606
                                        String folder = getURI().substring(0, getURI().lastIndexOf(fileName));
607
                                        if((getDataParameters() != null && getDataParameters() instanceof RasterDataParameters))
608
                                                ((RasterDataParameters)getDataParameters()).setRMFFolder(new File(folder));
609
                                }
610
                        }
611
                        return fileUtil.getNameWithoutExtension(getURI()) + tail;
612
                } else {
613
                        return rmfFolder.getAbsolutePath() + File.separator + fileName + tail;
614
                }
615
                
616
        }
617
        
618
        protected String getRMFFileForRemoteServices(String layerName) {
619
                String md5 = "";
620
                try {
621
                        md5 = RasterLocator.getManager().getFileUtils().convertPathToMD5(uri);
622
                } catch (LocatorException e) {
623
                        logger.debug("Error getting the Locator", e);
624
                } catch (NoSuchAlgorithmException e) {
625
                        logger.debug("Error getting the algorithm MD5", e);
626
                }
627
                File path = new File(RasterLibrary.pathRMFRemote);
628
                if(!path.exists())
629
                        path.mkdir();
630
                return RasterLibrary.pathRMFRemote + File.separator + md5 + "-" + layerName + ".rmf";
631
        }
632

    
633
        public boolean isInside(Point2D p){
634
                //Realizamos los calculos solo si el punto est? dentro del extent de la imagen rotada, as? nos ahorramos los calculos
635
                //cuando el puntero est? fuera
636

    
637
                Point2D pt = new Point2D.Double();
638
                try {
639

    
640
                        getAffineTransform().inverseTransform(p, pt);
641
                        if(        pt.getX() >= 0 && pt.getX() < getWidth() &&
642
                                        pt.getY() >= 0 && pt.getY() < getHeight())
643
                                return true;
644
                } catch (NoninvertibleTransformException e) {
645
                        return false;
646
                }
647

    
648
                return false;
649
        }
650

    
651
        /**
652
         * Consulta de si un raster tiene rotaci?n o no.
653
         * @return true si tiene rotaci?n y false si no la tiene.
654
         */
655
        public boolean isRotated() {
656
                if(externalTransformation.getShearX() != 0 || externalTransformation.getShearY() != 0)
657
                        return true;
658
                return false;
659
        }
660
        
661
        public boolean isMultiFile() {
662
                return false;
663
        }
664
        
665
        public boolean isMosaic() {
666
                return false;
667
        }
668

    
669
        /**
670
         * Devuelve si el Dataset es reproyectable
671
         * @return
672
         */
673
        public boolean isReproyectable() {
674
                return true;
675
        }
676

    
677
        public String getWktProjection() {
678
                if(proj != null && RasterLocator.getManager().isCRSUtilSupported())
679
                        return RasterLocator.getManager().getCRSUtils().convertIProjectionToWkt((IProjection) proj);
680
                return null;
681
        }
682

    
683
        public void saveObjectToRmf(Class<?> class1, Object value) throws RmfSerializerException {
684
                ((DefaultProviderServices)RasterLocator.getManager().getProviderServices()).saveObjectToRmfFile(getRmfBlocksManager(), class1, value);
685
        }
686

    
687
        /**
688
         * Carga un objecto desde un serializador del tipo class1. Usa value para iniciar dicho
689
         * serializador
690
         *
691
         * @param class1
692
         * @param value
693
         * @return
694
         * @throws RmfSerializerException
695
         */
696
        private static Object loadObjectFromRmfFile(RmfBlocksManager blocksManager, Class<?> class1, Object value) throws RmfSerializerException {
697
                ClassSerializer serializerObject = ((DefaultProviderServices)RasterLocator.getManager().getProviderServices()).getSerializerObject(class1, value);
698

    
699
                if (serializerObject == null)
700
                        throw new RmfSerializerException("No se ha podido encontrar el serializador para el Rmf");
701

    
702
                if (!blocksManager.checkRmf())
703
                        throw new RmfSerializerException("Error al comprobar el fichero Rmf");
704

    
705
                blocksManager.addClient(serializerObject);
706
                try {
707
                        blocksManager.read(null);
708
                } catch (ParsingException e) {
709
                        throw new RmfSerializerException("Error al leer el fichero Rmf", e);
710
                }
711
                blocksManager.removeAllClients();
712

    
713
                return serializerObject.getResult();
714
        }
715

    
716
        public Object loadObjectFromRmf(Class<?> class1, Object value) throws RmfSerializerException {
717
                return loadObjectFromRmfFile(getRmfBlocksManager(), class1, value);
718
        }
719

    
720
        /**
721
         * Carga un objeto del fichero RMF especificado por parametro
722
         * @param file
723
         * @param class1
724
         * @param value
725
         * @return
726
         * @throws RmfSerializerException
727
         */
728
        public static Object loadObjectFromRmfFile(String file, Class<?> class1, Object value) throws RmfSerializerException {
729
                String fileRMF = RasterLocator.getManager().getFileUtils().getNameWithoutExtension(file) + ".rmf";
730
                RmfBlocksManager blocksManager = new RmfBlocksManager(fileRMF);
731
                return loadObjectFromRmfFile(blocksManager, class1, value);
732
        }
733

    
734
        /**
735
         * Guarda en el RMF el objecto actual en caso de que exista un serializador para el
736
         * @param value
737
         * @throws RmfSerializerException
738
         */
739
        public void saveObjectToRmf(Object value) throws RmfSerializerException {
740
                saveObjectToRmf(value.getClass(), value);
741
        }
742

    
743
        /**
744
         * Carga un objecto desde un serializador usando el tipo del mismo objeto pasado por parametro.
745
         * Usa value para iniciar dicho serializador
746
         * @param value
747
         * @return
748
         * @throws RmfSerializerException
749
         */
750
        public Object loadObjectFromRmf(Object value) throws RmfSerializerException {
751
                return loadObjectFromRmf(value.getClass(), value);
752
        }
753
        
754

    
755
        public double getCellSize() {
756
                try {
757
                        Extent e = getExtent();
758
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getWidth();
759
                        return dCellsize;
760
                } catch (NullPointerException e) {
761
                        return 1;
762
                }
763
        }
764
        
765
        
766
        public RasterProvider newProvider() {
767
                return null;
768
        }
769
        
770
        public ColorTable getColorTable() {
771
                return colorTable;
772
        }
773
        
774
        public Image getImageLegend() {
775
                return null;
776
        }
777
        
778
        public void setColorTable(ColorTable value) {
779
                colorTable = value;
780
        }
781

    
782
        public Transparency getTransparency() {
783
                return transparency;
784
        }
785
        
786
        public Metadata getMetadata() {
787
                return null;
788
        }
789
        
790
        public ColorInterpretation getColorInterpretation() {
791
                return this.colorInterpretation;
792
        }
793

    
794
        /**
795
         * Asigna el objeto que contiene que contiene la interpretaci?n de
796
         * color por banda
797
         * @param DataStoreColorInterpretation
798
         */
799
        public void setColorInterpretation(ColorInterpretation colorInterpretation) {
800
                this.colorInterpretation = colorInterpretation;
801
        }
802
        
803
        public Statistics getStatistics() {
804
                if(stats == null) {
805
                        stats = new SimpleProviderStatistics(this);
806
                }
807
                return stats;
808
        }
809
        
810
        public void setStatistics(Statistics stats) throws RmfSerializerException {
811
                this.stats = stats;
812
                saveObjectToRmf(Statistics.class, stats);
813
        }
814
        
815
        public HistogramComputer getHistogramComputer() {
816
                if (histogram == null)
817
                        histogram = new SimpleProviderHistogramComputer(this);
818
                return histogram;
819
        }
820
        
821
    //****************************************************
822
        //*********Implementing Disposable methods************
823
        //****************************************************
824
    
825
    public void doDispose() {
826
            
827
    }
828
    
829
    //****************************************************
830
        //*****Implementing DataStoreProvider methods*********
831
        //****************************************************
832
    
833
        @Override
834
        public DataServerExplorer getExplorer() throws ReadException,
835
                        ValidateDataParametersException {
836
            /*DataManager manager = DALLocator.getDataManager();
837
                FilesystemServerExplorerParameters params;
838
                try {
839
                        params = (FilesystemServerExplorerParameters) manager
840
                                        .createServerExplorerParameters(FilesystemServerExplorer.NAME);
841
                        params.setRoot(((AbstractRasterStoreParameters)this.getDataParameters()).getFile().getParent());
842
                        return manager.createServerExplorer(params);
843
                } catch (DataException e) {
844
                        throw new ReadException(this.getName(), e);
845
                }*/
846
            return null;
847
        }
848
  
849
        
850
        /**
851
         * Returs the DataParameters
852
         * @return
853
         */
854
        public RasterDataParameters getDataParameters() {
855
                if(getDataStoreParameters() instanceof RasterDataParameters)
856
                        return (RasterDataParameters)getDataStoreParameters();
857
                return null;
858
        }
859

    
860
        public Iterator<?> getChilds() {
861
                return null;
862
        }
863

    
864
        public ResourceProvider getResource() {
865
                return null;
866
        }
867

    
868
        public Object getSourceId() {
869
                if( this.getDataParameters() instanceof RasterFileStoreParameters)
870
                        return ((RasterFileStoreParameters)this.getDataParameters()).getFile();
871
                else
872
                        return this.getDataParameters().getURI();
873
        }
874

    
875
        public void open() throws OpenException {
876
        }
877
        
878
        /**
879
         * Traduce el nombre del fichero por un alias asignado por el propio driver.
880
         * Cuando es traducido por un alias el driver intentar? abrir el alias y no el
881
         * fichero. Esto es util porque algunos formatos tienen la extensi?n en el
882
         * fichero de cabecera pero lo que se abre realmente es el fichero de datos.
883
         * @param fileName
884
         * @return
885
         */
886
        public String translateFileName(String fileName) {
887
                return fileName;
888
        }
889
        
890
        public String getFileSuffix() {
891
                return getURIOfFirstProvider().substring(getURIOfFirstProvider().lastIndexOf(".") + 1, getURIOfFirstProvider().length());
892
        }
893

    
894
        public String getURIOfFirstProvider() {
895
                return RasterLocator.getManager().getFileUtils().getFormatedRasterFileName(uri);
896
        }
897

    
898
        public String getURI() {
899
                return uri;
900
        }
901
        
902
        public void setFName(String n) {
903
                uri = n;
904
        }
905

    
906
        public String getName() {
907
            String pathName = null;
908
            try {
909
                URI x = new URI(this.uri);
910
                pathName = x.getPath();
911
                return FilenameUtils.getBaseName(pathName);
912
            } catch (Throwable th1) {
913
                try {
914
                    return FilenameUtils.getBaseName(pathName);
915
                } catch(Throwable th2) {
916
                    return uri;
917
                }
918
            }
919
        }
920
        
921
        public String getFullName() {
922
                return uri;
923
        }
924
        
925
        /**
926
         * Gets the size of the file if exists in Bytes
927
         * @return
928
         */
929
        public long getFileSize() {
930
                return fileSize;
931
        }
932

    
933
        public void setFileSize(long sz) {
934
                fileSize = sz;
935
        }
936

    
937
        public IProjection getProjection() {
938
                return proj;
939
        }
940

    
941
        public void setProjection(IProjection proj, boolean persist) throws RmfSerializerException {
942
                this.proj = proj;
943
                if(persist)
944
                        saveObjectToRmf(IProjection.class, proj);
945
        }
946

    
947
        protected long getTime() {
948
                return (new Date()).getTime();
949
        }
950

    
951
        public void setAffineTransform(AffineTransform t) {
952
                externalTransformation = (AffineTransform) t.clone();
953
        }
954

    
955
        public AffineTransform getAffineTransform() {
956
                return externalTransformation;
957
        }
958

    
959
        /**
960
         * Elimina la matriz de transformaci?n asociada al raster y que se tiene en
961
         * cuenta para el setView. Este reseteo tendr? en cuenta que si el raster
962
         * tiene asociado un rmf esta transformaci?n no ser? eliminada sino que se
963
         * asignar? la correspondiente al rmf existente.
964
         * @return devuelve true si tiene fichero rmf asociado y false si no lo tiene.
965
         */
966
        public void resetAffineTransform() {
967
                externalTransformation.setToIdentity();
968
        }
969

    
970
        public AffineTransform getOwnAffineTransform() {
971
                return ownTransformation;
972
        }
973

    
974
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
975
                return null;
976
        }
977
        
978
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
979
                return null;
980
        }
981
        
982
        public void setTileServer(Class<?> tileServer) throws InitializeException {
983
                
984
        }
985
        
986
        public int[] getTileSize(int level) {
987
                return new int[]{0, 0};
988
        }
989
        
990
        public boolean isRasterEnclosed() {
991
                return false;
992
        }
993
        
994
        public int getSourceType() {
995
                if(getURI().startsWith("PG:host"))
996
                        return RasterDataStore.POSTGIS;
997
                if(getURI().startsWith("http:") || getURI().startsWith("https:"))
998
                        return RasterDataStore.REMOTE;
999
                return RasterDataStore.FILE;
1000
        }
1001
        
1002
        /**
1003
         * Most of providers don't need tiles. It those cases this method
1004
         * won't execute anything. Only providers that use tile cache will need
1005
         * implement this function, for instance TileProvider and MosaicProvider.
1006
         */
1007
        public void deleteLayerFromCache() {
1008
                
1009
        }
1010
        
1011
        public TimeSeries getTimeSerials() throws RmfSerializerException {
1012
                if(serialInfo == null) {
1013
                        serialInfo =  new DefaultTimeSerials();
1014
                        loadObjectFromRmf(TimeSeries.class, serialInfo);
1015
                        //Seleccionamos la primera serie por defecto. El usuario seleccionar? otra si la necesita
1016
                        serialInfo.selectSerial(0);
1017
                }
1018
                return serialInfo;
1019
        }
1020
        
1021
        public void setTimeSerials(TimeSeries serialInfo) throws RmfSerializerException {
1022
                this.serialInfo = serialInfo;
1023
                saveObjectToRmf(TimeSeries.class, serialInfo);
1024
        }
1025
        
1026
        public long[] getFileSizeByProvider() {
1027
                return new long[]{getFileSize()};
1028
        }
1029
        
1030
        public String[] getURIByProvider() {
1031
                //For providers with one file
1032
                return new String[]{getURIOfFirstProvider()};
1033
        }
1034
        
1035
        public int[] getBandCountByProvider() {
1036
                return new int[]{getBandCount()};
1037
        }
1038
        
1039
        public int getInternalProviderCount() {
1040
                return 1;
1041
        }
1042
        
1043
        public RasterProvider getInternalProvider(int i) {
1044
                return this;
1045
        }
1046
        
1047
        public String getURIByBand(int band) {
1048
                //No matter which band be selected. In providers with one file is always the first URI
1049
                return getURIOfFirstProvider();
1050
        }
1051
        
1052
        public int getBandPositionByProvider(int band) {
1053
                return band;
1054
        }
1055
        
1056
        public int getSubdatasetCount() {
1057
                return 0;
1058
        }
1059
        
1060
        public void addFile(String file) throws InvalidSourceException {
1061
                //Do nothing
1062
        }
1063
        
1064
        public void removeFile(String file) {
1065
                //Do nothing                
1066
        }
1067
        
1068
        public boolean needEnhanced() {
1069
                return false;
1070
        }
1071
        
1072
        /**
1073
         * Gets the {@link Interval} of the store, that means the temporal
1074
         * interval where the store has valid data.
1075
         * In raster this method has sense in a mosaic. Therefore this has to be implemented 
1076
         * by the provider.
1077
         * @return
1078
         *         a time interval or null if there is not time support
1079
         */
1080
        public Interval getInterval() {
1081
                return null;
1082
        }
1083
        
1084
        /**
1085
         * Gets all the possible values of time for which the store has data.  
1086
         * In raster this method has sense in a mosaic. Therefore this has to be implemented 
1087
         * by the provider.
1088
         * @return
1089
         *         a collection of {@link Time} objects.
1090
         */
1091
        public Collection<?> getTimes() {
1092
                return null;
1093
        }
1094
        
1095
        /**
1096
         * Gets all the possible values of time for which the store has data
1097
         * and intersects with an interval.
1098
         * In raster this method has sense in a mosaic. Therefore this has to be implemented 
1099
         * by the provider.
1100
         * @param interval
1101
         *         the interval of time
1102
         * @return
1103
         *         a collection of {@link Time} objects.
1104
         */
1105
        public Collection<?> getTimes(Interval interval) {
1106
                return null;
1107
        }
1108
        
1109
        /**
1110
         * Gets the list of geo points associated to this provider
1111
         * @return
1112
         */
1113
        public GeoPointList getGeoPointList() {
1114
                return geoPointList;
1115
        }
1116
        
1117
        /**
1118
         * Sets the list of geo points associated to this provider
1119
         */
1120
        public void setGeoPointList(GeoPointList geoPointList) {
1121
                this.geoPointList = geoPointList;
1122
        }
1123
        
1124
        /**
1125
         * @deprecated This method should not be used. The store have a getDefaultBandList
1126
         * @return
1127
         */
1128
        public BandList getDefaultBandList() {
1129
                BandList bandList = new BandListImpl();
1130
                String[] uriByProvider = getURIByProvider();
1131
                int[] nBandsByProvider = getBandCountByProvider();
1132
                
1133
                for (int iProvider = 0; iProvider < uriByProvider.length; iProvider++) {
1134
                        for (int iBand = 0; iBand < nBandsByProvider[iProvider]; iBand++) {
1135
                                try {
1136
                                        bandList.addBand(new DatasetBandImpl(uriByProvider[iProvider], iBand, getDataType()[0], nBandsByProvider[iProvider]));
1137
                                } catch (BandNotFoundInListException e1) {
1138
                                }
1139
                        }
1140
                }
1141
                
1142
                int[] drawableBands = new int[bandList.getBandCount()];
1143
                for (int i = 0; i < bandList.getBandCount(); i++) {
1144
                        drawableBands[i] = i;
1145
                }
1146
                
1147
                bandList.setDrawableBands(drawableBands);
1148
                return bandList;
1149
        }
1150
        
1151
        public void close() {
1152
                if(transparency != null)
1153
                        transparency.dispose();
1154
                try {
1155
                        finalize();
1156
                } catch (Throwable e) {
1157
                }
1158
        }
1159
        
1160
        protected void finalize() throws Throwable {
1161
                dataType               = null;
1162
                noData                 = null;
1163
                stats                  = null;
1164
                histogram              = null;
1165
                param                  = null;
1166
                storeServices          = null;
1167
                rmfBlocksManager       = null;
1168
                colorTable             = null;
1169
                colorInterpretation    = null;
1170
                serialInfo             = null;
1171
                transparency           = null;
1172
                tileServer             = null;
1173
                fileUtil               = null;
1174
                rasterUtil             = null;
1175
                proj                   = null;
1176
                uri                    = null;
1177
                selectedSubdatasetID   = null;
1178
                ownTransformation      = null;
1179
                externalTransformation = null;
1180
        }
1181
}