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

History | View | Annotate | Download (38.5 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
            uri = translateURI(uri);
177
        }
178

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
319
        /**
320
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar
321
         * un objeto de este tipo.
322
         * @return RasterProvider
323
         */
324
        abstract public RasterProvider load();
325

    
326
        /**
327
         * Obtiene el ancho de la imagen
328
         * @return Ancho de la imagen
329
         */
330
        abstract public double getWidth();
331

    
332
        /**
333
         * Obtiene el ancho de la imagen
334
         * @return Ancho de la imagen
335
         */
336
        abstract public double getHeight();
337

    
338
        /**
339
         * Asigna un nuevo Extent
340
         * @param e        Extent
341
         */
342
        public abstract void setView(Extent e);
343

    
344
        /**
345
         * Obtiene el extent asignado
346
         * @return        Extent
347
         */
348
        public abstract Extent getView();
349

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

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

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

    
385
        abstract public int getBlockSize();
386

    
387
        abstract public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException;
388

    
389
        /**
390
         * Informa de si el dataset soporta overviews o no.
391
         * @return true si soporta overviews y false si no las soporta.
392
         */
393
        abstract public boolean isOverviewsSupported();
394

    
395
        public void reload() {
396
                try {
397
                        loadFromRmf(getRmfBlocksManager());
398
                } catch (ParsingException e) {
399
                        logger.debug("No se ha podido leer el RMF", e);
400
                }
401
        }
402

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

    
412
                if (!new File(manager.getPath()).exists())
413
                        return;
414

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

    
426
                manager.addClient(geoInfoSerializer);
427
                manager.addClient(colorTableSerializer);
428
                manager.addClient(gcpSerializer);
429
                manager.addClient(noDataSerializer);
430
                manager.addClient(colorInterpSerializer);
431
                manager.addClient(projectionRmfSerializer);
432
                manager.addClient(statsRmfSerializer);
433

    
434
                manager.read(null);
435

    
436
                manager.removeAllClients();
437

    
438
                if (colorTableSerializer.getResult() != null)
439
                        setColorTable((ColorTable) colorTableSerializer.getResult());
440

    
441
                if (colorInterpSerializer.getResult() != null) {
442
                        DataStoreColorInterpretation ci = (DataStoreColorInterpretation) colorInterpSerializer.getResult();
443
                        setColorInterpretation(ci);
444
                        getTransparency().setColorInterpretation(ci);
445
                        getTransparency().setTransparencyBand(ci.getBand(DataStoreColorInterpretation.ALPHA_BAND));
446
                }
447

    
448
                if (projectionRmfSerializer.getResult() != null) {
449
                        proj = (IProjection) projectionRmfSerializer.getResult();
450
                }
451

    
452
                if( gcpSerializer.getResult() != null &&
453
                        gcpSerializer.getResult() instanceof GeoPointList &&
454
                        ((GeoPointList)gcpSerializer.getResult()).size() > 0) {
455
                        setGeoPointList((GeoPointList)gcpSerializer.getResult());
456
                }
457
        }
458

    
459
        /**
460
         * Obtiene el n?mero de bandas del fichero
461
         * @return Entero que representa el n?mero de bandas
462
         */
463
        public int getBandCount() {
464
                return bandCount;
465
        }
466

    
467
        /**
468
         * @return Returns the dataType.
469
         */
470
        public int[] getDataType() {
471
                return dataType;
472
        }
473

    
474
        /**
475
         * @param dataType The dataType to set.
476
         */
477
        public void setDataType(int[] dataType) {
478
                this.dataType = dataType;
479
        }
480

    
481
        public double getPixelSizeX() {
482
                return externalTransformation.getScaleX();
483
        }
484

    
485
        public double getPixelSizeY() {
486
                return externalTransformation.getScaleY();
487
        }
488

    
489
        public NoData getNoDataValue() {
490
                if(noData == null) {
491
                        noData = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(getBandCount(), getDataType()[0]);
492
                        noData.setNoDataTransparent(false);
493
                        File rmfFile = getRMFFile();
494
                        if(rmfFile!=null){
495
                            noData.setFileName(rmfFile.getName());
496
                        }
497
                }
498
                return noData;
499
        }
500

    
501
        public void setNoDataValue(NoData value) {
502
                this.noData = value;
503
        }
504

    
505
        /**
506
         * Dice si el fichero tiene georreferenciaci?n o no.
507
         * @return true si tiene georreferenciaci?n y false si no la tiene
508
         */
509
        public boolean isGeoreferenced() {
510
                return true;
511
        }
512

    
513
        /**
514
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
515
         * @param pt Punto a transformar
516
         * @return punto transformado en coordenadas del mundo
517
         */
518
        public Point2D rasterToWorld(Point2D pt) {
519
                Point2D p = new Point2D.Double();
520
                externalTransformation.transform(pt, p);
521
                return p;
522
        }
523

    
524
        /**
525
         * Convierte un punto desde del mundo a coordenadas pixel.
526
         * @param pt Punto a transformar
527
         * @return punto transformado en coordenadas pixel
528
         */
529
        public Point2D worldToRaster(Point2D pt) {
530
                Point2D p = new Point2D.Double();
531
                try {
532
                        externalTransformation.inverseTransform(pt, p);
533
                } catch (NoninvertibleTransformException e) {
534
                        return pt;
535
                }
536
                return p;
537
        }
538

    
539
        /**
540
         * Calcula el extent en coordenadas del mundo real
541
         * @return Extent
542
         */
543
        public Extent getExtent() {
544
                return new ExtentImpl(        rasterToWorld(new Point2D.Double(0, 0)),
545
                                                        rasterToWorld(new Point2D.Double(getWidth(), getHeight())),
546
                                                        rasterToWorld(new Point2D.Double(getWidth(), 0)),
547
                                                        rasterToWorld(new Point2D.Double(0, getHeight())));
548
        }
549

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

    
565
        /**
566
         * Asigna el par?metro de inicializaci?n del driver.
567
         * @param provServices
568
         * @param param
569
         */
570
        public void setParam(DataStoreProviderServices provServices, DataStoreParameters param) {
571
                if(param instanceof RasterDataParameters)
572
                        this.uri = ((RasterDataParameters)param).getURI();
573
                this.param = param;
574
                this.storeServices = provServices;
575
        }
576

    
577
        abstract public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException;
578

    
579
        public void selectSubdataset() {}
580

    
581
        /**
582
         * Selects the subdataset. This method will select
583
         * the rmf file.
584
         */
585
        protected void selectSubdataset(String subdataset) {
586
                selectedSubdatasetID = subdataset;
587
                getRmfBlocksManager().setPath(getRMFFile().getPath());
588
        }
589

    
590
        /**
591
         * Obtiene el gestor de ficheros RMF
592
         * @return RmfBloksManager
593
         */
594
        public RmfBlocksManager getRmfBlocksManager() {
595
                File fileRMF = getRMFFile();
596
                if(fileRMF != null) {
597
                        if (rmfBlocksManager == null || !fileRMF.equals(rmfBlocksManager)) {
598
                                rmfBlocksManager = new RmfBlocksManager(fileRMF.getPath());
599
                        }
600
                }
601
                return rmfBlocksManager;
602
        }
603

    
604
    public File getRMFFile() {
605
        String tail = selectedSubdatasetID == null ? ".rmf" : "-sd" + selectedSubdatasetID + ".rmf";
606
        File rmfFolder =
607
            (getDataParameters() != null && getDataParameters() instanceof RasterDataParameters)
608
                ? ((RasterDataParameters) getDataParameters()).getRMFFolder() : null;
609

    
610
        String fileName;
611

    
612
        URI objUri = getURI();
613
        File file;
614
        if ("FILE".equalsIgnoreCase(objUri.getScheme())) {
615
            file = new File(objUri);
616
            fileName = FilenameUtils.getBaseName(objUri.getPath());
617
            if (rmfFolder == null) {
618
                rmfFolder = file.getParentFile();
619
                if ((getDataParameters() != null && getDataParameters() instanceof RasterDataParameters)) {
620
                    ((RasterDataParameters) getDataParameters()).setRMFFolder(rmfFolder);
621
                }
622
//                return new File(fileName + tail);
623
            }
624
            return new File(rmfFolder.getAbsolutePath() + File.separator + fileName + tail);
625
        }
626
        return null;
627
    }
628

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

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

    
648
                Point2D pt = new Point2D.Double();
649
                try {
650

    
651
                        getAffineTransform().inverseTransform(p, pt);
652
                        if(        pt.getX() >= 0 && pt.getX() < getWidth() &&
653
                                        pt.getY() >= 0 && pt.getY() < getHeight())
654
                                return true;
655
                } catch (NoninvertibleTransformException e) {
656
                        return false;
657
                }
658

    
659
                return false;
660
        }
661

    
662
        /**
663
         * Consulta de si un raster tiene rotaci?n o no.
664
         * @return true si tiene rotaci?n y false si no la tiene.
665
         */
666
        public boolean isRotated() {
667
                if(externalTransformation.getShearX() != 0 || externalTransformation.getShearY() != 0)
668
                        return true;
669
                return false;
670
        }
671

    
672
        public boolean isMultiFile() {
673
                return false;
674
        }
675

    
676
        public boolean isMosaic() {
677
                return false;
678
        }
679

    
680
        /**
681
         * Devuelve si el Dataset es reproyectable
682
         * @return true if Dataset is reproyectable
683
         */
684
        public boolean isReproyectable() {
685
                return true;
686
        }
687

    
688
        public String getWktProjection() {
689
                if(proj != null && RasterLocator.getManager().isCRSUtilSupported())
690
                        return RasterLocator.getManager().getCRSUtils().convertIProjectionToWkt((IProjection) proj);
691
                return null;
692
        }
693

    
694
        public void saveObjectToRmf(Class<?> class1, Object value) throws RmfSerializerException {
695
        if (getRmfBlocksManager() != null) {
696
            ((DefaultProviderServices) RasterLocator.getManager().getProviderServices()).saveObjectToRmfFile(
697
                getRmfBlocksManager(), class1, value);
698
        }
699
        }
700

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

    
713
                if (serializerObject == null)
714
                        throw new RmfSerializerException("No se ha podido encontrar el serializador para el Rmf");
715

    
716
                if (!blocksManager.checkRmf())
717
                        throw new RmfSerializerException("Error al comprobar el fichero Rmf");
718

    
719
                blocksManager.addClient(serializerObject);
720
                try {
721
                        blocksManager.read(null);
722
                } catch (ParsingException e) {
723
                        throw new RmfSerializerException("Error al leer el fichero Rmf", e);
724
                }
725
                blocksManager.removeAllClients();
726

    
727
                return serializerObject.getResult();
728
        }
729

    
730
        public Object loadObjectFromRmf(Class<?> class1, Object value) throws RmfSerializerException {
731
                RmfBlocksManager blocksManager = getRmfBlocksManager();
732
                if(blocksManager!=null){
733
                    return loadObjectFromRmfFile(blocksManager, class1, value);
734
                }
735
                return null;
736
        }
737

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

    
752
        /**
753
         * Guarda en el RMF el objecto actual en caso de que exista un serializador para el
754
         * @param value
755
         * @throws RmfSerializerException
756
         */
757
        public void saveObjectToRmf(Object value) throws RmfSerializerException {
758
                saveObjectToRmf(value.getClass(), value);
759
        }
760

    
761
        /**
762
         * Carga un objecto desde un serializador usando el tipo del mismo objeto pasado por parametro.
763
         * Usa value para iniciar dicho serializador
764
         * @param value
765
         * @return Object
766
         * @throws RmfSerializerException
767
         */
768
        public Object loadObjectFromRmf(Object value) throws RmfSerializerException {
769
                return loadObjectFromRmf(value.getClass(), value);
770
        }
771

    
772

    
773
        public double getCellSize() {
774
                try {
775
                        Extent e = getExtent();
776
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getWidth();
777
                        return dCellsize;
778
                } catch (NullPointerException e) {
779
                        return 1;
780
                }
781
        }
782

    
783

    
784
        public RasterProvider newProvider() {
785
                return null;
786
        }
787

    
788
        public ColorTable getColorTable() {
789
                return colorTable;
790
        }
791

    
792
        public Image getImageLegend() {
793
                return null;
794
        }
795

    
796
        public void setColorTable(ColorTable value) {
797
                colorTable = value;
798
        }
799

    
800
        public Transparency getTransparency() {
801
                return transparency;
802
        }
803

    
804
        public Metadata getMetadata() {
805
                return null;
806
        }
807

    
808
        public ColorInterpretation getColorInterpretation() {
809
                return this.colorInterpretation;
810
        }
811

    
812
        /**
813
         * Asigna el objeto que contiene que contiene la interpretaci?n de
814
         * color por banda
815
         * @param DataStoreColorInterpretation
816
         */
817
        public void setColorInterpretation(ColorInterpretation colorInterpretation) {
818
                this.colorInterpretation = colorInterpretation;
819
        }
820

    
821
        public Statistics getStatistics() {
822
                if(stats == null) {
823
                        stats = new SimpleProviderStatistics(this);
824
                }
825
                return stats;
826
        }
827

    
828
        public void setStatistics(Statistics stats) throws RmfSerializerException {
829
                this.stats = stats;
830
                saveObjectToRmf(Statistics.class, stats);
831
        }
832

    
833
        public HistogramComputer getHistogramComputer() {
834
                if (histogram == null)
835
                        histogram = new SimpleProviderHistogramComputer(this);
836
                return histogram;
837
        }
838

    
839
    //****************************************************
840
        //*********Implementing Disposable methods************
841
        //****************************************************
842

    
843
    public void doDispose() {
844

    
845
    }
846

    
847
    //****************************************************
848
        //*****Implementing DataStoreProvider methods*********
849
        //****************************************************
850

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

    
867

    
868
        /**
869
         * Returs the DataParameters
870
         * @return the DataParameters
871
         */
872
        public RasterDataParameters getDataParameters() {
873
                if(getDataStoreParameters() instanceof RasterDataParameters)
874
                        return (RasterDataParameters)getDataStoreParameters();
875
                return null;
876
        }
877

    
878
        public Iterator<?> getChilds() {
879
                return null;
880
        }
881

    
882
        public ResourceProvider getResource() {
883
                return null;
884
        }
885

    
886
        public Object getSourceId() {
887
                if( this.getDataParameters() instanceof RasterFileStoreParameters)
888
                        return ((RasterFileStoreParameters)this.getDataParameters()).getFile();
889
                else
890
                        return this.getDataParameters().getURI();
891
        }
892

    
893
        public void open() throws OpenException {
894
        }
895

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

    
908
        /*
909
         * Si alguna subclase necesita sobreescribir este m?todo, deber? hacerlo con el translateURI en lugar de este.
910
         */
911
        public final String translateFileName(String fileName) {
912
                return fileName;
913
        }
914

    
915

    
916
        public String getFileSuffix() {
917
                String path = getURIOfFirstProvider().getPath();
918
        return FilenameUtils.getExtension(path);
919
        }
920

    
921
        public URI getURIOfFirstProvider() {
922
            //FIXME: Esto que lo sobreescriban los proveedores que no son de archivo
923
//                return RasterLocator.getManager().getFileUtils().getFormatedRasterFileName(uri);
924
            return getURI();
925
        }
926

    
927
        public URI getURI() {
928
                return uri;
929
        }
930

    
931
        public void setFName(String n) {
932
            File file = new File(n);
933
            uri = file.toURI();
934
        }
935

    
936
    public String getName() {
937
        String pathName = null;
938
        try {
939
            URI x = this.getURI();
940
            pathName = x.getPath();
941
            return FilenameUtils.getBaseName(pathName);
942
        } catch (Throwable th1) {
943
            try {
944
                return FilenameUtils.getBaseName(this.uri.getPath());
945
            } catch (Throwable th2) {
946
                return this.uri.getPath();
947
            }
948
        }
949
    }
950

    
951
        public String getFullName() {
952
                return uri.getPath();
953
        }
954

    
955
        /**
956
         * Gets the size of the file if exists in Bytes
957
         * @return the size of file
958
         */
959
        public long getFileSize() {
960
                return fileSize;
961
        }
962

    
963
        public void setFileSize(long sz) {
964
                fileSize = sz;
965
        }
966

    
967
        public IProjection getProjection() {
968
                return proj;
969
        }
970

    
971
        public void setProjection(IProjection proj, boolean persist) throws RmfSerializerException {
972
                this.proj = proj;
973
                if(persist) {
974
                        saveObjectToRmf(IProjection.class, proj);
975
                }
976
        }
977

    
978
        protected long getTime() {
979
                return (new Date()).getTime();
980
        }
981

    
982
        public void setAffineTransform(AffineTransform t) {
983
                externalTransformation = (AffineTransform) t.clone();
984
        }
985

    
986
        public AffineTransform getAffineTransform() {
987
                return externalTransformation;
988
        }
989

    
990
        /**
991
         * Elimina la matriz de transformaci?n asociada al raster y que se tiene en
992
         * cuenta para el setView. Este reseteo tendr? en cuenta que si el raster
993
         * tiene asociado un rmf esta transformaci?n no ser? eliminada sino que se
994
         * asignar? la correspondiente al rmf existente.
995
         */
996
        public void resetAffineTransform() {
997
                externalTransformation.setToIdentity();
998
        }
999

    
1000
        public AffineTransform getOwnAffineTransform() {
1001
                return ownTransformation;
1002
        }
1003

    
1004
        public String getInfoByPoint(double x, double y, ICancellable cancellable) throws InfoByPointException {
1005
                return null;
1006
        }
1007

    
1008
        public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
1009
                return null;
1010
        }
1011

    
1012
        public void setTileServer(Class<?> tileServer) throws InitializeException {
1013

    
1014
        }
1015

    
1016
        public int[] getTileSize(int level) {
1017
                return new int[]{0, 0};
1018
        }
1019

    
1020
        public boolean isRasterEnclosed() {
1021
                return false;
1022
        }
1023

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

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

    
1042
        }
1043

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

    
1054
        public void setTimeSerials(TimeSeries serialInfo) throws RmfSerializerException {
1055
                this.serialInfo = serialInfo;
1056
                saveObjectToRmf(TimeSeries.class, serialInfo);
1057
        }
1058

    
1059
        public long[] getFileSizeByProvider() {
1060
                return new long[]{getFileSize()};
1061
        }
1062

    
1063
        public URI[] getURIByProvider() {
1064
                //For providers with one file
1065
                return new URI[]{getURIOfFirstProvider()};
1066
        }
1067

    
1068
        public int[] getBandCountByProvider() {
1069
                return new int[]{getBandCount()};
1070
        }
1071

    
1072
        public int getInternalProviderCount() {
1073
                return 1;
1074
        }
1075

    
1076
        public RasterProvider getInternalProvider(int i) {
1077
                return this;
1078
        }
1079

    
1080
        public URI getURIByBand(int band) {
1081
                //No matter which band be selected. In providers with one file is always the first URI
1082
                return getURIOfFirstProvider();
1083
        }
1084

    
1085
        public int getBandPositionByProvider(int band) {
1086
                return band;
1087
        }
1088

    
1089
        public int getSubdatasetCount() {
1090
                return 0;
1091
        }
1092

    
1093
//        public void addFile(File file) throws InvalidSourceException {
1094
//                //Do nothing
1095
//        }
1096
//
1097
//        public void removeFile(File file) {
1098
//                //Do nothing
1099
//        }
1100

    
1101
        public boolean needEnhanced() {
1102
                return false;
1103
        }
1104

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

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

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

    
1142
        /**
1143
         * Gets the list of geo points associated to this provider
1144
         * @return the list of geo points
1145
         */
1146
        public GeoPointList getGeoPointList() {
1147
                return geoPointList;
1148
        }
1149

    
1150
        /**
1151
         * Sets the list of geo points associated to this provider
1152
         */
1153
        public void setGeoPointList(GeoPointList geoPointList) {
1154
                this.geoPointList = geoPointList;
1155
        }
1156

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

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

    
1175
                int[] drawableBands = new int[bandList.getBandCount()];
1176
                for (int i = 0; i < bandList.getBandCount(); i++) {
1177
                        drawableBands[i] = i;
1178
                }
1179

    
1180
                bandList.setDrawableBands(drawableBands);
1181
                return bandList;
1182
        }
1183

    
1184
        public void close() {
1185
                if(transparency != null)
1186
                        transparency.dispose();
1187
                try {
1188
                        finalize();
1189
                } catch (Throwable e) {
1190
                }
1191
        }
1192

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