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

History | View | Annotate | Download (39.8 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.security.NoSuchAlgorithmException;
31
import java.util.Collection;
32
import java.util.Date;
33
import java.util.Iterator;
34
import java.util.List;
35

    
36
import org.apache.commons.io.FilenameUtils;
37
import org.cresques.cts.IProjection;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

    
41
import org.gvsig.compat.net.ICancellable;
42
import org.gvsig.fmap.dal.DALLocator;
43
import org.gvsig.fmap.dal.DataServerExplorer;
44
import org.gvsig.fmap.dal.DataStoreParameters;
45
import org.gvsig.fmap.dal.coverage.RasterLibrary;
46
import org.gvsig.fmap.dal.coverage.RasterLocator;
47
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
48
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
49
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
50
import org.gvsig.fmap.dal.coverage.datastruct.GeoPointList;
51
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
52
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
53
import org.gvsig.fmap.dal.coverage.exception.BandNotFoundInListException;
54
import org.gvsig.fmap.dal.coverage.exception.CloneException;
55
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
56
import org.gvsig.fmap.dal.coverage.exception.InfoByPointException;
57
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
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

    
114
/**
115
 * Base class for all raster providers.
116
 * @author Nacho Brodin (nachobrodin@gmail.com)
117
 */
118
public abstract class AbstractRasterProvider extends AbstractCoverageStoreProvider implements RasterProvider {
119
    
120
    private static final Logger LOG = LoggerFactory.getLogger(AbstractRasterProvider.class);
121
    
122
        /**
123
         * Flags que representan a las bandas visualizables
124
         */
125
        public static final int                   RED_BAND               = 0x01;
126
        public static final int                   GREEN_BAND             = 0x02;
127
        public static final int                   BLUE_BAND              = 0x04;
128
        public static final int                   ALPHA_BAND             = 0x08;
129

    
130
        protected int                             bandCount              = 1;
131
        private int[]                             dataType               = null;
132
        protected NoData                          noData                 = null;
133

    
134
        protected Statistics                      stats                  = null;
135
        protected HistogramComputer               histogram              = null;
136
        protected DataStoreParameters             param                  = null;
137
        protected DataStoreProviderServices       storeServices          = null;
138
        protected RmfBlocksManager                rmfBlocksManager       = null;
139
        protected ColorTable                      colorTable             = null;
140
        private ColorInterpretation               colorInterpretation    = null;
141
        protected TimeSeries                      serialInfo             = null;
142
        protected Transparency                    transparency           = null;
143
        protected TileServer                      tileServer             = null;
144
        protected GeoPointList                    geoPointList           = null;
145

    
146
        protected FileUtils                       fileUtil               = RasterLocator.getManager().getFileUtils();
147
        protected RasterUtils                     rasterUtil             = RasterLocator.getManager().getRasterUtils();
148

    
149
        protected IProjection                     proj                   = null;
150
        protected long                            fileSize               = 0;
151
        protected long                            bytesReaded            = 0;
152
        protected long                            lineCnt                = 0;
153
        protected URI                          uri;
154
        protected String                          selectedSubdatasetID   = null;
155
        /**
156
         * Transformaci?n creada a partir de la informaci?n de georreferencia de la
157
         * propia imagen. Esta informaci?n est? en la cabecera o en ficheros
158
         * worldfile.
159
         */
160
        protected AffineTransform                 ownTransformation      = null;
161
        /**
162
         * Transformaci?n asignada de forma externa, bien desde el fichero rmf o
163
         * asignada directamente por el usuario.
164
         */
165
        protected AffineTransform                 externalTransformation = null;
166
        private static Logger                     logger                 = LoggerFactory.getLogger(AbstractRasterProvider.class.getName());
167

    
168
    public AbstractRasterProvider(AbstractRasterDataParameters params,
169
        DataStoreProviderServices storeServices, DynObject metadata) {
170
        super(params, storeServices, metadata);
171
        if (params.getURI() != null) {
172
            uri = params.getURI();
173
            if ("FILE".equalsIgnoreCase(uri.getScheme())) {
174
                File f = new File(uri);
175
                if (f.exists()) {
176
                    setFileSize(f.length());
177
                }
178
            }
179
            uri = translateURI(uri);
180
        }
181
        
182
        // If there is a defined SRS, set it to provider. This must be override
183
        // if provider is georeferenced.
184
        if(params != null && params.getSRS() != null){
185
            try {
186
                this.setProjection(params.getSRS(), false);
187
            } catch (RmfSerializerException e) {
188
                LOG.warn("Can not persist {} parameter projection to {} provider",
189
                    new Object[] { params.getSRSID(), this.getName() });
190
            }
191
        }
192

    
193
        ownTransformation = new AffineTransform();
194
        externalTransformation = new AffineTransform();
195
    }
196

    
197
        public AbstractRasterProvider(DataStoreParameters params,
198
                        DataStoreProviderServices storeServices, DynObject metadata) {
199
                super(params, storeServices, metadata);
200
                RasterDataParameters rasterParameters = (RasterDataParameters) params;
201
                URI uriParam = rasterParameters.getURI();
202
        if(uriParam != null) {
203
            if ("FILE".equalsIgnoreCase(uriParam.getScheme())) {
204
                File f = new File(uriParam);
205
                if (f.exists())
206
                    setFileSize(f.length());
207
            }
208
                        if(params instanceof RemoteStoreParameters)
209
                                uri = translateURI(uriParam);
210
                }
211
        
212
        if(rasterParameters != null && rasterParameters.getSRS() != null){
213
            try {
214
                this.setProjection(rasterParameters.getSRS(), false);
215
            } catch (RmfSerializerException e) {
216
                LOG.warn("Can not persist {} parameter projection to {} provider",
217
                    new Object[] { rasterParameters.getSRSID(), this.getName() });
218
            }
219
        }
220

    
221
                ownTransformation = new AffineTransform();
222
                externalTransformation = new AffineTransform();
223
        }
224

    
225
        public AbstractRasterProvider(String params) {
226
                super();
227
        }
228

    
229
        public AbstractRasterProvider(URI uri) {
230
        super();
231
    }
232

    
233
        public AbstractRasterProvider() {
234
                super(null, null, null);
235
        }
236

    
237
        public String[] getFormatList() {
238
                return null;
239
        }
240

    
241
        /**
242
         * Acciones de inicilizaci?n comunes a todos los drivers.
243
         * Este m?todo debe ser llamado explicitamente por el constructor de cada driver.
244
         * Estas son acciones de inicializaci?n que se ejecutan despu?s del constructor de cada driver.
245
         * Las acciones que hayan de ser realizadas antes se definen en el constructor de RasterDataset.
246
         */
247
        protected void init() {
248
        }
249

    
250
        public boolean isRGB() {
251
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
252
                        ColorInterpretation ci = getColorInterpretation();
253
                        return ci.isRGB();
254
                }
255
                return false;
256
        }
257

    
258
        public boolean isARGB() {
259
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
260
                        ColorInterpretation ci = getColorInterpretation();
261
                        return ci.isRGBA();
262
                }
263
                return false;
264
        }
265

    
266
        public boolean isTiled() {
267
                return false;
268
        }
269

    
270
        public boolean isTimeSupported() {
271
                return false;
272
        }
273

    
274
        public RasterProvider cloneProvider() throws CloneException {
275
                try {
276
                        DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
277
                        AbstractRasterProvider provider = (AbstractRasterProvider)dataManager.createProvider(storeServices, param);
278
                        //DefaultRasterProvider provider = singleDatasetInstance(storeServices, param);
279
                        // Estas van por referencia
280
                        provider.histogram = histogram;
281
                        provider.stats = stats;
282
                        return provider;
283
                } catch (ProviderNotRegisteredException e) {
284
                        e.printStackTrace();
285
                } catch (InitializeException e) {
286
                        e.printStackTrace();
287
                }
288
                return null;
289
        }
290

    
291
        /**
292
         * Factoria para abrir distintos tipos de raster.
293
         * @param storeServices
294
         * @param param
295
         *
296
         * @return SingleDataset, o null si hay problemas.
297
         * @throws RasterDriverException
298
         */
299
        @SuppressWarnings("unchecked")
300
        public static AbstractRasterProvider singleDatasetInstance(DataStoreProviderServices storeServices, String param) throws RasterDriverException {
301
                DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
302
                //We have to locate a provider's name which manages the selected file
303
                //A FilesystemServerExplorer will give a getProviderNames service
304

    
305
                FilesystemServerExplorer serverExplorer = null;
306
                try {
307
                        FilesystemServerExplorerParameters paramsExplorer = (FilesystemServerExplorerParameters)dataManager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
308
                        paramsExplorer.setRoot(File.separator);
309
                        serverExplorer = (FilesystemServerExplorer)dataManager.openServerExplorer(FilesystemServerExplorer.NAME, paramsExplorer);
310
                } catch (ValidateDataParametersException e) {
311
                        throw new RasterDriverException("Error validating parameters", e);
312
                } catch (InitializeException e) {
313
                        throw new RasterDriverException("Error creating a server explorer ", e);
314
                } catch (ProviderNotRegisteredException e) {
315
                        throw new RasterDriverException("Provider not registered", e);
316
                }
317

    
318
                //Gets the list of provider's name to manage the file
319
                File file = new File(param);
320
                List<String> provName = serverExplorer.getProviderNameList(file);
321
                if(provName.size() > 0) {
322
                        for (int i = 0; i < provName.size(); i++) {
323
                                //Gets the first provider what is not a TileProvider
324
                                if(provName.get(i).compareTo("Tile Store") != 0) {
325
                                        DataStoreParameters newparams;
326
                                        try {
327
                                                newparams = dataManager.createStoreParameters(provName.get(i));
328
                                                ((FilesystemStoreParameters)newparams).setFile(file);
329
                                                if(storeServices == null)
330
                                                        storeServices = new DefaultRasterStore();
331
                                                return (AbstractRasterProvider)dataManager.createProvider(storeServices, newparams);
332
                                        } catch (InitializeException e) {
333
                                                throw new RasterDriverException("Error creating a server explorer ", e);
334
                                        } catch (ProviderNotRegisteredException e) {
335
                                                throw new RasterDriverException("Provider not registered", e);
336
                                        }
337
                                }
338
                        }
339
                }
340
                return null;
341
        }
342

    
343
        /**
344
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar
345
         * un objeto de este tipo.
346
         * @return RasterProvider
347
         */
348
        abstract public RasterProvider load();
349

    
350
        /**
351
         * Obtiene el ancho de la imagen
352
         * @return Ancho de la imagen
353
         */
354
        abstract public double getWidth();
355

    
356
        /**
357
         * Obtiene el ancho de la imagen
358
         * @return Ancho de la imagen
359
         */
360
        abstract public double getHeight();
361

    
362
        /**
363
         * Asigna un nuevo Extent
364
         * @param e        Extent
365
         */
366
        public abstract void setView(Extent e);
367

    
368
        /**
369
         * Obtiene el extent asignado
370
         * @return        Extent
371
         */
372
        public abstract Extent getView();
373

    
374
        /**
375
         * Obtiene el valor del raster en la coordenada que se le pasa.
376
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
377
         * raster.
378
         * @param x        coordenada X
379
         * @param y coordenada Y
380
         * @return data
381
         */
382
        abstract public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
383

    
384
        /**
385
         * Gets the set of data selected in the {@link RasterQuery}
386
         * @param q
387
         * @return buffer
388
         * @throws RasterDriverException
389
         * @throws ProcessInterruptedException
390
         */
391
        public Buffer getDataSet(SpiRasterQuery query) throws ProcessInterruptedException, RasterDriverException {
392
                SpiRasterQuery q = (SpiRasterQuery)query;
393
                loadBuffer(q);
394
                return q.getBufferForProviders();
395
        }
396

    
397
        /**
398
         * Load a buffer with the parameters. The buffer should already have been created
399
         * inside the query structure <code>SpiRasterQuery</code> by the <code>RasterDataStore</code>. The other
400
         * parameters have been calculated too, all of them adjusted to the raster limits. The provider only
401
         * have to read the parameters and load the buffer.
402
         *
403
         * @param query
404
         * @throws ProcessInterruptedException
405
         * @throws RasterDriverException
406
         */
407
        abstract public void loadBuffer(SpiRasterQuery query) throws ProcessInterruptedException, RasterDriverException;
408

    
409
        abstract public int getBlockSize();
410

    
411
        abstract public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException;
412

    
413
        /**
414
         * Informa de si el dataset soporta overviews o no.
415
         * @return true si soporta overviews y false si no las soporta.
416
         */
417
        abstract public boolean isOverviewsSupported();
418

    
419
        public void reload() {
420
                try {
421
                        loadFromRmf(getRmfBlocksManager());
422
                } catch (ParsingException e) {
423
                        logger.debug("No se ha podido leer el RMF", e);
424
                }
425
        }
426

    
427
        /**
428
         * Carga metadatos desde el fichero Rmf si estos existen
429
         * @param fName Nombre del fichero
430
         * @throws ParsingException
431
         */
432
        protected void loadFromRmf(RmfBlocksManager manager) throws ParsingException {
433
                if (!manager.checkRmf())
434
                        return;
435

    
436
                if (!new File(manager.getPath()).exists())
437
                        return;
438

    
439
                GeoInfoRmfSerializer geoInfoSerializer = new GeoInfoRmfSerializer(this);
440
                ColorTableRmfSerializer colorTableSerializer = new ColorTableRmfSerializer();
441
                GeoPointListRmfSerializer gcpSerializer = new GeoPointListRmfSerializer();
442
                NoDataRmfSerializer noDataSerializer = null;
443
                if(noData == null)
444
                        noData = new DefaultNoData(null, null, manager.getPath(), getBandCount());
445
                noDataSerializer = new NoDataRmfSerializer((DefaultNoData)noData);
446
                ColorInterpretationRmfSerializer colorInterpSerializer = new ColorInterpretationRmfSerializer();
447
                ProjectionRmfSerializer projectionRmfSerializer = new ProjectionRmfSerializer();
448
                StatisticsRmfSerializer statsRmfSerializer = new StatisticsRmfSerializer(getStatistics());
449

    
450
                manager.addClient(geoInfoSerializer);
451
                manager.addClient(colorTableSerializer);
452
                manager.addClient(gcpSerializer);
453
                manager.addClient(noDataSerializer);
454
                manager.addClient(colorInterpSerializer);
455
                manager.addClient(projectionRmfSerializer);
456
                manager.addClient(statsRmfSerializer);
457

    
458
                manager.read(null);
459

    
460
                manager.removeAllClients();
461

    
462
                if (colorTableSerializer.getResult() != null)
463
                        setColorTable((ColorTable) colorTableSerializer.getResult());
464

    
465
                if (colorInterpSerializer.getResult() != null) {
466
                        DataStoreColorInterpretation ci = (DataStoreColorInterpretation) colorInterpSerializer.getResult();
467
                        setColorInterpretation(ci);
468
                        getTransparency().setColorInterpretation(ci);
469
                        getTransparency().setTransparencyBand(ci.getBand(DataStoreColorInterpretation.ALPHA_BAND));
470
                }
471

    
472
                if (projectionRmfSerializer.getResult() != null) {
473
                        proj = (IProjection) projectionRmfSerializer.getResult();
474
                }
475

    
476
                if( gcpSerializer.getResult() != null &&
477
                        gcpSerializer.getResult() instanceof GeoPointList &&
478
                        ((GeoPointList)gcpSerializer.getResult()).size() > 0) {
479
                        setGeoPointList((GeoPointList)gcpSerializer.getResult());
480
                }
481
        }
482

    
483
        /**
484
         * Obtiene el n?mero de bandas del fichero
485
         * @return Entero que representa el n?mero de bandas
486
         */
487
        public int getBandCount() {
488
                return bandCount;
489
        }
490

    
491
        /**
492
         * @return Returns the dataType.
493
         */
494
        public int[] getDataType() {
495
                return dataType;
496
        }
497

    
498
        /**
499
         * @param dataType The dataType to set.
500
         */
501
        public void setDataType(int[] dataType) {
502
                this.dataType = dataType;
503
        }
504

    
505
        public double getPixelSizeX() {
506
                return externalTransformation.getScaleX();
507
        }
508

    
509
        public double getPixelSizeY() {
510
                return externalTransformation.getScaleY();
511
        }
512

    
513
        public NoData getNoDataValue() {
514
                if(noData == null) {
515
                        noData = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(getBandCount(), getDataType()[0]);
516
                        noData.setNoDataTransparent(false);
517
                        File rmfFile = getRMFFile();
518
                        if(rmfFile!=null){
519
                            noData.setFileName(rmfFile.getName());
520
                        }
521
                }
522
                return noData;
523
        }
524

    
525
        public void setNoDataValue(NoData value) {
526
                this.noData = value;
527
        }
528

    
529
        /**
530
         * Dice si el fichero tiene georreferenciaci?n o no.
531
         * @return true si tiene georreferenciaci?n y false si no la tiene
532
         */
533
        public boolean isGeoreferenced() {
534
                return true;
535
        }
536

    
537
        /**
538
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
539
         * @param pt Punto a transformar
540
         * @return punto transformado en coordenadas del mundo
541
         */
542
        public Point2D rasterToWorld(Point2D pt) {
543
                Point2D p = new Point2D.Double();
544
                externalTransformation.transform(pt, p);
545
                return p;
546
        }
547

    
548
        /**
549
         * Convierte un punto desde del mundo a coordenadas pixel.
550
         * @param pt Punto a transformar
551
         * @return punto transformado en coordenadas pixel
552
         */
553
        public Point2D worldToRaster(Point2D pt) {
554
                Point2D p = new Point2D.Double();
555
                try {
556
                        externalTransformation.inverseTransform(pt, p);
557
                } catch (NoninvertibleTransformException e) {
558
                        return pt;
559
                }
560
                return p;
561
        }
562

    
563
        /**
564
         * Calcula el extent en coordenadas del mundo real
565
         * @return Extent
566
         */
567
        public Extent getExtent() {
568
                return new ExtentImpl(        rasterToWorld(new Point2D.Double(0, 0)),
569
                                                        rasterToWorld(new Point2D.Double(getWidth(), getHeight())),
570
                                                        rasterToWorld(new Point2D.Double(getWidth(), 0)),
571
                                                        rasterToWorld(new Point2D.Double(0, getHeight())));
572
        }
573

    
574
        /**
575
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
576
         * @return Extent
577
         */
578
        public Extent getExtentWithoutRot() {
579
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0,
580
                                                                                                        0, externalTransformation.getScaleY(),
581
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
582
                Point2D p1 = new Point2D.Double(0, 0);
583
                Point2D p2 = new Point2D.Double(getWidth(), getHeight());
584
                at.transform(p1, p1);
585
                at.transform(p2, p2);
586
                return new ExtentImpl(p1, p2);
587
        }
588

    
589
        /**
590
         * Asigna el par?metro de inicializaci?n del driver.
591
         * @param provServices
592
         * @param param
593
         */
594
        public void setParam(DataStoreProviderServices provServices, DataStoreParameters param) {
595
                if(param instanceof RasterDataParameters)
596
                        this.uri = ((RasterDataParameters)param).getURI();
597
                this.param = param;
598
                this.storeServices = provServices;
599
        }
600

    
601
        abstract public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException;
602

    
603
        public void selectSubdataset() {}
604

    
605
        /**
606
         * Selects the subdataset. This method will select
607
         * the rmf file.
608
         */
609
        protected void selectSubdataset(String subdataset) {
610
                selectedSubdatasetID = subdataset;
611
                getRmfBlocksManager().setPath(getRMFFile().getPath());
612
        }
613

    
614
        /**
615
         * Obtiene el gestor de ficheros RMF
616
         * @return RmfBloksManager
617
         */
618
        public RmfBlocksManager getRmfBlocksManager() {
619
                File fileRMF = getRMFFile();
620
                if(fileRMF != null) {
621
                        if (rmfBlocksManager == null || !fileRMF.equals(rmfBlocksManager)) {
622
                                rmfBlocksManager = new RmfBlocksManager(fileRMF.getPath());
623
                        }
624
                }
625
                return rmfBlocksManager;
626
        }
627

    
628
    public File getRMFFile() {
629
        String tail = selectedSubdatasetID == null ? ".rmf" : "-sd" + selectedSubdatasetID + ".rmf";
630
        File rmfFolder =
631
            (getDataParameters() != null && getDataParameters() instanceof RasterDataParameters)
632
                ? ((RasterDataParameters) getDataParameters()).getRMFFolder() : null;
633

    
634
        String fileName;
635

    
636
        URI objUri = getURI();
637
        File file;
638
        if ("FILE".equalsIgnoreCase(objUri.getScheme())) {
639
            file = new File(objUri);
640
            fileName = FilenameUtils.getBaseName(new File(objUri).getAbsolutePath());
641
            if (rmfFolder == null) {
642
                rmfFolder = file.getParentFile();
643
                if ((getDataParameters() != null && getDataParameters() instanceof RasterDataParameters)) {
644
                    ((RasterDataParameters) getDataParameters()).setRMFFolder(rmfFolder);
645
                }
646
            }
647
            return new File(rmfFolder.getAbsolutePath() + File.separator + fileName + tail);
648
        }
649
        return new File(getRMFFileForRemoteServices(getName()));
650
    }
651

    
652
        protected String getRMFFileForRemoteServices(String layerName) {
653
                String md5 = "";
654
                try {
655
                        md5 = RasterLocator.getManager().getFileUtils().convertPathToMD5(uri.toString());
656
                } catch (LocatorException e) {
657
                        logger.debug("Error getting the Locator", e);
658
                } catch (NoSuchAlgorithmException e) {
659
                        logger.debug("Error getting the algorithm MD5", e);
660
                }
661
                File path = new File(RasterLibrary.pathRMFRemote);
662
                if(!path.exists())
663
                        path.mkdir();
664
                return RasterLibrary.pathRMFRemote + File.separator + md5 + "-" + layerName + ".rmf";
665
        }
666

    
667
        public boolean isInside(Point2D p){
668
                //Realizamos los calculos solo si el punto est?n dentro del extent de la imagen rotada, as? nos ahorramos los calculos
669
                //cuando el puntero est? fuera
670

    
671
                Point2D pt = new Point2D.Double();
672
                try {
673

    
674
                        getAffineTransform().inverseTransform(p, pt);
675
                        if(        pt.getX() >= 0 && pt.getX() < getWidth() &&
676
                                        pt.getY() >= 0 && pt.getY() < getHeight())
677
                                return true;
678
                } catch (NoninvertibleTransformException e) {
679
                        return false;
680
                }
681

    
682
                return false;
683
        }
684

    
685
        /**
686
         * Consulta de si un raster tiene rotaci?n o no.
687
         * @return true si tiene rotaci?n y false si no la tiene.
688
         */
689
        public boolean isRotated() {
690
                if(externalTransformation.getShearX() != 0 || externalTransformation.getShearY() != 0)
691
                        return true;
692
                return false;
693
        }
694

    
695
        public boolean isMultiFile() {
696
                return false;
697
        }
698

    
699
        public boolean isMosaic() {
700
                return false;
701
        }
702

    
703
        /**
704
         * Devuelve si el Dataset es reproyectable
705
         * @return true if Dataset is reproyectable
706
         */
707
        public boolean isReproyectable() {
708
                return true;
709
        }
710

    
711
        public String getWktProjection() {
712
                if(proj != null && RasterLocator.getManager().isCRSUtilSupported())
713
                        return RasterLocator.getManager().getCRSUtils().convertIProjectionToWkt((IProjection) proj);
714
                return null;
715
        }
716

    
717
        public void saveObjectToRmf(Class<?> class1, Object value) throws RmfSerializerException {
718
        if (getRmfBlocksManager() != null) {
719
            ((DefaultProviderServices) RasterLocator.getManager().getProviderServices()).saveObjectToRmfFile(
720
                getRmfBlocksManager(), class1, value);
721
        }
722
        }
723

    
724
        /**
725
         * Carga un objecto desde un serializador del tipo class1. Usa value para iniciar dicho
726
         * serializador
727
         *
728
         * @param class1
729
         * @param value
730
         * @return
731
         * @throws RmfSerializerException
732
         */
733
        private static Object loadObjectFromRmfFile(RmfBlocksManager blocksManager, Class<?> class1, Object value) throws RmfSerializerException {
734
                ClassSerializer serializerObject = ((DefaultProviderServices)RasterLocator.getManager().getProviderServices()).getSerializerObject(class1, value);
735

    
736
                if (serializerObject == null)
737
                        throw new RmfSerializerException("No se ha podido encontrar el serializador para el Rmf");
738

    
739
                if (!blocksManager.checkRmf())
740
                        throw new RmfSerializerException("Error al comprobar el fichero Rmf");
741

    
742
                blocksManager.addClient(serializerObject);
743
                try {
744
                        blocksManager.read(null);
745
                } catch (ParsingException e) {
746
                        throw new RmfSerializerException("Error al leer el fichero Rmf", e);
747
                }
748
                blocksManager.removeAllClients();
749

    
750
                return serializerObject.getResult();
751
        }
752

    
753
        public Object loadObjectFromRmf(Class<?> class1, Object value) throws RmfSerializerException {
754
                RmfBlocksManager blocksManager = getRmfBlocksManager();
755
                if(blocksManager!=null){
756
                    return loadObjectFromRmfFile(blocksManager, class1, value);
757
                }
758
                return null;
759
        }
760

    
761
        /**
762
         * Carga un objeto del fichero RMF especificado por parametro
763
         * @param file
764
         * @param class1
765
         * @param value
766
         * @return Object
767
         * @throws RmfSerializerException
768
         */
769
        public static Object loadObjectFromRmfFile(String file, Class<?> class1, Object value) throws RmfSerializerException {
770
                String fileRMF = RasterLocator.getManager().getFileUtils().getNameWithoutExtension(file) + ".rmf";
771
                RmfBlocksManager blocksManager = new RmfBlocksManager(fileRMF);
772
                return loadObjectFromRmfFile(blocksManager, class1, value);
773
        }
774

    
775
        /**
776
         * Guarda en el RMF el objecto actual en caso de que exista un serializador para el
777
         * @param value
778
         * @throws RmfSerializerException
779
         */
780
        public void saveObjectToRmf(Object value) throws RmfSerializerException {
781
                saveObjectToRmf(value.getClass(), value);
782
        }
783

    
784
        /**
785
         * Carga un objecto desde un serializador usando el tipo del mismo objeto pasado por parametro.
786
         * Usa value para iniciar dicho serializador
787
         * @param value
788
         * @return Object
789
         * @throws RmfSerializerException
790
         */
791
        public Object loadObjectFromRmf(Object value) throws RmfSerializerException {
792
                return loadObjectFromRmf(value.getClass(), value);
793
        }
794

    
795

    
796
        public double getCellSize() {
797
                try {
798
                        Extent e = getExtent();
799
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getWidth();
800
                        return dCellsize;
801
                } catch (NullPointerException e) {
802
                        return 1;
803
                }
804
        }
805

    
806

    
807
        public RasterProvider newProvider() {
808
                return null;
809
        }
810

    
811
        public ColorTable getColorTable() {
812
                return colorTable;
813
        }
814

    
815
        public Image getImageLegend() {
816
                return null;
817
        }
818

    
819
        public void setColorTable(ColorTable value) {
820
                colorTable = value;
821
        }
822

    
823
        public Transparency getTransparency() {
824
                return transparency;
825
        }
826

    
827
        public Metadata getMetadata() {
828
                return null;
829
        }
830

    
831
        public ColorInterpretation getColorInterpretation() {
832
                return this.colorInterpretation;
833
        }
834

    
835
        /**
836
         * Asigna el objeto que contiene que contiene la interpretaci?n de
837
         * color por banda
838
         * @param DataStoreColorInterpretation
839
         */
840
        public void setColorInterpretation(ColorInterpretation colorInterpretation) {
841
                this.colorInterpretation = colorInterpretation;
842
        }
843

    
844
        public Statistics getStatistics() {
845
                if(stats == null) {
846
                        stats = new SimpleProviderStatistics(this);
847
                }
848
                return stats;
849
        }
850

    
851
        public void setStatistics(Statistics stats) throws RmfSerializerException {
852
                this.stats = stats;
853
                saveObjectToRmf(Statistics.class, stats);
854
        }
855

    
856
        public HistogramComputer getHistogramComputer() {
857
                if (histogram == null)
858
                        histogram = new SimpleProviderHistogramComputer(this);
859
                return histogram;
860
        }
861

    
862
    //****************************************************
863
        //*********Implementing Disposable methods************
864
        //****************************************************
865

    
866
    public void doDispose() {
867

    
868
    }
869

    
870
    //****************************************************
871
        //*****Implementing DataStoreProvider methods*********
872
        //****************************************************
873

    
874
        @Override
875
        public DataServerExplorer getExplorer() throws ReadException,
876
                        ValidateDataParametersException {
877
            /*DataManager manager = DALLocator.getDataManager();
878
                FilesystemServerExplorerParameters params;
879
                try {
880
                        params = (FilesystemServerExplorerParameters) manager
881
                                        .createServerExplorerParameters(FilesystemServerExplorer.NAME);
882
                        params.setRoot(((AbstractRasterStoreParameters)this.getDataParameters()).getFile().getParent());
883
                        return manager.createServerExplorer(params);
884
                } catch (DataException e) {
885
                        throw new ReadException(this.getName(), e);
886
                }*/
887
            return null;
888
        }
889

    
890

    
891
        /**
892
         * Returs the DataParameters
893
         * @return the DataParameters
894
         */
895
        public RasterDataParameters getDataParameters() {
896
                if(getDataStoreParameters() instanceof RasterDataParameters)
897
                        return (RasterDataParameters)getDataStoreParameters();
898
                return null;
899
        }
900

    
901
        public Iterator<?> getChilds() {
902
                return null;
903
        }
904

    
905
        public ResourceProvider getResource() {
906
                return null;
907
        }
908

    
909
        public Object getSourceId() {
910
                if( this.getDataParameters() instanceof RasterFileStoreParameters)
911
                        return ((RasterFileStoreParameters)this.getDataParameters()).getFile();
912
                else
913
                        return this.getDataParameters().getURI();
914
        }
915

    
916
        public void open() throws OpenException {
917
        }
918

    
919
        /**
920
         * Traduce el nombre del fichero por un alias asignado por el propio driver.
921
         * Cuando es traducido por un alias el driver intentar? abrir el alias y no el
922
         * fichero. Esto es util porque algunos formatos tienen la extensi?n en el
923
         * fichero de cabecera pero lo que se abre realmente es el fichero de datos.
924
         * @param uri
925
         * @return uri
926
         */
927
        public URI translateURI(URI uri) {
928
            return uri;
929
        }
930

    
931
        /*
932
         * Si alguna subclase necesita sobreescribir este m?todo, deber? hacerlo con el translateURI en lugar de este.
933
         */
934
        public final String translateFileName(String fileName) {
935
                return fileName;
936
        }
937

    
938

    
939
        public String getFileSuffix() {
940
                String path = new File(getURIOfFirstProvider()).getAbsolutePath();
941
        return FilenameUtils.getExtension(path);
942
        }
943

    
944
        public URI getURIOfFirstProvider() {
945
            //FIXME: Esto que lo sobreescriban los proveedores que no son de archivo
946
//                return RasterLocator.getManager().getFileUtils().getFormatedRasterFileName(uri);
947
            return getURI();
948
        }
949

    
950
        public URI getURI() {
951
                return uri;
952
        }
953

    
954
        public void setFName(String n) {
955
            File file = new File(n);
956
            uri = file.toURI();
957
        }
958

    
959
    public String getName() {
960
        String pathName = null;
961
        try {
962
            URI x = this.getURI();
963
            pathName = new File(x).getAbsolutePath();
964
            return FilenameUtils.getBaseName(pathName);
965
        } catch (Throwable th1) {
966
            try {
967
                return FilenameUtils.getBaseName(this.uri.getPath());
968
            } catch (Throwable th2) {
969
                return this.uri.getPath();
970
            }
971
        }
972
    }
973

    
974
        public String getFullName() {
975
                return new File(uri).getAbsolutePath();
976
        }
977

    
978
        /**
979
         * Gets the size of the file if exists in Bytes
980
         * @return the size of file
981
         */
982
        public long getFileSize() {
983
                return fileSize;
984
        }
985

    
986
        public void setFileSize(long sz) {
987
                fileSize = sz;
988
        }
989

    
990
        public IProjection getProjection() {
991
                return proj;
992
        }
993

    
994
        public void setProjection(IProjection proj, boolean persist) throws RmfSerializerException {
995
                this.proj = proj;
996
                if(persist) {
997
                        saveObjectToRmf(IProjection.class, proj);
998
                }
999
        }
1000

    
1001
        protected long getTime() {
1002
                return (new Date()).getTime();
1003
        }
1004

    
1005
        public void setAffineTransform(AffineTransform t) {
1006
                externalTransformation = (AffineTransform) t.clone();
1007
        }
1008

    
1009
        public AffineTransform getAffineTransform() {
1010
                return externalTransformation;
1011
        }
1012

    
1013
        /**
1014
         * Elimina la matriz de transformaci?n asociada al raster y que se tiene en
1015
         * cuenta para el setView. Este reseteo tendr? en cuenta que si el raster
1016
         * tiene asociado un rmf esta transformaci?n no ser? eliminada sino que se
1017
         * asignar? la correspondiente al rmf existente.
1018
         */
1019
        public void resetAffineTransform() {
1020
                externalTransformation.setToIdentity();
1021
        }
1022

    
1023
        public AffineTransform getOwnAffineTransform() {
1024
                return ownTransformation;
1025
        }
1026

    
1027
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
1028
                return null;
1029
        }
1030

    
1031
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
1032
                return null;
1033
        }
1034

    
1035
        public void setTileServer(Class<?> tileServer) throws InitializeException {
1036

    
1037
        }
1038

    
1039
        public int[] getTileSize(int level) {
1040
                return new int[]{0, 0};
1041
        }
1042

    
1043
        public boolean isRasterEnclosed() {
1044
                return false;
1045
        }
1046

    
1047
        public int getSourceType() {
1048
            String scheme = getURI().getScheme();
1049
        if("PG".equalsIgnoreCase(scheme)){
1050
                   return RasterDataStore.POSTGIS;
1051
            } else if ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)) {
1052
            return RasterDataStore.REMOTE;
1053
            }
1054
        //"file".equalsIgnoreCase(scheme)
1055
                return RasterDataStore.FILE;
1056
        }
1057

    
1058
        /**
1059
         * Most of providers don't need tiles. It those cases this method
1060
         * won't execute anything. Only providers that use tile cache will need
1061
         * implement this function, for instance TileProvider and MosaicProvider.
1062
         */
1063
        public void deleteLayerFromCache() {
1064

    
1065
        }
1066

    
1067
        public TimeSeries getTimeSerials() throws RmfSerializerException {
1068
                if(serialInfo == null) {
1069
                        serialInfo =  new DefaultTimeSerials();
1070
                        loadObjectFromRmf(TimeSeries.class, serialInfo);
1071
                        //Seleccionamos la primera serie por defecto. El usuario seleccionar? otra si la necesita
1072
                        serialInfo.selectSerial(0);
1073
                }
1074
                return serialInfo;
1075
        }
1076

    
1077
        public void setTimeSerials(TimeSeries serialInfo) throws RmfSerializerException {
1078
                this.serialInfo = serialInfo;
1079
                saveObjectToRmf(TimeSeries.class, serialInfo);
1080
        }
1081

    
1082
        public long[] getFileSizeByProvider() {
1083
                return new long[]{getFileSize()};
1084
        }
1085

    
1086
        public URI[] getURIByProvider() {
1087
                //For providers with one file
1088
                return new URI[]{getURIOfFirstProvider()};
1089
        }
1090

    
1091
        public int[] getBandCountByProvider() {
1092
                return new int[]{getBandCount()};
1093
        }
1094

    
1095
        public int getInternalProviderCount() {
1096
                return 1;
1097
        }
1098

    
1099
        public RasterProvider getInternalProvider(int i) {
1100
                return this;
1101
        }
1102

    
1103
        public URI getURIByBand(int band) {
1104
                //No matter which band be selected. In providers with one file is always the first URI
1105
                return getURIOfFirstProvider();
1106
        }
1107

    
1108
        public int getBandPositionByProvider(int band) {
1109
                return band;
1110
        }
1111

    
1112
        public int getSubdatasetCount() {
1113
                return 0;
1114
        }
1115

    
1116
//        public void addFile(File file) throws InvalidSourceException {
1117
//                //Do nothing
1118
//        }
1119
//
1120
//        public void removeFile(File file) {
1121
//                //Do nothing
1122
//        }
1123

    
1124
        public boolean needEnhanced() {
1125
                return false;
1126
        }
1127

    
1128
        /**
1129
         * Gets the {@link Interval} of the store, that means the temporal
1130
         * interval where the store has valid data.
1131
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1132
         * by the provider.
1133
         * @return
1134
         *         a time interval or null if there is not time support
1135
         */
1136
        public Interval getInterval() {
1137
                return null;
1138
        }
1139

    
1140
        /**
1141
         * Gets all the possible values of time for which the store has data.
1142
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1143
         * by the provider.
1144
         * @return
1145
         *         a collection of {@link Time} objects.
1146
         */
1147
        public Collection<?> getTimes() {
1148
                return null;
1149
        }
1150

    
1151
        /**
1152
         * Gets all the possible values of time for which the store has data
1153
         * and intersects with an interval.
1154
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1155
         * by the provider.
1156
         * @param interval
1157
         *         the interval of time
1158
         * @return
1159
         *         a collection of {@link Time} objects.
1160
         */
1161
        public Collection<?> getTimes(Interval interval) {
1162
                return null;
1163
        }
1164

    
1165
        /**
1166
         * Gets the list of geo points associated to this provider
1167
         * @return the list of geo points
1168
         */
1169
        public GeoPointList getGeoPointList() {
1170
                return geoPointList;
1171
        }
1172

    
1173
        /**
1174
         * Sets the list of geo points associated to this provider
1175
         */
1176
        public void setGeoPointList(GeoPointList geoPointList) {
1177
                this.geoPointList = geoPointList;
1178
        }
1179

    
1180
        /**
1181
         * @deprecated This method should not be used. The store have a getDefaultBandList
1182
         * @return BandList
1183
         */
1184
        public BandList getDefaultBandList() {
1185
                BandList bandList = new BandListImpl();
1186
                URI[] uriByProvider = getURIByProvider();
1187
                int[] nBandsByProvider = getBandCountByProvider();
1188

    
1189
                for (int iProvider = 0; iProvider < uriByProvider.length; iProvider++) {
1190
                        for (int iBand = 0; iBand < nBandsByProvider[iProvider]; iBand++) {
1191
                                try {
1192
                    bandList.addBand(new DatasetBandImpl(
1193
                        new File(uriByProvider[iProvider]).getAbsolutePath(),
1194
                        iBand,
1195
                        getDataType()[0],
1196
                        nBandsByProvider[iProvider])
1197
                    );
1198
                                } catch (BandNotFoundInListException e1) {
1199
                                }
1200
                        }
1201
                }
1202

    
1203
                int[] drawableBands = new int[bandList.getBandCount()];
1204
                for (int i = 0; i < bandList.getBandCount(); i++) {
1205
                        drawableBands[i] = i;
1206
                }
1207

    
1208
                bandList.setDrawableBands(drawableBands);
1209
                return bandList;
1210
        }
1211

    
1212
        public void close() {
1213
                if(transparency != null)
1214
                        transparency.dispose();
1215
                try {
1216
                        finalize();
1217
                } catch (Throwable e) {
1218
                }
1219
        }
1220

    
1221
        protected void finalize() throws Throwable {
1222
                dataType               = null;
1223
                noData                 = null;
1224
                stats                  = null;
1225
                histogram              = null;
1226
                param                  = null;
1227
                storeServices          = null;
1228
                rmfBlocksManager       = null;
1229
                colorTable             = null;
1230
                colorInterpretation    = null;
1231
                serialInfo             = null;
1232
                transparency           = null;
1233
                tileServer             = null;
1234
                fileUtil               = null;
1235
                rasterUtil             = null;
1236
                proj                   = null;
1237
                uri                    = null;
1238
                selectedSubdatasetID   = null;
1239
                ownTransformation      = null;
1240
                externalTransformation = null;
1241
        }
1242
}