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

History | View | Annotate | Download (38.4 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
         * Flags que representan a las bandas visualizables
121
         */
122
        public static final int                   RED_BAND               = 0x01;
123
        public static final int                   GREEN_BAND             = 0x02;
124
        public static final int                   BLUE_BAND              = 0x04;
125
        public static final int                   ALPHA_BAND             = 0x08;
126

    
127
        protected int                             bandCount              = 1;
128
        private int[]                             dataType               = null;
129
        protected NoData                          noData                 = null;
130

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

    
143
        protected FileUtils                       fileUtil               = RasterLocator.getManager().getFileUtils();
144
        protected RasterUtils                     rasterUtil             = RasterLocator.getManager().getRasterUtils();
145

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

    
165
    public AbstractRasterProvider(AbstractRasterDataParameters params,
166
        DataStoreProviderServices storeServices, DynObject metadata) {
167
        super(params, storeServices, metadata);
168
        if (params.getURI() != null) {
169
            uri = params.getURI();
170
            if ("FILE".equalsIgnoreCase(params.getURI().getScheme())) {
171
                File f = new File(params.getURI());
172
                if (f.exists()) {
173
                    setFileSize(f.length());
174
                }
175
            }
176
        }
177

    
178
        ownTransformation = new AffineTransform();
179
        externalTransformation = new AffineTransform();
180
    }
181

    
182
        public AbstractRasterProvider(DataStoreParameters params,
183
                        DataStoreProviderServices storeServices, DynObject metadata) {
184
                super(params, storeServices, metadata);
185
                URI uriParam = ((RasterDataParameters)params).getURI();
186
        if(uriParam != null) {
187
            if ("FILE".equalsIgnoreCase(uriParam.getScheme())) {
188
                File f = new File(uriParam);
189
                if (f.exists())
190
                    setFileSize(f.length());
191
            }
192
                        if(params instanceof RemoteStoreParameters)
193
                                uri = translateURI(uriParam);
194
                }
195

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

    
200
        public AbstractRasterProvider(String params) {
201
                super();
202
        }
203

    
204
        public AbstractRasterProvider(URI uri) {
205
        super();
206
    }
207

    
208
        public AbstractRasterProvider() {
209
                super(null, null, null);
210
        }
211

    
212
        public String[] getFormatList() {
213
                return null;
214
        }
215

    
216
        /**
217
         * Acciones de inicilizaci?n comunes a todos los drivers.
218
         * Este m?todo debe ser llamado explicitamente por el constructor de cada driver.
219
         * Estas son acciones de inicializaci?n que se ejecutan despu?s del constructor de cada driver.
220
         * Las acciones que hayan de ser realizadas antes se definen en el constructor de RasterDataset.
221
         */
222
        protected void init() {
223
        }
224

    
225
        public boolean isRGB() {
226
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
227
                        ColorInterpretation ci = getColorInterpretation();
228
                        return ci.isRGB();
229
                }
230
                return false;
231
        }
232

    
233
        public boolean isARGB() {
234
                if(getDataType()[0] == Buffer.TYPE_BYTE) {
235
                        ColorInterpretation ci = getColorInterpretation();
236
                        return ci.isRGBA();
237
                }
238
                return false;
239
        }
240

    
241
        public boolean isTiled() {
242
                return false;
243
        }
244

    
245
        public boolean isTimeSupported() {
246
                return false;
247
        }
248

    
249
        public RasterProvider cloneProvider() throws CloneException {
250
                try {
251
                        DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
252
                        AbstractRasterProvider provider = (AbstractRasterProvider)dataManager.createProvider(storeServices, param);
253
                        //DefaultRasterProvider provider = singleDatasetInstance(storeServices, param);
254
                        // Estas van por referencia
255
                        provider.histogram = histogram;
256
                        provider.stats = stats;
257
                        return provider;
258
                } catch (ProviderNotRegisteredException e) {
259
                        e.printStackTrace();
260
                } catch (InitializeException e) {
261
                        e.printStackTrace();
262
                }
263
                return null;
264
        }
265

    
266
        /**
267
         * Factoria para abrir distintos tipos de raster.
268
         * @param fName Nombre del fichero.
269
         *
270
         * @return SingleDataset, o null si hay problemas.
271
         */
272
        @SuppressWarnings("unchecked")
273
        public static AbstractRasterProvider singleDatasetInstance(DataStoreProviderServices storeServices, String param) throws RasterDriverException {
274
                DataManagerProviderServices dataManager = (DataManagerProviderServices)DALLocator.getDataManager();
275
                //We have to locate a provider's name which manages the selected file
276
                //A FilesystemServerExplorer will give a getProviderNames service
277

    
278
                FilesystemServerExplorer serverExplorer = null;
279
                try {
280
                        FilesystemServerExplorerParameters paramsExplorer = (FilesystemServerExplorerParameters)dataManager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
281
                        paramsExplorer.setRoot(File.separator);
282
                        serverExplorer = (FilesystemServerExplorer)dataManager.openServerExplorer(FilesystemServerExplorer.NAME, paramsExplorer);
283
                } catch (ValidateDataParametersException e) {
284
                        throw new RasterDriverException("Error validating parameters", e);
285
                } catch (InitializeException e) {
286
                        throw new RasterDriverException("Error creating a server explorer ", e);
287
                } catch (ProviderNotRegisteredException e) {
288
                        throw new RasterDriverException("Provider not registered", e);
289
                }
290

    
291
                //Gets the list of provider's name to manage the file
292
                File file = new File(param);
293
                List<String> provName = serverExplorer.getProviderNameList(file);
294
                if(provName.size() > 0) {
295
                        for (int i = 0; i < provName.size(); i++) {
296
                                //Gets the first provider what is not a TileProvider
297
                                if(provName.get(i).compareTo("Tile Store") != 0) {
298
                                        DataStoreParameters newparams;
299
                                        try {
300
                                                newparams = dataManager.createStoreParameters(provName.get(i));
301
                                                ((FilesystemStoreParameters)newparams).setFile(file);
302
                                                if(storeServices == null)
303
                                                        storeServices = new DefaultRasterStore();
304
                                                return (AbstractRasterProvider)dataManager.createProvider(storeServices, newparams);
305
                                        } catch (InitializeException e) {
306
                                                throw new RasterDriverException("Error creating a server explorer ", e);
307
                                        } catch (ProviderNotRegisteredException e) {
308
                                                throw new RasterDriverException("Provider not registered", e);
309
                                        }
310
                                }
311
                        }
312
                }
313
                return null;
314
        }
315

    
316
        /**
317
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar
318
         * un objeto de este tipo.
319
         */
320
        abstract public RasterProvider load();
321

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

    
328
        /**
329
         * Obtiene el ancho de la imagen
330
         * @return Ancho de la imagen
331
         */
332
        abstract public double getHeight();
333

    
334
        /**
335
         * Asigna un nuevo Extent
336
         * @param e        Extent
337
         */
338
        public abstract void setView(Extent e);
339

    
340
        /**
341
         * Obtiene el extent asignado
342
         * @return        Extent
343
         */
344
        public abstract Extent getView();
345

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

    
356
        /**
357
         * Gets the set of data selected in the {@link RasterQuery}
358
         * @param q
359
         * @return
360
         * @throws RasterDriverException
361
         * @throws ProcessInterruptedException
362
         */
363
        public Buffer getDataSet(SpiRasterQuery query) throws ProcessInterruptedException, RasterDriverException {
364
                SpiRasterQuery q = (SpiRasterQuery)query;
365
                loadBuffer(q);
366
                return q.getBufferForProviders();
367
        }
368

    
369
        /**
370
         * Load a buffer with the parameters. The buffer should already have been created
371
         * inside the query structure <code>SpiRasterQuery</code> by the <code>RasterDataStore</code>. The other
372
         * parameters have been calculated too, all of them adjusted to the raster limits. The provider only
373
         * have to read the parameters and load the buffer.
374
         *
375
         * @param query
376
         * @throws ProcessInterruptedException
377
         * @throws RasterDriverException
378
         */
379
        abstract public void loadBuffer(SpiRasterQuery query) throws ProcessInterruptedException, RasterDriverException;
380

    
381
        abstract public int getBlockSize();
382

    
383
        abstract public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException;
384

    
385
        /**
386
         * Informa de si el dataset soporta overviews o no.
387
         * @return true si soporta overviews y false si no las soporta.
388
         */
389
        abstract public boolean isOverviewsSupported();
390

    
391
        public void reload() {
392
                try {
393
                        loadFromRmf(getRmfBlocksManager());
394
                } catch (ParsingException e) {
395
                        logger.debug("No se ha podido leer el RMF", e);
396
                }
397
        }
398

    
399
        /**
400
         * Carga metadatos desde el fichero Rmf si estos existen
401
         * @param fName Nombre del fichero
402
         * @throws ParsingException
403
         */
404
        protected void loadFromRmf(RmfBlocksManager manager) throws ParsingException {
405
                if (!manager.checkRmf())
406
                        return;
407

    
408
                if (!new File(manager.getPath()).exists())
409
                        return;
410

    
411
                GeoInfoRmfSerializer geoInfoSerializer = new GeoInfoRmfSerializer(this);
412
                ColorTableRmfSerializer colorTableSerializer = new ColorTableRmfSerializer();
413
                GeoPointListRmfSerializer gcpSerializer = new GeoPointListRmfSerializer();
414
                NoDataRmfSerializer noDataSerializer = null;
415
                if(noData == null)
416
                        noData = new DefaultNoData(null, null, manager.getPath(), getBandCount());
417
                noDataSerializer = new NoDataRmfSerializer((DefaultNoData)noData);
418
                ColorInterpretationRmfSerializer colorInterpSerializer = new ColorInterpretationRmfSerializer();
419
                ProjectionRmfSerializer projectionRmfSerializer = new ProjectionRmfSerializer();
420
                StatisticsRmfSerializer statsRmfSerializer = new StatisticsRmfSerializer(getStatistics());
421

    
422
                manager.addClient(geoInfoSerializer);
423
                manager.addClient(colorTableSerializer);
424
                manager.addClient(gcpSerializer);
425
                manager.addClient(noDataSerializer);
426
                manager.addClient(colorInterpSerializer);
427
                manager.addClient(projectionRmfSerializer);
428
                manager.addClient(statsRmfSerializer);
429

    
430
                manager.read(null);
431

    
432
                manager.removeAllClients();
433

    
434
                if (colorTableSerializer.getResult() != null)
435
                        setColorTable((ColorTable) colorTableSerializer.getResult());
436

    
437
                if (colorInterpSerializer.getResult() != null) {
438
                        DataStoreColorInterpretation ci = (DataStoreColorInterpretation) colorInterpSerializer.getResult();
439
                        setColorInterpretation(ci);
440
                        getTransparency().setColorInterpretation(ci);
441
                        getTransparency().setTransparencyBand(ci.getBand(DataStoreColorInterpretation.ALPHA_BAND));
442
                }
443

    
444
                if (projectionRmfSerializer.getResult() != null) {
445
                        proj = (IProjection) projectionRmfSerializer.getResult();
446
                }
447

    
448
                if( gcpSerializer.getResult() != null &&
449
                        gcpSerializer.getResult() instanceof GeoPointList &&
450
                        ((GeoPointList)gcpSerializer.getResult()).size() > 0) {
451
                        setGeoPointList((GeoPointList)gcpSerializer.getResult());
452
                }
453
        }
454

    
455
        /**
456
         * Obtiene el n?mero de bandas del fichero
457
         * @return Entero que representa el n?mero de bandas
458
         */
459
        public int getBandCount() {
460
                return bandCount;
461
        }
462

    
463
        /**
464
         * @return Returns the dataType.
465
         */
466
        public int[] getDataType() {
467
                return dataType;
468
        }
469

    
470
        /**
471
         * @param dataType The dataType to set.
472
         */
473
        public void setDataType(int[] dataType) {
474
                this.dataType = dataType;
475
        }
476

    
477
        public double getPixelSizeX() {
478
                return externalTransformation.getScaleX();
479
        }
480

    
481
        public double getPixelSizeY() {
482
                return externalTransformation.getScaleY();
483
        }
484

    
485
        public NoData getNoDataValue() {
486
                if(noData == null) {
487
                        noData = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(getBandCount(), getDataType()[0]);
488
                        noData.setNoDataTransparent(false);
489
                        noData.setFileName(getRMFFile().getName());
490
                }
491
                return noData;
492
        }
493

    
494
        public void setNoDataValue(NoData value) {
495
                this.noData = value;
496
        }
497

    
498
        /**
499
         * Dice si el fichero tiene georreferenciaci?n o no.
500
         * @return true si tiene georreferenciaci?n y false si no la tiene
501
         */
502
        public boolean isGeoreferenced() {
503
                return true;
504
        }
505

    
506
        /**
507
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
508
         * @param pt Punto a transformar
509
         * @return punto transformado en coordenadas del mundo
510
         */
511
        public Point2D rasterToWorld(Point2D pt) {
512
                Point2D p = new Point2D.Double();
513
                externalTransformation.transform(pt, p);
514
                return p;
515
        }
516

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

    
532
        /**
533
         * Calcula el extent en coordenadas del mundo real
534
         * @return Extent
535
         */
536
        public Extent getExtent() {
537
                return new ExtentImpl(        rasterToWorld(new Point2D.Double(0, 0)),
538
                                                        rasterToWorld(new Point2D.Double(getWidth(), getHeight())),
539
                                                        rasterToWorld(new Point2D.Double(getWidth(), 0)),
540
                                                        rasterToWorld(new Point2D.Double(0, getHeight())));
541
        }
542

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

    
558
        /**
559
         * Asigna el par?metro de inicializaci?n del driver.
560
         */
561
        public void setParam(DataStoreProviderServices provServices, DataStoreParameters param) {
562
                if(param instanceof RasterDataParameters)
563
                        this.uri = ((RasterDataParameters)param).getURI();
564
                this.param = param;
565
                this.storeServices = provServices;
566
        }
567

    
568
        abstract public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException;
569

    
570
        public void selectSubdataset() {}
571

    
572
        /**
573
         * Selects the subdataset. This method will select
574
         * the rmf file.
575
         */
576
        protected void selectSubdataset(String subdataset) {
577
                selectedSubdatasetID = subdataset;
578
                getRmfBlocksManager().setPath(getRMFFile().getPath());
579
        }
580

    
581
        /**
582
         * Obtiene el gestor de ficheros RMF
583
         * @return RmfBloksManager
584
         */
585
        public RmfBlocksManager getRmfBlocksManager() {
586
                File fileRMF = getRMFFile();
587
                if(fileRMF != null) {
588
                        if (rmfBlocksManager == null || !fileRMF.equals(rmfBlocksManager)) {
589
                                rmfBlocksManager = new RmfBlocksManager(fileRMF.getPath());
590
                        }
591
                }
592
                return rmfBlocksManager;
593
        }
594

    
595
    public File getRMFFile() {
596
        String tail = selectedSubdatasetID == null ? ".rmf" : "-sd" + selectedSubdatasetID + ".rmf";
597
        File rmfFolder =
598
            (getDataParameters() != null && getDataParameters() instanceof RasterDataParameters)
599
                ? ((RasterDataParameters) getDataParameters()).getRMFFolder() : null;
600

    
601
        String fileName;
602

    
603
        URI objUri = getURI();
604
        File file;
605
        if ("FILE".equalsIgnoreCase(objUri.getScheme())) {
606
            file = new File(objUri);
607
            fileName = FilenameUtils.getBaseName(objUri.getPath());
608
        } else {
609
            file = new File(objUri.getHost());
610
            fileName = FilenameUtils.getBaseName(objUri.getHost());
611
        }
612
        if (rmfFolder == null) {
613
            rmfFolder = file.getParentFile();
614
            if ((getDataParameters() != null && getDataParameters() instanceof RasterDataParameters)) {
615
                ((RasterDataParameters) getDataParameters()).setRMFFolder(rmfFolder);
616
            }
617
            return new File(fileName + tail);
618
        } else {
619
            return new File(rmfFolder.getAbsolutePath() + File.separator + fileName + tail);
620
        }
621
    }
622

    
623
        protected String getRMFFileForRemoteServices(String layerName) {
624
                String md5 = "";
625
                try {
626
                        md5 = RasterLocator.getManager().getFileUtils().convertPathToMD5(uri.getPath());
627
                } catch (LocatorException e) {
628
                        logger.debug("Error getting the Locator", e);
629
                } catch (NoSuchAlgorithmException e) {
630
                        logger.debug("Error getting the algorithm MD5", e);
631
                }
632
                File path = new File(RasterLibrary.pathRMFRemote);
633
                if(!path.exists())
634
                        path.mkdir();
635
                return RasterLibrary.pathRMFRemote + File.separator + md5 + "-" + layerName + ".rmf";
636
        }
637

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

    
642
                Point2D pt = new Point2D.Double();
643
                try {
644

    
645
                        getAffineTransform().inverseTransform(p, pt);
646
                        if(        pt.getX() >= 0 && pt.getX() < getWidth() &&
647
                                        pt.getY() >= 0 && pt.getY() < getHeight())
648
                                return true;
649
                } catch (NoninvertibleTransformException e) {
650
                        return false;
651
                }
652

    
653
                return false;
654
        }
655

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

    
666
        public boolean isMultiFile() {
667
                return false;
668
        }
669

    
670
        public boolean isMosaic() {
671
                return false;
672
        }
673

    
674
        /**
675
         * Devuelve si el Dataset es reproyectable
676
         * @return
677
         */
678
        public boolean isReproyectable() {
679
                return true;
680
        }
681

    
682
        public String getWktProjection() {
683
                if(proj != null && RasterLocator.getManager().isCRSUtilSupported())
684
                        return RasterLocator.getManager().getCRSUtils().convertIProjectionToWkt((IProjection) proj);
685
                return null;
686
        }
687

    
688
        public void saveObjectToRmf(Class<?> class1, Object value) throws RmfSerializerException {
689
        if (getRmfBlocksManager() != null) {
690
            ((DefaultProviderServices) RasterLocator.getManager().getProviderServices()).saveObjectToRmfFile(
691
                getRmfBlocksManager(), class1, value);
692
        }
693
        }
694

    
695
        /**
696
         * Carga un objecto desde un serializador del tipo class1. Usa value para iniciar dicho
697
         * serializador
698
         *
699
         * @param class1
700
         * @param value
701
         * @return
702
         * @throws RmfSerializerException
703
         */
704
        private static Object loadObjectFromRmfFile(RmfBlocksManager blocksManager, Class<?> class1, Object value) throws RmfSerializerException {
705
                ClassSerializer serializerObject = ((DefaultProviderServices)RasterLocator.getManager().getProviderServices()).getSerializerObject(class1, value);
706

    
707
                if (serializerObject == null)
708
                        throw new RmfSerializerException("No se ha podido encontrar el serializador para el Rmf");
709

    
710
                if (!blocksManager.checkRmf())
711
                        throw new RmfSerializerException("Error al comprobar el fichero Rmf");
712

    
713
                blocksManager.addClient(serializerObject);
714
                try {
715
                        blocksManager.read(null);
716
                } catch (ParsingException e) {
717
                        throw new RmfSerializerException("Error al leer el fichero Rmf", e);
718
                }
719
                blocksManager.removeAllClients();
720

    
721
                return serializerObject.getResult();
722
        }
723

    
724
        public Object loadObjectFromRmf(Class<?> class1, Object value) throws RmfSerializerException {
725
                RmfBlocksManager blocksManager = getRmfBlocksManager();
726
                if(blocksManager!=null){
727
                    return loadObjectFromRmfFile(blocksManager, class1, value);
728
                }
729
                return null;
730
        }
731

    
732
        /**
733
         * Carga un objeto del fichero RMF especificado por parametro
734
         * @param file
735
         * @param class1
736
         * @param value
737
         * @return
738
         * @throws RmfSerializerException
739
         */
740
        public static Object loadObjectFromRmfFile(String file, Class<?> class1, Object value) throws RmfSerializerException {
741
                String fileRMF = RasterLocator.getManager().getFileUtils().getNameWithoutExtension(file) + ".rmf";
742
                RmfBlocksManager blocksManager = new RmfBlocksManager(fileRMF);
743
                return loadObjectFromRmfFile(blocksManager, class1, value);
744
        }
745

    
746
        /**
747
         * Guarda en el RMF el objecto actual en caso de que exista un serializador para el
748
         * @param value
749
         * @throws RmfSerializerException
750
         */
751
        public void saveObjectToRmf(Object value) throws RmfSerializerException {
752
                saveObjectToRmf(value.getClass(), value);
753
        }
754

    
755
        /**
756
         * Carga un objecto desde un serializador usando el tipo del mismo objeto pasado por parametro.
757
         * Usa value para iniciar dicho serializador
758
         * @param value
759
         * @return
760
         * @throws RmfSerializerException
761
         */
762
        public Object loadObjectFromRmf(Object value) throws RmfSerializerException {
763
                return loadObjectFromRmf(value.getClass(), value);
764
        }
765

    
766

    
767
        public double getCellSize() {
768
                try {
769
                        Extent e = getExtent();
770
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getWidth();
771
                        return dCellsize;
772
                } catch (NullPointerException e) {
773
                        return 1;
774
                }
775
        }
776

    
777

    
778
        public RasterProvider newProvider() {
779
                return null;
780
        }
781

    
782
        public ColorTable getColorTable() {
783
                return colorTable;
784
        }
785

    
786
        public Image getImageLegend() {
787
                return null;
788
        }
789

    
790
        public void setColorTable(ColorTable value) {
791
                colorTable = value;
792
        }
793

    
794
        public Transparency getTransparency() {
795
                return transparency;
796
        }
797

    
798
        public Metadata getMetadata() {
799
                return null;
800
        }
801

    
802
        public ColorInterpretation getColorInterpretation() {
803
                return this.colorInterpretation;
804
        }
805

    
806
        /**
807
         * Asigna el objeto que contiene que contiene la interpretaci?n de
808
         * color por banda
809
         * @param DataStoreColorInterpretation
810
         */
811
        public void setColorInterpretation(ColorInterpretation colorInterpretation) {
812
                this.colorInterpretation = colorInterpretation;
813
        }
814

    
815
        public Statistics getStatistics() {
816
                if(stats == null) {
817
                        stats = new SimpleProviderStatistics(this);
818
                }
819
                return stats;
820
        }
821

    
822
        public void setStatistics(Statistics stats) throws RmfSerializerException {
823
                this.stats = stats;
824
                saveObjectToRmf(Statistics.class, stats);
825
        }
826

    
827
        public HistogramComputer getHistogramComputer() {
828
                if (histogram == null)
829
                        histogram = new SimpleProviderHistogramComputer(this);
830
                return histogram;
831
        }
832

    
833
    //****************************************************
834
        //*********Implementing Disposable methods************
835
        //****************************************************
836

    
837
    public void doDispose() {
838

    
839
    }
840

    
841
    //****************************************************
842
        //*****Implementing DataStoreProvider methods*********
843
        //****************************************************
844

    
845
        @Override
846
        public DataServerExplorer getExplorer() throws ReadException,
847
                        ValidateDataParametersException {
848
            /*DataManager manager = DALLocator.getDataManager();
849
                FilesystemServerExplorerParameters params;
850
                try {
851
                        params = (FilesystemServerExplorerParameters) manager
852
                                        .createServerExplorerParameters(FilesystemServerExplorer.NAME);
853
                        params.setRoot(((AbstractRasterStoreParameters)this.getDataParameters()).getFile().getParent());
854
                        return manager.createServerExplorer(params);
855
                } catch (DataException e) {
856
                        throw new ReadException(this.getName(), e);
857
                }*/
858
            return null;
859
        }
860

    
861

    
862
        /**
863
         * Returs the DataParameters
864
         * @return
865
         */
866
        public RasterDataParameters getDataParameters() {
867
                if(getDataStoreParameters() instanceof RasterDataParameters)
868
                        return (RasterDataParameters)getDataStoreParameters();
869
                return null;
870
        }
871

    
872
        public Iterator<?> getChilds() {
873
                return null;
874
        }
875

    
876
        public ResourceProvider getResource() {
877
                return null;
878
        }
879

    
880
        public Object getSourceId() {
881
                if( this.getDataParameters() instanceof RasterFileStoreParameters)
882
                        return ((RasterFileStoreParameters)this.getDataParameters()).getFile();
883
                else
884
                        return this.getDataParameters().getURI();
885
        }
886

    
887
        public void open() throws OpenException {
888
        }
889

    
890
        /**
891
         * Traduce el nombre del fichero por un alias asignado por el propio driver.
892
         * Cuando es traducido por un alias el driver intentar? abrir el alias y no el
893
         * fichero. Esto es util porque algunos formatos tienen la extensi?n en el
894
         * fichero de cabecera pero lo que se abre realmente es el fichero de datos.
895
         * @param fileName
896
         * @return
897
         */
898
        public URI translateURI(URI uri) {
899
            return uri;
900
        }
901

    
902
        /*
903
         * Si alguna subclase necesita sobreescribir este m?todo, deber? hacerlo con el translateURI en lugar de este.
904
         */
905
        public final String translateFileName(String fileName) {
906
                return fileName;
907
        }
908

    
909

    
910
        public String getFileSuffix() {
911
            //FIXME: ?Sirve para algo?
912
                String path = getURIOfFirstProvider().getPath();
913
        return path.substring(path.lastIndexOf(".") + 1, path.length());
914
        }
915

    
916
        public URI getURIOfFirstProvider() {
917
            //FIXME: Esto que lo sobreescriban los proveedores que no son de archivo
918
//                return RasterLocator.getManager().getFileUtils().getFormatedRasterFileName(uri);
919
            return getURI();
920
        }
921

    
922
        public URI getURI() {
923
                return uri;
924
        }
925

    
926
        public void setFName(String n) {
927
            File file = new File(n);
928
            uri = file.toURI();
929
        }
930

    
931
    public String getName() {
932
        String pathName = null;
933
        try {
934
            URI x = this.getURI();
935
            pathName = x.getPath();
936
            return FilenameUtils.getBaseName(pathName);
937
        } catch (Throwable th1) {
938
            try {
939
                return FilenameUtils.getBaseName(this.uri.getPath());
940
            } catch (Throwable th2) {
941
                return this.uri.getPath();
942
            }
943
        }
944
    }
945

    
946
        public String getFullName() {
947
                return uri.getPath();
948
        }
949

    
950
        /**
951
         * Gets the size of the file if exists in Bytes
952
         * @return
953
         */
954
        public long getFileSize() {
955
                return fileSize;
956
        }
957

    
958
        public void setFileSize(long sz) {
959
                fileSize = sz;
960
        }
961

    
962
        public IProjection getProjection() {
963
                return proj;
964
        }
965

    
966
        public void setProjection(IProjection proj, boolean persist) throws RmfSerializerException {
967
                this.proj = proj;
968
                if(persist) {
969
                        saveObjectToRmf(IProjection.class, proj);
970
                }
971
        }
972

    
973
        protected long getTime() {
974
                return (new Date()).getTime();
975
        }
976

    
977
        public void setAffineTransform(AffineTransform t) {
978
                externalTransformation = (AffineTransform) t.clone();
979
        }
980

    
981
        public AffineTransform getAffineTransform() {
982
                return externalTransformation;
983
        }
984

    
985
        /**
986
         * Elimina la matriz de transformaci?n asociada al raster y que se tiene en
987
         * cuenta para el setView. Este reseteo tendr? en cuenta que si el raster
988
         * tiene asociado un rmf esta transformaci?n no ser? eliminada sino que se
989
         * asignar? la correspondiente al rmf existente.
990
         * @return devuelve true si tiene fichero rmf asociado y false si no lo tiene.
991
         */
992
        public void resetAffineTransform() {
993
                externalTransformation.setToIdentity();
994
        }
995

    
996
        public AffineTransform getOwnAffineTransform() {
997
                return ownTransformation;
998
        }
999

    
1000
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
1001
                return null;
1002
        }
1003

    
1004
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
1005
                return null;
1006
        }
1007

    
1008
        public void setTileServer(Class<?> tileServer) throws InitializeException {
1009

    
1010
        }
1011

    
1012
        public int[] getTileSize(int level) {
1013
                return new int[]{0, 0};
1014
        }
1015

    
1016
        public boolean isRasterEnclosed() {
1017
                return false;
1018
        }
1019

    
1020
        public int getSourceType() {
1021
            String scheme = getURI().getScheme();
1022
        if("PG".equalsIgnoreCase(scheme)){
1023
                   return RasterDataStore.POSTGIS;
1024
            } else if ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)) {
1025
            return RasterDataStore.REMOTE;
1026
            }
1027
        //"file".equalsIgnoreCase(scheme)
1028
                return RasterDataStore.FILE;
1029
        }
1030

    
1031
        /**
1032
         * Most of providers don't need tiles. It those cases this method
1033
         * won't execute anything. Only providers that use tile cache will need
1034
         * implement this function, for instance TileProvider and MosaicProvider.
1035
         */
1036
        public void deleteLayerFromCache() {
1037

    
1038
        }
1039

    
1040
        public TimeSeries getTimeSerials() throws RmfSerializerException {
1041
                if(serialInfo == null) {
1042
                        serialInfo =  new DefaultTimeSerials();
1043
                        loadObjectFromRmf(TimeSeries.class, serialInfo);
1044
                        //Seleccionamos la primera serie por defecto. El usuario seleccionar? otra si la necesita
1045
                        serialInfo.selectSerial(0);
1046
                }
1047
                return serialInfo;
1048
        }
1049

    
1050
        public void setTimeSerials(TimeSeries serialInfo) throws RmfSerializerException {
1051
                this.serialInfo = serialInfo;
1052
                saveObjectToRmf(TimeSeries.class, serialInfo);
1053
        }
1054

    
1055
        public long[] getFileSizeByProvider() {
1056
                return new long[]{getFileSize()};
1057
        }
1058

    
1059
        public URI[] getURIByProvider() {
1060
                //For providers with one file
1061
                return new URI[]{getURIOfFirstProvider()};
1062
        }
1063

    
1064
        public int[] getBandCountByProvider() {
1065
                return new int[]{getBandCount()};
1066
        }
1067

    
1068
        public int getInternalProviderCount() {
1069
                return 1;
1070
        }
1071

    
1072
        public RasterProvider getInternalProvider(int i) {
1073
                return this;
1074
        }
1075

    
1076
        public URI getURIByBand(int band) {
1077
                //No matter which band be selected. In providers with one file is always the first URI
1078
                return getURIOfFirstProvider();
1079
        }
1080

    
1081
        public int getBandPositionByProvider(int band) {
1082
                return band;
1083
        }
1084

    
1085
        public int getSubdatasetCount() {
1086
                return 0;
1087
        }
1088

    
1089
//        public void addFile(File file) throws InvalidSourceException {
1090
//                //Do nothing
1091
//        }
1092
//
1093
//        public void removeFile(File file) {
1094
//                //Do nothing
1095
//        }
1096

    
1097
        public boolean needEnhanced() {
1098
                return false;
1099
        }
1100

    
1101
        /**
1102
         * Gets the {@link Interval} of the store, that means the temporal
1103
         * interval where the store has valid data.
1104
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1105
         * by the provider.
1106
         * @return
1107
         *         a time interval or null if there is not time support
1108
         */
1109
        public Interval getInterval() {
1110
                return null;
1111
        }
1112

    
1113
        /**
1114
         * Gets all the possible values of time for which the store has data.
1115
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1116
         * by the provider.
1117
         * @return
1118
         *         a collection of {@link Time} objects.
1119
         */
1120
        public Collection<?> getTimes() {
1121
                return null;
1122
        }
1123

    
1124
        /**
1125
         * Gets all the possible values of time for which the store has data
1126
         * and intersects with an interval.
1127
         * In raster this method has sense in a mosaic. Therefore this has to be implemented
1128
         * by the provider.
1129
         * @param interval
1130
         *         the interval of time
1131
         * @return
1132
         *         a collection of {@link Time} objects.
1133
         */
1134
        public Collection<?> getTimes(Interval interval) {
1135
                return null;
1136
        }
1137

    
1138
        /**
1139
         * Gets the list of geo points associated to this provider
1140
         * @return
1141
         */
1142
        public GeoPointList getGeoPointList() {
1143
                return geoPointList;
1144
        }
1145

    
1146
        /**
1147
         * Sets the list of geo points associated to this provider
1148
         */
1149
        public void setGeoPointList(GeoPointList geoPointList) {
1150
                this.geoPointList = geoPointList;
1151
        }
1152

    
1153
        /**
1154
         * @deprecated This method should not be used. The store have a getDefaultBandList
1155
         * @return
1156
         */
1157
        public BandList getDefaultBandList() {
1158
                BandList bandList = new BandListImpl();
1159
                URI[] uriByProvider = getURIByProvider();
1160
                int[] nBandsByProvider = getBandCountByProvider();
1161

    
1162
                for (int iProvider = 0; iProvider < uriByProvider.length; iProvider++) {
1163
                        for (int iBand = 0; iBand < nBandsByProvider[iProvider]; iBand++) {
1164
                                try {
1165
                                        bandList.addBand(new DatasetBandImpl(uriByProvider[iProvider].getPath(), iBand, getDataType()[0], nBandsByProvider[iProvider]));
1166
                                } catch (BandNotFoundInListException e1) {
1167
                                }
1168
                        }
1169
                }
1170

    
1171
                int[] drawableBands = new int[bandList.getBandCount()];
1172
                for (int i = 0; i < bandList.getBandCount(); i++) {
1173
                        drawableBands[i] = i;
1174
                }
1175

    
1176
                bandList.setDrawableBands(drawableBands);
1177
                return bandList;
1178
        }
1179

    
1180
        public void close() {
1181
                if(transparency != null)
1182
                        transparency.dispose();
1183
                try {
1184
                        finalize();
1185
                } catch (Throwable e) {
1186
                }
1187
        }
1188

    
1189
        protected void finalize() throws Throwable {
1190
                dataType               = null;
1191
                noData                 = null;
1192
                stats                  = null;
1193
                histogram              = null;
1194
                param                  = null;
1195
                storeServices          = null;
1196
                rmfBlocksManager       = null;
1197
                colorTable             = null;
1198
                colorInterpretation    = null;
1199
                serialInfo             = null;
1200
                transparency           = null;
1201
                tileServer             = null;
1202
                fileUtil               = null;
1203
                rasterUtil             = null;
1204
                proj                   = null;
1205
                uri                    = null;
1206
                selectedSubdatasetID   = null;
1207
                ownTransformation      = null;
1208
                externalTransformation = null;
1209
        }
1210
}