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 / DefaultRasterProvider.java @ 162

History | View | Annotate | Download (37.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.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27
import java.io.File;
28
import java.lang.reflect.Constructor;
29
import java.lang.reflect.InvocationTargetException;
30
import java.util.Date;
31
import java.util.Iterator;
32

    
33
import org.cresques.cts.IProjection;
34
import org.gvsig.fmap.dal.DALLocator;
35
import org.gvsig.fmap.dal.DataManager;
36
import org.gvsig.fmap.dal.DataParameters;
37
import org.gvsig.fmap.dal.DataServerExplorer;
38
import org.gvsig.fmap.dal.coverage.RasterLibrary;
39
import org.gvsig.fmap.dal.coverage.RasterLocator;
40
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
41
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
42
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
43
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
44
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
45
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
46
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
47
import org.gvsig.fmap.dal.coverage.exception.ParsingException;
48
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
49
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
50
import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException;
51
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
52
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
53
import org.gvsig.fmap.dal.coverage.store.props.Histogram;
54
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
55
import org.gvsig.fmap.dal.coverage.util.FileUtils;
56
import org.gvsig.fmap.dal.coverage.util.RasterUtils;
57
import org.gvsig.fmap.dal.exception.DataException;
58
import org.gvsig.fmap.dal.exception.OpenException;
59
import org.gvsig.fmap.dal.exception.ReadException;
60
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
61
import org.gvsig.fmap.dal.raster.impl.DefaultCoverageStore;
62
import org.gvsig.fmap.dal.raster.spi.AbstractCoverageStoreProvider;
63
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
64
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
65
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
66
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
67
import org.gvsig.raster.impl.datastruct.DefaultNoData;
68
import org.gvsig.raster.impl.datastruct.ExtentImpl;
69
import org.gvsig.raster.impl.datastruct.serializer.ColorTableRmfSerializer;
70
import org.gvsig.raster.impl.datastruct.serializer.NoDataRmfSerializer;
71
import org.gvsig.raster.impl.store.AbstractRasterStoreParameters;
72
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
73
import org.gvsig.raster.impl.store.properties.DataStoreHistogram;
74
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
75
import org.gvsig.raster.impl.store.properties.DataStoreStatistics;
76
import org.gvsig.raster.impl.store.rmf.ClassSerializer;
77
import org.gvsig.raster.impl.store.rmf.RmfBlocksManager;
78
import org.gvsig.raster.impl.store.serializer.ColorInterpretationRmfSerializer;
79
import org.gvsig.raster.impl.store.serializer.GeoInfoRmfSerializer;
80
import org.gvsig.raster.impl.store.serializer.ProjectionRmfSerializer;
81
import org.gvsig.raster.util.DefaultProviderServices;
82
import org.gvsig.tools.ToolsLocator;
83
import org.gvsig.tools.dynobject.DynObject;
84
import org.gvsig.tools.extensionpoint.ExtensionPoint;
85
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
86
import org.gvsig.tools.extensionpoint.ExtensionPoint.Extension;
87

    
88
/**
89
 * Manejador de ficheros raster georeferenciados.
90
 *
91
 * Esta clase abstracta es el ancestro de todas las clases que proporcionan
92
 * soporte para ficheros raster georeferenciados.<br>
93
 * Actua tambien como una 'Fabrica', ocultando al cliente la manera en que
94
 * se ha implementado ese manejo. Una clase nueva que soportara un nuevo
95
 * tipo de raster tendr?a que registrar su extensi?n o extensiones usando
96
 * el m?todo @see registerExtension.<br>
97
 * 
98
 * @author Nacho Brodin (nachobrodin@gmail.com)
99
 */
100
public abstract class DefaultRasterProvider extends AbstractCoverageStoreProvider implements RasterProvider {
101
        /**
102
         * Flags que representan a las bandas visualizables
103
         */
104
        public static final int                 RED_BAND               = 0x01;
105
        public static final int                 GREEN_BAND             = 0x02;
106
        public static final int                 BLUE_BAND              = 0x04;
107
        public static final int                 ALPHA_BAND             = 0x08;
108
        
109
        protected int                           bandCount              = 1;
110
        private int[]                           dataType               = null;
111
        protected double                        noData                 = 0;
112
        protected String                        wktProjection          = "";
113

    
114
        protected DataStoreStatistics             stats                  = new DataStoreStatistics(this);
115
        protected DataStoreHistogram              histogram              = null;
116
        protected AbstractRasterStoreParameters param                  = null;
117
        protected RmfBlocksManager              rmfBlocksManager       = null;
118
        protected ColorTable                    colorTable             = null;
119
        protected DataStoreColorInterpretation    colorInterpretation    = null;
120

    
121
        /**
122
         * Indica si el valor NoData esta activo
123
         */
124
        protected boolean                       noDataEnabled          = false;
125
        protected FileUtils                     fileUtil               = RasterLocator.getManager().getFileUtils();
126
        protected RasterUtils                   rasterUtil             = RasterLocator.getManager().getRasterUtils();
127
        
128
        protected IProjection                   proj                   = null;
129
        protected long                          fileSize               = 0;
130
        protected long                          bytesReaded            = 0;
131
        protected long                          lineCnt                = 0;
132
        protected String                        name;
133
        /**
134
         * Transformaci?n creada a partir de la informaci?n de georreferencia de la
135
         * propia imagen. Esta informaci?n est? en la cabecera o en ficheros
136
         * worldfile.
137
         */
138
        protected AffineTransform               ownTransformation      = null;
139
        /**
140
         * Transformaci?n asignada de forma externa, bien desde el fichero rmf o
141
         * asignada directamente por el usuario.
142
         */
143
        protected AffineTransform               externalTransformation = null;
144
        
145
        public DefaultRasterProvider(AbstractRasterStoreParameters params,
146
                        DataStoreProviderServices storeServices, DynObject metadata) {
147
                super(params, storeServices, metadata);
148
                if(params.getFileName() != null) {
149
                        File f = new File(params.getFileName());
150
                        if(f.exists())
151
                                setFileSize(f.length());
152
                }
153
                
154
                if(params.getFileName() != null)
155
                        name = translateFileName(params.getFileName());
156
                
157
                ownTransformation = new AffineTransform();
158
                externalTransformation = new AffineTransform();
159
        }
160
        
161
        public DefaultRasterProvider(String params) {
162
                super();
163
        }
164
        
165
        public DefaultRasterProvider() {
166
                super(null, null, null);
167
        }
168
        
169
        /**
170
         * Acciones de inicilizaci?n comunes a todos los drivers.
171
         * Este m?todo debe ser llamado explicitamente por el constructor de cada driver.
172
         * Estas son acciones de inicializaci?n que se ejecutan despu?s del constructor de cada driver.
173
         * Las acciones que hayan de ser realizadas antes se definen en el constructor de RasterDataset.
174
         */
175
        protected void init() {
176
        }
177
        
178
        /*
179
         * (non-Javadoc)
180
         * @see java.lang.Object#clone()
181
         */
182
        public RasterProvider cloneProvider() {
183
                try {
184
                        DefaultRasterProvider provider = singleDatasetInstance(param);
185
                        // Estas van por referencia
186
                        provider.histogram = histogram;
187
                        provider.stats = stats;
188
                        return provider;
189
                } catch (NotSupportedExtensionException e) {
190
                        e.printStackTrace();
191
                } catch (RasterDriverException e) {
192
                        e.printStackTrace();
193
                }
194
                return null;
195
        }
196
        
197
        /**
198
         * Factoria para abrir distintos tipos de raster.
199
         * @param fName Nombre del fichero.
200
         *
201
         * @return SingleDataset, o null si hay problemas.
202
         */
203
        @SuppressWarnings("unchecked")
204
        public static DefaultRasterProvider singleDatasetInstance(AbstractRasterStoreParameters param) throws NotSupportedExtensionException, RasterDriverException {
205
                String idFormat = null;
206

    
207
                if (param.getFileName() != null)
208
                        idFormat = RasterLocator.getManager().getFileUtils().getExtensionFromFileName(param.getFileName());
209
                
210
                DefaultRasterProvider grf = null;
211

    
212
                Class clase = null;
213
                ExtensionPointManager extensionPoints = ToolsLocator.getExtensionPointManager();
214
                
215
                if (idFormat != null) {
216
                        ExtensionPoint point = extensionPoints.get("RasterReader");
217
                        Extension ext = point.get(idFormat);
218
                        if (ext != null)
219
                                clase = ext.getExtension();
220
                }
221

    
222
                if (clase == null) {
223
                        ExtensionPoint pointDefaultReader = extensionPoints.get("DefaultDriver");
224
                        Extension extReader = pointDefaultReader.get("reader");
225
                        clase = extReader.getExtension();
226
                }
227

    
228
                Class [] args = {param.getClass(), DefaultCoverageStore.class};
229
                try {
230
                        Constructor hazNuevo = clase.getConstructor(args);
231
                        Object [] args2 = {param, null};
232
                        grf = (DefaultRasterProvider) hazNuevo.newInstance(args2);
233
                } catch (SecurityException e) {
234
                        throw new RasterDriverException("Error SecurityException in open", e);
235
                } catch (NoSuchMethodException e) {
236
                        throw new RasterDriverException("Error NoSuchMethodException in open", e);
237
                } catch (IllegalArgumentException e) {
238
                        throw new RasterDriverException("Error IllegalArgumentException in open", e);
239
                } catch (InstantiationException e) {
240
                        throw new RasterDriverException("Error InstantiationException in open", e);
241
                } catch (IllegalAccessException e) {
242
                        throw new RasterDriverException("Error IllegalAccessException in open", e);
243
                } catch (InvocationTargetException e) {
244
                        throw new NotSupportedExtensionException("Error opening this image with " + clase, e);
245
                }
246
                return grf;
247
        }
248
        
249
        /**
250
         * Factoria para abrir distintos tipos de raster.
251
         * @param fName Nombre del fichero.
252
         *
253
         * @return SingleDataset, o null si hay problemas.
254
         */
255
        @SuppressWarnings("unchecked")
256
        public static DefaultRasterProvider singleDatasetInstance(String param) throws NotSupportedExtensionException, RasterDriverException {
257
                String idFormat = null;
258

    
259
                if (param instanceof String)
260
                        idFormat = RasterLocator.getManager().getFileUtils().getExtensionFromFileName(((String) param));
261
                
262
                DefaultRasterProvider grf = null;
263

    
264
                Class clase = null;
265
                ExtensionPointManager extensionPoints = ToolsLocator.getExtensionPointManager();
266
                if (idFormat != null) {
267
                        ExtensionPoint point = extensionPoints.get("RasterReader");
268
                        Extension ext = point.get(idFormat);
269
                        if (ext != null)
270
                                clase = ext.getExtension();
271
                }
272

    
273
                if (clase == null) {
274
                        ExtensionPoint pointDefaultReader = extensionPoints.get("DefaultDriver");
275
                        Extension extReader = pointDefaultReader.get("reader");
276
                        clase = extReader.getExtension();
277
                }
278

    
279
                Class [] args = {String.class};
280
                try {
281
                        Constructor hazNuevo = clase.getConstructor(args);
282
                        Object [] args2 = {param};
283
                        grf = (DefaultRasterProvider) hazNuevo.newInstance(args2);
284
                } catch (SecurityException e) {
285
                        throw new RasterDriverException("Error SecurityException in open", e);
286
                } catch (NoSuchMethodException e) {
287
                        throw new RasterDriverException("Error NoSuchMethodException in open", e);
288
                } catch (IllegalArgumentException e) {
289
                        throw new RasterDriverException("Error IllegalArgumentException in open", e);
290
                } catch (InstantiationException e) {
291
                        throw new RasterDriverException("Error InstantiationException in open", e);
292
                } catch (IllegalAccessException e) {
293
                        throw new RasterDriverException("Error IllegalAccessException in open", e);
294
                } catch (InvocationTargetException e) {
295
                        throw new NotSupportedExtensionException("Error opening this image with " + clase, e);
296
                }
297
                return grf;
298
        }
299

    
300
        /**
301
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar
302
         * un objeto de este tipo.
303
         */
304
        abstract public RasterProvider load();
305

    
306
        /**
307
         * Cierra el fichero y libera los recursos.
308
         */
309
        abstract public void close();
310

    
311
        /**
312
         * Obtiene el ancho de la imagen
313
         * @return Ancho de la imagen
314
         */
315
        abstract public double getWidth();
316

    
317
        /**
318
         * Obtiene el ancho de la imagen
319
         * @return Ancho de la imagen
320
         */
321
        abstract public double getHeight();
322

    
323
        /**
324
         * Asigna un nuevo Extent
325
         * @param e        Extent
326
         */
327
        public abstract void setView(Extent e);
328

    
329
        /**
330
         * Obtiene el extent asignado
331
         * @return        Extent
332
         */
333
        public abstract Extent getView();
334

    
335
        /**
336
         * Obtiene el valor del raster en la coordenada que se le pasa.
337
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
338
         * raster.
339
         * @param x        coordenada X
340
         * @param y coordenada Y
341
         * @return
342
         */
343
        abstract public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
344

    
345
        /**
346
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales.
347
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
348
         * pixeles de disco.
349
         * @param ulx Posici?n X superior izquierda
350
         * @param uly Posici?n Y superior izquierda
351
         * @param lrx Posici?n X inferior derecha
352
         * @param lry Posici?n Y inferior derecha
353
         * @param rasterBuf        Buffer de datos
354
         * @param bandList
355
         * @return Buffer de datos
356
         */
357
        abstract public Buffer getWindowRaster(double ulx, double uly, double lrx, double lry, BandList bandList, Buffer rasterBuf)throws ProcessInterruptedException, RasterDriverException;
358

    
359
        /**
360
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales.
361
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
362
         * pixeles de disco.
363
         * @param x Posici?n X superior izquierda
364
         * @param y Posici?n Y superior izquierda
365
         * @param w Ancho en coordenadas reales
366
         * @param h Alto en coordenadas reales
367
         * @param rasterBuf        Buffer de datos
368
         * @param bandList
369
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
370
         * @return Buffer de datos
371
         */
372
        abstract public Buffer getWindowRaster(double x, double y, double w, double h, BandList bandList, Buffer rasterBuf, boolean adjustToExtent)throws ProcessInterruptedException, RasterDriverException;
373

    
374
        /**
375
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales.
376
         * Se aplica supersampleo o subsampleo dependiendo del tama?o del buffer especificado.
377
         *
378
         * @param minX Posici?n m?nima X superior izquierda
379
         * @param minY Posici?n m?nima Y superior izquierda
380
         * @param maxX Posici?n m?xima X inferior derecha
381
         * @param maxY Posici?n m?xima Y inferior derecha
382
         * @param bufWidth Ancho del buffer de datos
383
         * @param bufHeight Alto del buffer de datos
384
         * @param rasterBuf        Buffer de datos
385
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
386
         * @param bandList
387
         * @return Buffer de datos
388
         */
389
        abstract public Buffer getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, Buffer rasterBuf, boolean adjustToExtent)throws ProcessInterruptedException, RasterDriverException;
390

    
391
        /**
392
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel.
393
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
394
         * pixeles de disco.
395
         * @param x Posici?n X superior izquierda
396
         * @param y Posici?n Y superior izquierda
397
         * @param w Ancho en coordenadas reales
398
         * @param h Alto en coordenadas reales
399
         * @param rasterBuf        Buffer de datos
400
         * @param bandList
401
         * @return Buffer de datos
402
         */
403
        abstract public Buffer getWindowRaster(int x, int y, int w, int h, BandList bandList, Buffer rasterBuf)throws ProcessInterruptedException, RasterDriverException;
404

    
405
        /**
406
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel.
407
         * Se aplica supersampleo o subsampleo dependiendo del tama?o del buffer especificado.
408
         *
409
         * @param x Posici?n X superior izquierda
410
         * @param y Posici?n Y superior izquierda
411
         * @param w Ancho en coordenadas reales
412
         * @param h Alto en coordenadas reales
413
         * @param bufWidth Ancho del buffer de datos
414
         * @param bufHeight Alto del buffer de datos
415
         * @param rasterBuf        Buffer de datos
416
         * @param bandList
417
         * @return Buffer de datos
418
         */
419
        abstract public Buffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, Buffer rasterBuf)throws ProcessInterruptedException, RasterDriverException;
420

    
421
        abstract public int getBlockSize();
422
        
423
        /*
424
         * (non-Javadoc)
425
         * @see org.gvsig.raster.impl.provider.RasterProvider#getOverviewHeight(int, int)
426
         */
427
        abstract public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException;
428

    
429
        /**
430
         * Informa de si el dataset soporta overviews o no.
431
         * @return true si soporta overviews y false si no las soporta.
432
         */
433
        abstract public boolean overviewsSupport();
434
        
435
        /**
436
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
437
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista.
438
         * @param nLine N?mero de l?nea a leer
439
         * @param band Banda requerida
440
         * @return Object que es un array unidimendional del tipo de datos del raster
441
         * @throws InvalidSetViewException
442
         * @throws FileNotOpenException
443
         * @throws RasterDriverException
444
         */
445
        abstract public Object readCompleteLine(int line, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
446

    
447
        /**
448
         * Lee un bloque completo de datos del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
449
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista.
450
         * @param pos Posici?n donde se empieza  a leer
451
         * @param blockHeight Altura m?xima del bloque leido
452
         * @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
453
         * @throws InvalidSetViewException
454
         * @throws FileNotOpenException
455
         * @throws RasterDriverException
456
         */
457
        abstract public Object readBlock(int pos, int blockHeight)
458
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException;
459

    
460
        /**
461
         * Carga metadatos desde el fichero Rmf si estos existen
462
         * @param fName Nombre del fichero
463
         * @throws ParsingException
464
         */
465
        protected void loadFromRmf(RmfBlocksManager manager) throws ParsingException {
466
                if (!manager.checkRmf())
467
                        return;
468

    
469
                if (!new File(manager.getPath()).exists())
470
                        return;
471

    
472
                GeoInfoRmfSerializer geoInfoSerializer = new GeoInfoRmfSerializer(this);
473
                ColorTableRmfSerializer colorTableSerializer = new ColorTableRmfSerializer();
474
                NoDataRmfSerializer noDataSerializer = new NoDataRmfSerializer(new DefaultNoData(noData, RasterLibrary.NODATATYPE_LAYER));
475
                ColorInterpretationRmfSerializer colorInterpSerializer = new ColorInterpretationRmfSerializer();
476
                ProjectionRmfSerializer projectionRmfSerializer = new ProjectionRmfSerializer();
477

    
478
                manager.addClient(geoInfoSerializer);
479
                manager.addClient(colorTableSerializer);
480
                manager.addClient(noDataSerializer);
481
                manager.addClient(colorInterpSerializer);
482
                manager.addClient(projectionRmfSerializer);
483

    
484
                manager.read(null);
485

    
486
                manager.removeAllClients();
487

    
488
                if (colorTableSerializer.getResult() != null)
489
                        setColorTable((ColorTable) colorTableSerializer.getResult());
490

    
491
                if (noDataSerializer.getResult() != null) {
492
                        noData = ((DefaultNoData) noDataSerializer.getResult()).getValue();
493
                        noDataEnabled = (((DefaultNoData) noDataSerializer.getResult()).getType() != RasterLibrary.NODATATYPE_DISABLED);
494
                }
495

    
496
                if (colorInterpSerializer.getResult() != null) {
497
                        DataStoreColorInterpretation ci = (DataStoreColorInterpretation) colorInterpSerializer.getResult();
498
                        setColorInterpretation(ci);
499
                        if (ci.getBand(DataStoreColorInterpretation.ALPHA_BAND) != -1)
500
                                getTransparency().setTransparencyBand(ci.getBand(DataStoreColorInterpretation.ALPHA_BAND));
501
                }
502

    
503
                if (projectionRmfSerializer.getResult() != null)
504
                        wktProjection = RasterLocator.getManager().getCRSUtils().convertIProjectionToWkt((IProjection) projectionRmfSerializer.getResult());
505
        }
506

    
507
        /**
508
         * Obtiene el n?nero de bandas del fichero
509
         * @return Entero que representa el n?mero de bandas
510
         */
511
        public int getBandCount() {
512
                return bandCount;
513
        }
514

    
515
        /**
516
         * @return Returns the dataType.
517
         */
518
        public int[] getDataType() {
519
                return dataType;
520
        }
521

    
522
        /**
523
         * @param dataType The dataType to set.
524
         */
525
        public void setDataType(int[] dataType) {
526
                this.dataType = dataType;
527
        }
528

    
529
        /*
530
         * (non-Javadoc)
531
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataSet#getPixelSizeX()
532
         */
533
        public double getPixelSizeX() {
534
                return externalTransformation.getScaleX();
535
        }
536

    
537
        /*
538
         * (non-Javadoc)
539
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataSet#getPixelSizeY()
540
         */
541
        public double getPixelSizeY() {
542
                return externalTransformation.getScaleY();
543
        }
544

    
545
        /**
546
         * Obtiene el valor NoData asociado al raster. Si hay un valor en el fichero
547
         * RMF se devuelve este, sino se buscar? en la cabecera del raster o metadatos de
548
         * este. Si finalmente no encuentra ninguno se devuelve el valor por defecto
549
         * definido en la libreria.
550
         * @return
551
         */
552
        public double getNoDataValue() {
553
                return noData;
554
        }
555

    
556
        /**
557
         * Pone el valor original de noData. Primero lo consulta del valor del metadata
558
         * y luego del RMF.
559
         */
560
        public void resetNoDataValue() {
561
                /**
562
                 * Intentamos recuperar el valor del metadatas, en caso de no encontrarlo le
563
                 * asignamos el noData por defecto
564
                 */
565
                noDataEnabled = false;
566
                do {
567
                        if (getMetadata() == null) {
568
                                noData = RasterLibrary.defaultNoDataValue;
569
                                break;
570
                        }
571

    
572
                        if (getMetadata().getNoDataValue().length == 0) {
573
                                noData = RasterLibrary.defaultNoDataValue;
574
                                break;
575
                        }
576

    
577
                        noData = getMetadata().getNoDataValue()[0];
578
                        noDataEnabled = getMetadata().isNoDataEnabled();
579
                } while (false);
580

    
581
                try {
582
                        DefaultNoData noDataObject = (DefaultNoData) loadObjectFromRmf(DefaultNoData.class, null);
583
                        if (noDataObject != null) {
584
                                if (noDataObject.getType() > 0)
585
                                        noData = noDataObject.getValue();
586
                                noDataEnabled = (noDataObject.getType() > 0);
587
                        }
588
                } catch (RmfSerializerException e) {
589
                }
590
        }
591

    
592
        /**
593
         * Establece el valor del NoData
594
         * @param value
595
         */
596
        public void setNoDataValue(double value) {
597
                noData = value;
598
                noDataEnabled = true;
599
        }
600

    
601
        /**
602
         * Dice si el fichero tiene georreferenciaci?n o no.
603
         * @return true si tiene georreferenciaci?n y false si no la tiene
604
         */
605
        public boolean isGeoreferenced(){
606
                return true;
607
        }
608

    
609
        /**
610
         * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster.
611
         * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que
612
         * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el
613
         * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
614
         * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
615
         * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
616
         * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
617
         * el driver autom?ticamente.
618
         * @param dWorldTLX Coordenada real X superior izquierda
619
         * @param dWorldTLY Coordenada real Y superior izquierda
620
         * @param dWorldBRX Coordenada real X inferior derecha
621
         * @param dWorldBRY Coordenada real Y inferior derecha
622
         * @param nWidth Ancho del raster
623
         * @param nHeight Alto del raster
624
         * @param bufWidth Ancho del buffer
625
         * @param bufHeight Alto del buffer
626
         * @return Array de dos elementos con el desplazamiento en X e Y.
627
         */
628
        public double[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
629
                        double nWidth, double nHeight, int bufWidth, int bufHeight) {
630

    
631
                Point2D p1 = new Point2D.Double(dWorldTLX, dWorldTLY);
632
                Point2D p2 = new Point2D.Double(dWorldBRX, dWorldBRY);
633

    
634
                Point2D tl = worldToRaster(new Point2D.Double(p1.getX(), p1.getY()));
635
                Point2D br = worldToRaster(new Point2D.Double(p2.getX(), p2.getY()));
636

    
637
                double wPx = (bufWidth / Math.abs(br.getX() - tl.getX()));
638
                double hPx = (bufHeight / Math.abs(br.getY() - tl.getY()));
639

    
640
                int x = (int)((tl.getX() > br.getX()) ? Math.floor(br.getX()) : Math.floor(tl.getX()));
641
                int y = (int)((tl.getY() > br.getY()) ? Math.floor(br.getY()) : Math.floor(tl.getY()));
642

    
643
                double a = (tl.getX() > br.getX()) ? (Math.abs(br.getX() - x)) : (Math.abs(tl.getX() - x));
644
                double b = (tl.getY() > br.getY()) ? (Math.abs(br.getY() - y)) : (Math.abs(tl.getY() - y));
645

    
646
                                double stpX = (int)((a * bufWidth) / Math.abs(br.getX() - tl.getX()));
647
                double stpY = (int)((b * bufHeight) / Math.abs(br.getY() - tl.getY()));
648

    
649
                return new double[]{stpX, stpY, wPx, hPx};
650
        }
651

    
652
        /**
653
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
654
         * @param pt Punto a transformar
655
         * @return punto transformado en coordenadas del mundo
656
         */
657
        public Point2D rasterToWorld(Point2D pt) {
658
                Point2D p = new Point2D.Double();
659
                externalTransformation.transform(pt, p);
660
                return p;
661
        }
662

    
663
        /**
664
         * Convierte un punto desde del mundo a coordenadas pixel.
665
         * @param pt Punto a transformar
666
         * @return punto transformado en coordenadas pixel
667
         */
668
        public Point2D worldToRaster(Point2D pt) {
669
                Point2D p = new Point2D.Double();
670
                try {
671
                        externalTransformation.inverseTransform(pt, p);
672
                } catch (NoninvertibleTransformException e) {
673
                        return pt;
674
                }
675
                return p;
676
        }
677

    
678
        /**
679
         * Calcula el extent en coordenadas del mundo real
680
         * @return Extent
681
         */
682
        public Extent getExtent() {
683
                return new ExtentImpl(        rasterToWorld(new Point2D.Double(0, 0)),
684
                                                        rasterToWorld(new Point2D.Double(getWidth(), getHeight())),
685
                                                        rasterToWorld(new Point2D.Double(getWidth(), 0)),
686
                                                        rasterToWorld(new Point2D.Double(0, getHeight())));
687
        }
688

    
689
        /**
690
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
691
         * @return Extent
692
         */
693
        public Extent getExtentWithoutRot() {
694
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0,
695
                                                                                                        0, externalTransformation.getScaleY(),
696
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
697
                Point2D p1 = new Point2D.Double(0, 0);
698
                Point2D p2 = new Point2D.Double(getWidth(), getHeight());
699
                at.transform(p1, p1);
700
                at.transform(p2, p2);
701
                return new ExtentImpl(p1, p2);
702
        }
703

    
704
        /**
705
         * ASigna el par?metro de inicializaci?n del driver.
706
         */
707
        public void setParam(AbstractRasterStoreParameters param) {
708
                this.name = param.getFileName();
709
                this.param = param;
710
        }
711

    
712
        /*
713
         * (non-Javadoc)
714
         * @see org.gvsig.raster.impl.provider.RasterProvider#getOverviewWidth(int, int)
715
         */
716
        abstract public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException;
717

    
718
        /**
719
         * Obtiene el gestor de ficheros RMF
720
         * @return RmfBloksManager
721
         */
722
        public RmfBlocksManager getRmfBlocksManager() {
723
                if (rmfBlocksManager == null) {
724
                        String fileRMF = fileUtil.getNameWithoutExtension(getFName()) + ".rmf";
725
                        rmfBlocksManager = new RmfBlocksManager(fileRMF);
726
                }
727
                return rmfBlocksManager;
728
        }
729

    
730
        /*
731
         * (non-Javadoc)
732
         * @see org.gvsig.raster.impl.provider.RasterProvider#isInside(java.awt.geom.Point2D)
733
         */
734
        public boolean isInside(Point2D p){
735
                //Realizamos los calculos solo si el punto est? dentro del extent de la imagen rotada, as? nos ahorramos los calculos
736
                //cuando el puntero est? fuera
737

    
738
                Point2D pt = new Point2D.Double();
739
                try {
740

    
741
                        getAffineTransform().inverseTransform(p, pt);
742
                        if(        pt.getX() >= 0 && pt.getX() < getWidth() &&
743
                                        pt.getY() >= 0 && pt.getY() < getHeight())
744
                                return true;
745
                } catch (NoninvertibleTransformException e) {
746
                        return false;
747
                }
748

    
749
                return false;
750
        }
751

    
752
        /**
753
         * Consulta de si un raster tiene rotaci?n o no.
754
         * @return true si tiene rotaci?n y false si no la tiene.
755
         */
756
        public boolean isRotated() {
757
                if(externalTransformation.getShearX() != 0 || externalTransformation.getShearY() != 0)
758
                        return true;
759
                return false;
760
        }
761

    
762
        /**
763
         * Devuelve si el RasterDataSet tiene el valor noData activo
764
         * @return the noDataEnabled
765
         */
766
        public boolean isNoDataEnabled() {
767
                return noDataEnabled;
768
        }
769

    
770
        /**
771
         * Define si el RasterDataSet tiene el valor noData activo
772
         * @param noDataEnabled the noDataEnabled to set
773
         */
774
        public void setNoDataEnabled(boolean noDataEnabled) {
775
                this.noDataEnabled = noDataEnabled;
776
        }
777

    
778
        /**
779
         * Devuelve si el Dataset es reproyectable
780
         * @return
781
         */
782
        public boolean isReproyectable() {
783
                return false;
784
        }
785

    
786
        public String getWktProjection() {
787
                return wktProjection;
788
        }
789

    
790
        /*
791
         * (non-Javadoc)
792
         * @see org.gvsig.raster.impl.dataset.RasterProvider#saveObjectToRmf(java.lang.Class, java.lang.Object)
793
         */
794
        @SuppressWarnings("unchecked")
795
        public void saveObjectToRmf(Class class1, Object value) throws RmfSerializerException {
796
                ((DefaultProviderServices)RasterLocator.getManager().getProviderServices()).saveObjectToRmfFile(getRmfBlocksManager(), class1, value);
797
        }
798

    
799
        /**
800
         * Carga un objecto desde un serializador del tipo class1. Usa value para iniciar dicho
801
         * serializador
802
         *
803
         * @param class1
804
         * @param value
805
         * @return
806
         * @throws RmfSerializerException
807
         */
808
        @SuppressWarnings("unchecked")
809
        private static Object loadObjectFromRmfFile(RmfBlocksManager blocksManager, Class class1, Object value) throws RmfSerializerException {
810
                ClassSerializer serializerObject = ((DefaultProviderServices)RasterLocator.getManager().getProviderServices()).getSerializerObject(class1, value);
811

    
812
                if (serializerObject == null)
813
                        throw new RmfSerializerException("No se ha podido encontrar el serializador para el Rmf");
814

    
815
                if (!blocksManager.checkRmf())
816
                        throw new RmfSerializerException("Error al comprobar el fichero Rmf");
817

    
818
                blocksManager.addClient(serializerObject);
819
                try {
820
                        blocksManager.read(null);
821
                } catch (ParsingException e) {
822
                        throw new RmfSerializerException("Error al leer el fichero Rmf", e);
823
                }
824
                blocksManager.removeAllClients();
825

    
826
                return serializerObject.getResult();
827
        }
828

    
829
        /*
830
         * (non-Javadoc)
831
         * @see org.gvsig.raster.impl.dataset.RasterProvider#loadObjectFromRmf(java.lang.Class, java.lang.Object)
832
         */
833
        @SuppressWarnings("unchecked")
834
        public Object loadObjectFromRmf(Class class1, Object value) throws RmfSerializerException {
835
                return loadObjectFromRmfFile(getRmfBlocksManager(), class1, value);
836
        }
837

    
838
        /**
839
         * Carga un objeto del fichero RMF especificado por parametro
840
         * @param file
841
         * @param class1
842
         * @param value
843
         * @return
844
         * @throws RmfSerializerException
845
         */
846
        @SuppressWarnings("unchecked")
847
        public static Object loadObjectFromRmfFile(String file, Class class1, Object value) throws RmfSerializerException {
848
                String fileRMF = RasterLocator.getManager().getFileUtils().getNameWithoutExtension(file) + ".rmf";
849
                RmfBlocksManager blocksManager = new RmfBlocksManager(fileRMF);
850
                return loadObjectFromRmfFile(blocksManager, class1, value);
851
        }
852

    
853
        /**
854
         * Guarda en el RMF el objecto actual en caso de que exista un serializador para el
855
         * @param value
856
         * @throws RmfSerializerException
857
         */
858
        public void saveObjectToRmf(Object value) throws RmfSerializerException {
859
                saveObjectToRmf(value.getClass(), value);
860
        }
861

    
862
        /**
863
         * Carga un objecto desde un serializador usando el tipo del mismo objeto pasado por parametro.
864
         * Usa value para iniciar dicho serializador
865
         * @param value
866
         * @return
867
         * @throws RmfSerializerException
868
         */
869
        public Object loadObjectFromRmf(Object value) throws RmfSerializerException {
870
                return loadObjectFromRmf(value.getClass(), value);
871
        }
872
        
873
        /*
874
         * (non-Javadoc)
875
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataSet#getDatasetCount()
876
         */
877
        public int getDatasetCount() {
878
                return 1;
879
        }
880
        
881

    
882
        public double getCellSize() {
883
                try {
884
                        Extent e = getExtent();
885
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getWidth();
886
                        return dCellsize;
887
                } catch (NullPointerException e) {
888
                        return 1;
889
                }
890
        }
891
        
892
        
893
        public RasterProvider newProvider() {
894
                return null;
895
        }
896
        
897
        /*
898
         * (non-Javadoc)
899
         * @see org.gvsig.raster.impl.dataset.RasterProvider#getColorTable()
900
         */
901
        public ColorTable getColorTable() {
902
                return colorTable;
903
        }
904
        
905
        /**
906
         * Define el objeto paleta. Si se define null quiere decir que no tiene paleta
907
         * para su visualizaci?n.
908
         * @param value
909
         */
910
        public void setColorTable(ColorTable value) {
911
                colorTable = value;
912
        }
913

    
914
        /*
915
         * (non-Javadoc)
916
         * @see org.gvsig.raster.impl.dataset.RasterProvider#getTransparency()
917
         */
918
        public Transparency getTransparency() {
919
                return null;
920
        }
921
        
922
        /*
923
         * (non-Javadoc)
924
         * @see org.gvsig.raster.impl.provider.RasterProvider#getMetadata()
925
         */
926
        public DataStoreMetadata getMetadata() {
927
                return null;
928
        }
929
        
930
        /*
931
         * (non-Javadoc)
932
         * @see org.gvsig.raster.impl.dataset.RasterProvider#getColorInterpretation()
933
         */
934
        public ColorInterpretation getColorInterpretation(){
935
                return colorInterpretation;
936
        }
937

    
938
        /**
939
         * Asigna el objeto que contiene que contiene la interpretaci?n de
940
         * color por banda
941
         * @param DataStoreColorInterpretation
942
         */
943
        public void setColorInterpretation(DataStoreColorInterpretation colorInterpretation){
944
                this.colorInterpretation = colorInterpretation;
945
        }
946
        
947
        /*
948
         * (non-Javadoc)
949
         * @see org.gvsig.raster.impl.dataset.RasterProvider#getStatistics()
950
         */
951
        public DataStoreStatistics getStatistics() {
952
                return stats;
953
        }
954
        
955
        /*
956
         * (non-Javadoc)
957
         * @see org.gvsig.raster.impl.dataset.RasterProvider#getHistogram()
958
         */
959
        public Histogram getHistogram() {
960
                if (histogram == null)
961
                        histogram = new DataStoreHistogram(this);
962
                return histogram;
963
        }
964
        
965
    //****************************************************
966
        //*********Implementing Disposable methods************
967
        //****************************************************
968
    
969
    /*
970
     * (non-Javadoc)
971
     * @see org.gvsig.tools.dispose.impl.AbstractDisposable#doDispose()
972
     */
973
    public void doDispose() {
974
            
975
    }
976
    
977
    //****************************************************
978
        //*****Implementing DataStoreProvider methods*********
979
        //****************************************************
980
    
981
    /**
982
     * Gets the specific parameter. All of them inherit from RasterStoreParameters
983
     */
984
    //public abstract RasterStoreParameters getRasterParameters();
985
    
986
    @SuppressWarnings("deprecation")
987
        @Override
988
        public DataServerExplorer getExplorer() throws ReadException,
989
                        ValidateDataParametersException {
990
            DataManager manager = DALLocator.getDataManager();
991
                FilesystemServerExplorerParameters params;
992
                try {
993
                        params = (FilesystemServerExplorerParameters) manager
994
                                        .createServerExplorerParameters(FilesystemServerExplorer.NAME);
995
                        params.setRoot(((AbstractRasterStoreParameters)this.getDataParameters()).getFile().getParent());
996
                        return manager.createServerExplorer(params);
997
                } catch (DataException e) {
998
                        throw new ReadException(this.getName(), e);
999
                }
1000
        }
1001
  
1002
        
1003
        /**
1004
         * Returs the DataParameters
1005
         * @return
1006
         */
1007
        public DataParameters getDataParameters() {
1008
                return getDataStoreParameters();
1009
        }
1010

    
1011
        /*
1012
         * (non-Javadoc)
1013
         * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getChilds()
1014
         */
1015
        @SuppressWarnings("unchecked")
1016
        public Iterator getChilds() {
1017
                return null;
1018
        }
1019

    
1020
        /*
1021
         * (non-Javadoc)
1022
         * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getResource()
1023
         */
1024
        public ResourceProvider getResource() {
1025
                return null;
1026
        }
1027

    
1028
        /*
1029
         * (non-Javadoc)
1030
         * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getSourceId()
1031
         */
1032
        public Object getSourceId() {
1033
                return ((AbstractRasterStoreParameters)this.getDataParameters()).getFile();
1034
        }
1035

    
1036
        /*
1037
         * (non-Javadoc)
1038
         * @see org.gvsig.fmap.dal.spi.DataStoreProvider#open()
1039
         */
1040
        public void open() throws OpenException {
1041
        }
1042
        
1043
        /**
1044
         * Traduce el nombre del fichero por un alias asignado por el propio driver.
1045
         * Cuando es traducido por un alias el driver intentar? abrir el alias y no el
1046
         * fichero. Esto es util porque algunos formatos tienen la extensi?n en el
1047
         * fichero de cabecera pero lo que se abre realmente es el fichero de datos.
1048
         * @param fileName
1049
         * @return
1050
         */
1051
        public String translateFileName(String fileName) {
1052
                return fileName;
1053
        }
1054

    
1055
        public String getFName() {
1056
                return name;
1057
        }
1058

    
1059
        public void setFName(String n) {
1060
                name = n;
1061
        }
1062

    
1063
        public long getFileSize() {
1064
                return fileSize;
1065
        }
1066

    
1067
        public void setFileSize(long sz) {
1068
                fileSize = sz;
1069
        }
1070

    
1071
        /*
1072
         * (non-Javadoc)
1073
         * @see org.gvsig.raster.impl.provider.RasterProvider#getProjection()
1074
         */
1075
        public IProjection getProjection() {
1076
                return proj;
1077
        }
1078

    
1079
        public void setProjection(IProjection p) {
1080
                proj = p;
1081
        }
1082

    
1083
        protected long getTime() {
1084
                return (new Date()).getTime();
1085
        }
1086

    
1087
        /*
1088
         * (non-Javadoc)
1089
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataSet#setAffineTransform(java.awt.geom.AffineTransform)
1090
         */
1091
        public void setAffineTransform(AffineTransform t) {
1092
                externalTransformation = (AffineTransform) t.clone();
1093
        }
1094

    
1095
        /*
1096
         * (non-Javadoc)
1097
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataSet#getAffineTransform()
1098
         */
1099
        public AffineTransform getAffineTransform() {
1100
                return externalTransformation;
1101
        }
1102

    
1103
        /**
1104
         * Elimina la matriz de transformaci?n asociada al raster y que se tiene en
1105
         * cuenta para el setView. Este reseteo tendr? en cuenta que si el raster
1106
         * tiene asociado un rmf esta transformaci?n no ser? eliminada sino que se
1107
         * asignar? la correspondiente al rmf existente.
1108
         * @return devuelve true si tiene fichero rmf asociado y false si no lo tiene.
1109
         */
1110
        public void resetAffineTransform() {
1111
                externalTransformation.setToIdentity();
1112
        }
1113

    
1114
        /*
1115
         * (non-Javadoc)
1116
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataSet#getOwnAffineTransform()
1117
         */
1118
        public AffineTransform getOwnAffineTransform() {
1119
                return ownTransformation;
1120
        }
1121
}