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

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

    
118
/**
119
 * Base class for all raster providers.
120
 * @author Nacho Brodin (nachobrodin@gmail.com)
121
 */
122
public abstract class AbstractRasterProvider extends AbstractCoverageStoreProvider implements RasterProvider {
123

    
124
    private static final Logger LOG = LoggerFactory.getLogger(AbstractRasterProvider.class);
125

    
126
        /**
127
         * Flags que representan a las bandas visualizables
128
         */
129
        public static final int                   RED_BAND               = 0x01;
130
        public static final int                   GREEN_BAND             = 0x02;
131
        public static final int                   BLUE_BAND              = 0x04;
132
        public static final int                   ALPHA_BAND             = 0x08;
133

    
134
        protected int                             bandCount              = 1;
135
        private int[]                             dataType               = null;
136
        protected NoData                          noData                 = null;
137

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

    
150
        protected FileUtils                       fileUtil               = RasterLocator.getManager().getFileUtils();
151
        protected RasterUtils                     rasterUtil             = RasterLocator.getManager().getRasterUtils();
152

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

    
172
    public AbstractRasterProvider(AbstractRasterDataParameters params,
173
        DataStoreProviderServices storeServices, DynObject metadata) {
174
        super(params, storeServices, metadata);
175
        if (params.getURI() != null) {
176
            uri = params.getURI();
177
            if ("FILE".equalsIgnoreCase(uri.getScheme())) {
178
                File f = new File(uri);
179
                if (f.exists()) {
180
                    setFileSize(f.length());
181
                }
182
            }
183
            uri = translateURI(uri);
184
        }
185

    
186
        // If there is a defined SRS, set it to provider. This must be override
187
        // if provider is georeferenced.
188
        if(params != null && params.getSRS() != null){
189
            try {
190
                this.setProjection(params.getSRS(), false);
191
            } catch (RmfSerializerException e) {
192
                LOG.warn("Can not persist {} parameter projection to {} provider",
193
                    new Object[] { params.getSRSID(), this.getName() });
194
            }
195
        }
196

    
197
        ownTransformation = new AffineTransform();
198
        externalTransformation = new AffineTransform();
199
    }
200

    
201
        public AbstractRasterProvider(DataStoreParameters params,
202
                        DataStoreProviderServices storeServices, DynObject metadata) {
203
                super(params, storeServices, metadata);
204
                RasterDataParameters rasterParameters = (RasterDataParameters) params;
205
                URI uriParam = rasterParameters.getURI();
206
        if(uriParam != null) {
207
            if ("FILE".equalsIgnoreCase(uriParam.getScheme())) {
208
                File f = new File(uriParam);
209
                if (f.exists())
210
                    setFileSize(f.length());
211
            }
212
                        if(params instanceof RemoteStoreParameters)
213
                                uri = translateURI(uriParam);
214
                }
215

    
216
        if(rasterParameters != null && rasterParameters.getSRS() != null){
217
            try {
218
                this.setProjection(rasterParameters.getSRS(), false);
219
            } catch (RmfSerializerException e) {
220
                LOG.warn("Can not persist {} parameter projection to {} provider",
221
                    new Object[] { rasterParameters.getSRSID(), this.getName() });
222
            }
223
        }
224

    
225
                ownTransformation = new AffineTransform();
226
                externalTransformation = new AffineTransform();
227
        }
228

    
229
        public AbstractRasterProvider(String params) {
230
                super();
231
        }
232

    
233
        public AbstractRasterProvider(URI uri) {
234
        super();
235
    }
236

    
237
        public AbstractRasterProvider() {
238
                super(null, null, null);
239
        }
240

    
241
        public String[] getFormatList() {
242
                return null;
243
        }
244

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

    
254
        public boolean isRGB() {
255
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
256
                        ColorInterpretation ci = getColorInterpretation();
257
                        return ci.isRGB();
258
                }
259
                return false;
260
        }
261

    
262
        public boolean isARGB() {
263
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
264
                        ColorInterpretation ci = getColorInterpretation();
265
                        return ci.isRGBA();
266
                }
267
                return false;
268
        }
269

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

    
274
        public boolean isTimeSupported() {
275
                return false;
276
        }
277

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

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

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

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

    
347
        /**
348
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar
349
         * un objeto de este tipo.
350
         * @return RasterProvider
351
         */
352
        abstract public RasterProvider load();
353

    
354
        /**
355
         * Obtiene el ancho de la imagen
356
         * @return Ancho de la imagen
357
         */
358
        abstract public double getWidth();
359

    
360
        /**
361
         * Obtiene el ancho de la imagen
362
         * @return Ancho de la imagen
363
         */
364
        abstract public double getHeight();
365

    
366
        /**
367
         * Asigna un nuevo Extent
368
         * @param e        Extent
369
         */
370
        public abstract void setView(Extent e);
371

    
372
        /**
373
         * Obtiene el extent asignado
374
         * @return        Extent
375
         */
376
        public abstract Extent getView();
377

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

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

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

    
413
        abstract public int getBlockSize();
414

    
415
        abstract public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException;
416

    
417
        /**
418
         * Informa de si el dataset soporta overviews o no.
419
         * @return true si soporta overviews y false si no las soporta.
420
         */
421
        abstract public boolean isOverviewsSupported();
422

    
423
        public void reload() {
424
                try {
425
                        loadFromRmf(getRmfBlocksManager());
426
                } catch (ParsingException e) {
427
                        logger.debug("No se ha podido leer el RMF", e);
428
                }
429
        }
430

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

    
440
                if (!new File(manager.getPath()).exists())
441
                        return;
442

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

    
454
                manager.addClient(geoInfoSerializer);
455
                manager.addClient(colorTableSerializer);
456
                manager.addClient(gcpSerializer);
457
                manager.addClient(noDataSerializer);
458
                manager.addClient(colorInterpSerializer);
459
                manager.addClient(projectionRmfSerializer);
460
                manager.addClient(statsRmfSerializer);
461

    
462
                manager.read(null);
463

    
464
                manager.removeAllClients();
465

    
466
                if (colorTableSerializer.getResult() != null)
467
                        setColorTable((ColorTable) colorTableSerializer.getResult());
468

    
469
                if (colorInterpSerializer.getResult() != null) {
470
                        DataStoreColorInterpretation ci = (DataStoreColorInterpretation) colorInterpSerializer.getResult();
471
                        setColorInterpretation(ci);
472
                        getTransparency().setColorInterpretation(ci);
473
                        getTransparency().setTransparencyBand(ci.getBand(DataStoreColorInterpretation.ALPHA_BAND));
474
                }
475

    
476
                if (projectionRmfSerializer.getResult() != null) {
477
                        proj = (IProjection) projectionRmfSerializer.getResult();
478
                }
479

    
480
                if( gcpSerializer.getResult() != null &&
481
                        gcpSerializer.getResult() instanceof GeoPointList &&
482
                        ((GeoPointList)gcpSerializer.getResult()).size() > 0) {
483
                        setGeoPointList((GeoPointList)gcpSerializer.getResult());
484
                }
485
        }
486

    
487
        /**
488
         * Obtiene el n?mero de bandas del fichero
489
         * @return Entero que representa el n?mero de bandas
490
         */
491
        public int getBandCount() {
492
                return bandCount;
493
        }
494

    
495
        /**
496
         * @return Returns the dataType.
497
         */
498
        public int[] getDataType() {
499
                return dataType;
500
        }
501

    
502
        /**
503
         * @param dataType The dataType to set.
504
         */
505
        public void setDataType(int[] dataType) {
506
                this.dataType = dataType;
507
        }
508

    
509
        public double getPixelSizeX() {
510
                return externalTransformation.getScaleX();
511
        }
512

    
513
        public double getPixelSizeY() {
514
                return externalTransformation.getScaleY();
515
        }
516

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

    
529
        public void setNoDataValue(NoData value) {
530
                this.noData = value;
531
        }
532

    
533
        /**
534
         * Dice si el fichero tiene georreferenciaci?n o no.
535
         * @return true si tiene georreferenciaci?n y false si no la tiene
536
         */
537
        public boolean isGeoreferenced() {
538
                return true;
539
        }
540

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

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

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

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

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

    
605
        abstract public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException;
606

    
607
        public void selectSubdataset() {}
608

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

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

    
632
    public File getRMFFile() {
633
        String tail = selectedSubdatasetID == null ? ".rmf" : "-sd" + selectedSubdatasetID + ".rmf";
634
        File rmfFolder =
635
            (getDataParameters() != null && getDataParameters() instanceof RasterDataParameters)
636
                ? ((RasterDataParameters) getDataParameters()).getRMFFolder() : null;
637

    
638
        String fileName;
639

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

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

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

    
675
                Point2D pt = new Point2D.Double();
676
                try {
677

    
678
                        getAffineTransform().inverseTransform(p, pt);
679
                        if(        pt.getX() >= 0 && pt.getX() < getWidth() &&
680
                                        pt.getY() >= 0 && pt.getY() < getHeight())
681
                                return true;
682
                } catch (NoninvertibleTransformException e) {
683
                        return false;
684
                }
685

    
686
                return false;
687
        }
688

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

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

    
703
        public boolean isMosaic() {
704
                return false;
705
        }
706

    
707
        /**
708
         * Devuelve si el Dataset es reproyectable
709
         * @return true if Dataset is reproyectable
710
         */
711
        public boolean isReproyectable() {
712
                return true;
713
        }
714

    
715
        public String getWktProjection() {
716
                if(proj != null && RasterLocator.getManager().isCRSUtilSupported())
717
                        return RasterLocator.getManager().getCRSUtils().convertIProjectionToWkt((IProjection) proj);
718
                return null;
719
        }
720

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

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

    
740
                if (serializerObject == null)
741
                        throw new RmfSerializerException("No se ha podido encontrar el serializador para el Rmf");
742

    
743
                if (!blocksManager.checkRmf())
744
                        throw new RmfSerializerException("Error al comprobar el fichero Rmf");
745

    
746
                blocksManager.addClient(serializerObject);
747
                try {
748
                        blocksManager.read(null);
749
                } catch (ParsingException e) {
750
                        throw new RmfSerializerException("Error al leer el fichero Rmf", e);
751
                }
752
                blocksManager.removeAllClients();
753

    
754
                return serializerObject.getResult();
755
        }
756

    
757
        public Object loadObjectFromRmf(Class<?> class1, Object value) throws RmfSerializerException {
758
                RmfBlocksManager blocksManager = getRmfBlocksManager();
759
                if(blocksManager!=null){
760
                    return loadObjectFromRmfFile(blocksManager, class1, value);
761
                }
762
                return null;
763
        }
764

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

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

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

    
799

    
800
        public double getCellSize() {
801
                try {
802
                        Extent e = getExtent();
803
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getWidth();
804
                        return dCellsize;
805
                } catch (NullPointerException e) {
806
                        return 1;
807
                }
808
        }
809

    
810

    
811
        public RasterProvider newProvider() {
812
                return null;
813
        }
814

    
815
        public ColorTable getColorTable() {
816
                return colorTable;
817
        }
818

    
819
        public Image getImageLegend() {
820
                return null;
821
        }
822

    
823
        public void setColorTable(ColorTable value) {
824
                colorTable = value;
825
        }
826

    
827
        public Transparency getTransparency() {
828
                return transparency;
829
        }
830

    
831
        public Metadata getMetadata() {
832
                return null;
833
        }
834

    
835
        public ColorInterpretation getColorInterpretation() {
836
                return this.colorInterpretation;
837
        }
838

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

    
848
        public Statistics getStatistics() {
849
                if(stats == null) {
850
                        stats = new SimpleProviderStatistics(this);
851
                }
852
                return stats;
853
        }
854

    
855
        public void setStatistics(Statistics stats) throws RmfSerializerException {
856
                this.stats = stats;
857
                saveObjectToRmf(Statistics.class, stats);
858
        }
859

    
860
        public HistogramComputer getHistogramComputer() {
861
                if (histogram == null)
862
                        histogram = new SimpleProviderHistogramComputer(this);
863
                return histogram;
864
        }
865

    
866
    //****************************************************
867
        //*********Implementing Disposable methods************
868
        //****************************************************
869

    
870
    public void doDispose() {
871

    
872
    }
873

    
874
    //****************************************************
875
        //*****Implementing DataStoreProvider methods*********
876
        //****************************************************
877

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

    
894

    
895
        /**
896
         * Returs the DataParameters
897
         * @return the DataParameters
898
         */
899
        public RasterDataParameters getDataParameters() {
900
                if(getDataStoreParameters() instanceof RasterDataParameters)
901
                        return (RasterDataParameters)getDataStoreParameters();
902
                return null;
903
        }
904

    
905
        public Iterator<?> getChilds() {
906
                return null;
907
        }
908

    
909
        public ResourceProvider getResource() {
910
                return null;
911
        }
912

    
913
        public Object getSourceId() {
914
                if( this.getDataParameters() instanceof RasterFileStoreParameters)
915
                        return ((RasterFileStoreParameters)this.getDataParameters()).getFile();
916
                else
917
                        return this.getDataParameters().getURI();
918
        }
919

    
920
        public void open() throws OpenException {
921
        }
922

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

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

    
942

    
943
        public String getFileSuffix() {
944
                String path = new File(getURIOfFirstProvider()).getAbsolutePath();
945
        return FilenameUtils.getExtension(path);
946
        }
947

    
948
        public URI getURIOfFirstProvider() {
949
            //FIXME: Esto que lo sobreescriban los proveedores que no son de archivo
950
//                return RasterLocator.getManager().getFileUtils().getFormatedRasterFileName(uri);
951
            return getURI();
952
        }
953

    
954
        public URI getURI() {
955
                return uri;
956
        }
957

    
958
        public void setFName(String n) {
959
            File file = new File(n);
960
            uri = file.toURI();
961
        }
962

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

    
978
        public String getFullName() {
979
            if(uri!=null && "FILE".equalsIgnoreCase(uri.getScheme())){
980
                return new File(uri).getAbsolutePath();
981
            } else {
982
                return uri.toString();
983
            }
984
        }
985

    
986
        /**
987
         * Gets the size of the file if exists in Bytes
988
         * @return the size of file
989
         */
990
        public long getFileSize() {
991
                return fileSize;
992
        }
993

    
994
        public void setFileSize(long sz) {
995
                fileSize = sz;
996
        }
997

    
998
        public IProjection getProjection() {
999
                return proj;
1000
        }
1001

    
1002
        public void setProjection(IProjection proj, boolean persist) throws RmfSerializerException {
1003
                this.proj = proj;
1004
                if(persist) {
1005
                        saveObjectToRmf(IProjection.class, proj);
1006
                }
1007
        }
1008

    
1009
        protected long getTime() {
1010
                return (new Date()).getTime();
1011
        }
1012

    
1013
        public void setAffineTransform(AffineTransform t) {
1014
                externalTransformation = (AffineTransform) t.clone();
1015
        }
1016

    
1017
        public AffineTransform getAffineTransform() {
1018
                return externalTransformation;
1019
        }
1020

    
1021
        /**
1022
         * Elimina la matriz de transformaci?n asociada al raster y que se tiene en
1023
         * cuenta para el setView. Este reseteo tendr? en cuenta que si el raster
1024
         * tiene asociado un rmf esta transformaci?n no ser? eliminada sino que se
1025
         * asignar? la correspondiente al rmf existente.
1026
         */
1027
        public void resetAffineTransform() {
1028
                externalTransformation.setToIdentity();
1029
        }
1030

    
1031
        public AffineTransform getOwnAffineTransform() {
1032
                return ownTransformation;
1033
        }
1034

    
1035
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
1036
                return null;
1037
        }
1038

    
1039
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
1040
                return null;
1041
        }
1042

    
1043
        public void setTileServer(Class<?> tileServer) throws InitializeException {
1044

    
1045
        }
1046

    
1047
        public int[] getTileSize(int level) {
1048
                return new int[]{0, 0};
1049
        }
1050

    
1051
        public boolean isRasterEnclosed() {
1052
                return false;
1053
        }
1054

    
1055
        public int getSourceType() {
1056
            String scheme = getURI().getScheme();
1057
        if("PG".equalsIgnoreCase(scheme)){
1058
                   return RasterDataStore.POSTGIS;
1059
            } else if ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)) {
1060
            return RasterDataStore.REMOTE;
1061
            }
1062
        //"file".equalsIgnoreCase(scheme)
1063
                return RasterDataStore.FILE;
1064
        }
1065

    
1066
        /**
1067
         * Most of providers don't need tiles. It those cases this method
1068
         * won't execute anything. Only providers that use tile cache will need
1069
         * implement this function, for instance TileProvider and MosaicProvider.
1070
         */
1071
        public void deleteLayerFromCache() {
1072

    
1073
        }
1074

    
1075
        public TimeSeries getTimeSerials() throws RmfSerializerException {
1076
                if(serialInfo == null) {
1077
                        serialInfo =  new DefaultTimeSerials();
1078
                        loadObjectFromRmf(TimeSeries.class, serialInfo);
1079
                        //Seleccionamos la primera serie por defecto. El usuario seleccionar? otra si la necesita
1080
                        serialInfo.selectSerial(0);
1081
                }
1082
                return serialInfo;
1083
        }
1084

    
1085
        public void setTimeSerials(TimeSeries serialInfo) throws RmfSerializerException {
1086
                this.serialInfo = serialInfo;
1087
                saveObjectToRmf(TimeSeries.class, serialInfo);
1088
        }
1089

    
1090
        public long[] getFileSizeByProvider() {
1091
                return new long[]{getFileSize()};
1092
        }
1093

    
1094
        public URI[] getURIByProvider() {
1095
                //For providers with one file
1096
                return new URI[]{getURIOfFirstProvider()};
1097
        }
1098

    
1099
        public int[] getBandCountByProvider() {
1100
                return new int[]{getBandCount()};
1101
        }
1102

    
1103
        public int getInternalProviderCount() {
1104
                return 1;
1105
        }
1106

    
1107
        public RasterProvider getInternalProvider(int i) {
1108
                return this;
1109
        }
1110

    
1111
        public URI getURIByBand(int band) {
1112
                //No matter which band be selected. In providers with one file is always the first URI
1113
                return getURIOfFirstProvider();
1114
        }
1115

    
1116
        public int getBandPositionByProvider(int band) {
1117
                return band;
1118
        }
1119

    
1120
        public int getSubdatasetCount() {
1121
                return 0;
1122
        }
1123

    
1124
//        public void addFile(File file) throws InvalidSourceException {
1125
//                //Do nothing
1126
//        }
1127
//
1128
//        public void removeFile(File file) {
1129
//                //Do nothing
1130
//        }
1131

    
1132
        public boolean needEnhanced() {
1133
                return false;
1134
        }
1135

    
1136
        /**
1137
         * Gets the {@link Interval} of the store, that means the temporal
1138
         * interval where the store has valid data.
1139
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1140
         * by the provider.
1141
         * @return
1142
         *         a time interval or null if there is not time support
1143
         */
1144
        public Interval getInterval() {
1145
                return null;
1146
        }
1147

    
1148
        /**
1149
         * Gets all the possible values of time for which the store has data.
1150
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1151
         * by the provider.
1152
         * @return
1153
         *         a collection of {@link Time} objects.
1154
         */
1155
        public Collection<?> getTimes() {
1156
                return null;
1157
        }
1158

    
1159
        /**
1160
         * Gets all the possible values of time for which the store has data
1161
         * and intersects with an interval.
1162
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1163
         * by the provider.
1164
         * @param interval
1165
         *         the interval of time
1166
         * @return
1167
         *         a collection of {@link Time} objects.
1168
         */
1169
        public Collection<?> getTimes(Interval interval) {
1170
                return null;
1171
        }
1172

    
1173
        /**
1174
         * Gets the list of geo points associated to this provider
1175
         * @return the list of geo points
1176
         */
1177
        public GeoPointList getGeoPointList() {
1178
                return geoPointList;
1179
        }
1180

    
1181
        /**
1182
         * Sets the list of geo points associated to this provider
1183
         */
1184
        public void setGeoPointList(GeoPointList geoPointList) {
1185
                this.geoPointList = geoPointList;
1186
        }
1187

    
1188
        /**
1189
         * @deprecated This method should not be used. The store have a getDefaultBandList
1190
         * @return BandList
1191
         */
1192
        public BandList getDefaultBandList() {
1193
                BandList bandList = new BandListImpl();
1194
                URI[] uriByProvider = getURIByProvider();
1195
                int[] nBandsByProvider = getBandCountByProvider();
1196

    
1197
                for (int iProvider = 0; iProvider < uriByProvider.length; iProvider++) {
1198
                        for (int iBand = 0; iBand < nBandsByProvider[iProvider]; iBand++) {
1199
                                try {
1200
                    bandList.addBand(new DatasetBandImpl(
1201
                        new File(uriByProvider[iProvider]).getAbsolutePath(),
1202
                        iBand,
1203
                        getDataType()[0],
1204
                        nBandsByProvider[iProvider])
1205
                    );
1206
                                } catch (BandNotFoundInListException e1) {
1207
                                }
1208
                        }
1209
                }
1210

    
1211
                int[] drawableBands = new int[bandList.getBandCount()];
1212
                for (int i = 0; i < bandList.getBandCount(); i++) {
1213
                        drawableBands[i] = i;
1214
                }
1215

    
1216
                bandList.setDrawableBands(drawableBands);
1217
                return bandList;
1218
        }
1219

    
1220
        public void close() {
1221
                if(transparency != null)
1222
                        transparency.dispose();
1223
                try {
1224
                        finalize();
1225
                } catch (Throwable e) {
1226
                }
1227
        }
1228

    
1229
        protected void finalize() throws Throwable {
1230
                dataType               = null;
1231
                noData                 = null;
1232
                stats                  = null;
1233
                histogram              = null;
1234
                param                  = null;
1235
                storeServices          = null;
1236
                rmfBlocksManager       = null;
1237
                colorTable             = null;
1238
                colorInterpretation    = null;
1239
                serialInfo             = null;
1240
                transparency           = null;
1241
                tileServer             = null;
1242
                fileUtil               = null;
1243
                rasterUtil             = null;
1244
                proj                   = null;
1245
                uri                    = null;
1246
                selectedSubdatasetID   = null;
1247
                ownTransformation      = null;
1248
                externalTransformation = null;
1249
        }
1250
                
1251
    @Override
1252
    public UnmodifiableBasicMap<String, DataStore> getChildren() {
1253
        return null;
1254
    }
1255

    
1256
    @Override
1257
    public StoresRepository getStoresRepository() {
1258
        return null;
1259
    }
1260

    
1261
    @Override
1262
    public ResourcesStorage getResourcesStorage() {
1263
        return null;
1264
    }
1265
}