Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster_dataaccess_refactoring / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / provider / AbstractRasterProvider.java @ 2367

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

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

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

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

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

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

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

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

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

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

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

    
379
        abstract public int getBlockSize();
380
        
381
        abstract public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException;
382

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

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

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

    
428
                manager.read(null);
429

    
430
                manager.removeAllClients();
431

    
432
                if (colorTableSerializer.getResult() != null)
433
                        setColorTable((ColorTable) colorTableSerializer.getResult());
434

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

    
442
                if (projectionRmfSerializer.getResult() != null) {
443
                        proj = (IProjection) projectionRmfSerializer.getResult();
444
                }
445
                
446
                if( gcpSerializer.getResult() != null && 
447
                        gcpSerializer.getResult() instanceof GeoPointList && 
448
                        ((GeoPointList)gcpSerializer.getResult()).size() > 0) {
449
                        setGeoPointList((GeoPointList)gcpSerializer.getResult());
450
                }
451
        }
452

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

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

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

    
475
        public double getPixelSizeX() {
476
                return externalTransformation.getScaleX();
477
        }
478

    
479
        public double getPixelSizeY() {
480
                return externalTransformation.getScaleY();
481
        }
482

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

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

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

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

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

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

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

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

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

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

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

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

    
652
                return false;
653
        }
654

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

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

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

    
687
        public void saveObjectToRmf(Class<?> class1, Object value) throws RmfSerializerException {
688
                ((DefaultProviderServices)RasterLocator.getManager().getProviderServices()).saveObjectToRmfFile(getRmfBlocksManager(), class1, value);
689
        }
690

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

    
703
                if (serializerObject == null)
704
                        throw new RmfSerializerException("No se ha podido encontrar el serializador para el Rmf");
705

    
706
                if (!blocksManager.checkRmf())
707
                        throw new RmfSerializerException("Error al comprobar el fichero Rmf");
708

    
709
                blocksManager.addClient(serializerObject);
710
                try {
711
                        blocksManager.read(null);
712
                } catch (ParsingException e) {
713
                        throw new RmfSerializerException("Error al leer el fichero Rmf", e);
714
                }
715
                blocksManager.removeAllClients();
716

    
717
                return serializerObject.getResult();
718
        }
719

    
720
        public Object loadObjectFromRmf(Class<?> class1, Object value) throws RmfSerializerException {
721
                return loadObjectFromRmfFile(getRmfBlocksManager(), class1, value);
722
        }
723

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

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

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

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

    
786
        public Transparency getTransparency() {
787
                return transparency;
788
        }
789
        
790
        public Metadata getMetadata() {
791
                return null;
792
        }
793
        
794
        public ColorInterpretation getColorInterpretation() {
795
                return this.colorInterpretation;
796
        }
797

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

    
864
        public Iterator<?> getChilds() {
865
                return null;
866
        }
867

    
868
        public ResourceProvider getResource() {
869
                return null;
870
        }
871

    
872
        public Object getSourceId() {
873
                if( this.getDataParameters() instanceof RasterFileStoreParameters)
874
                        return ((RasterFileStoreParameters)this.getDataParameters()).getFile();
875
                else
876
                        return this.getDataParameters().getURI();
877
        }
878

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

    
898
        public String getURIOfFirstProvider() {
899
                return RasterLocator.getManager().getFileUtils().getFormatedRasterFileName(uri);
900
        }
901

    
902
        public String getURI() {
903
                return uri;
904
        }
905
        
906
        public void setFName(String n) {
907
                uri = n;
908
        }
909

    
910
        /**
911
         * Gets the size of the file if exists in Bytes
912
         * @return
913
         */
914
        public long getFileSize() {
915
                return fileSize;
916
        }
917

    
918
        public void setFileSize(long sz) {
919
                fileSize = sz;
920
        }
921

    
922
        public IProjection getProjection() {
923
                return proj;
924
        }
925

    
926
        public void setProjection(IProjection proj, boolean persist) throws RmfSerializerException {
927
                this.proj = proj;
928
                if(persist)
929
                        saveObjectToRmf(IProjection.class, proj);
930
        }
931

    
932
        protected long getTime() {
933
                return (new Date()).getTime();
934
        }
935

    
936
        public void setAffineTransform(AffineTransform t) {
937
                externalTransformation = (AffineTransform) t.clone();
938
        }
939

    
940
        public AffineTransform getAffineTransform() {
941
                return externalTransformation;
942
        }
943

    
944
        /**
945
         * Elimina la matriz de transformaci?n asociada al raster y que se tiene en
946
         * cuenta para el setView. Este reseteo tendr? en cuenta que si el raster
947
         * tiene asociado un rmf esta transformaci?n no ser? eliminada sino que se
948
         * asignar? la correspondiente al rmf existente.
949
         * @return devuelve true si tiene fichero rmf asociado y false si no lo tiene.
950
         */
951
        public void resetAffineTransform() {
952
                externalTransformation.setToIdentity();
953
        }
954

    
955
        public AffineTransform getOwnAffineTransform() {
956
                return ownTransformation;
957
        }
958

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