Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / RasterDataset.java @ 18040

History | View | Annotate | Download (28.4 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.dataset;
20

    
21
import java.awt.geom.AffineTransform;
22
import java.awt.geom.NoninvertibleTransformException;
23
import java.awt.geom.Point2D;
24
import java.io.File;
25
import java.io.IOException;
26
import java.lang.reflect.Constructor;
27
import java.lang.reflect.InvocationTargetException;
28
import java.util.ArrayList;
29
import java.util.Iterator;
30
import java.util.Map;
31
import java.util.Set;
32

    
33
import org.cresques.cts.ICoordTrans;
34
import org.cresques.cts.IProjection;
35
import org.gvsig.raster.RasterLibrary;
36
import org.gvsig.raster.dataset.io.GdalDriver;
37
import org.gvsig.raster.dataset.io.IRegistrableRasterFormat;
38
import org.gvsig.raster.dataset.io.MemoryRasterDriver;
39
import org.gvsig.raster.dataset.io.MemoryRasterDriverParam;
40
import org.gvsig.raster.dataset.io.RasterDriverException;
41
import org.gvsig.raster.dataset.io.rmf.ParsingException;
42
import org.gvsig.raster.dataset.io.rmf.RmfBlocksManager;
43
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
44
import org.gvsig.raster.dataset.properties.DatasetHistogram;
45
import org.gvsig.raster.dataset.properties.DatasetMetadata;
46
import org.gvsig.raster.dataset.properties.DatasetStatistics;
47
import org.gvsig.raster.dataset.serializer.ColorInterpretationRmfSerializer;
48
import org.gvsig.raster.dataset.serializer.GeoInfoRmfSerializer;
49
import org.gvsig.raster.datastruct.ColorTable;
50
import org.gvsig.raster.datastruct.Extent;
51
import org.gvsig.raster.datastruct.Transparency;
52
import org.gvsig.raster.datastruct.serializer.ColorTableRmfSerializer;
53
import org.gvsig.raster.datastruct.serializer.NoDataRmfSerializer;
54
import org.gvsig.raster.util.RasterUtilities;
55
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
56
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
57
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
58

    
59
/**
60
 * Manejador de ficheros raster georeferenciados.
61
 * 
62
 * Esta clase abstracta es el ancestro de todas las clases que proporcionan
63
 * soporte para ficheros raster georeferenciados.<br>
64
 * Actua tambien como una 'Fabrica', ocultando al cliente la manera en que
65
 * se ha implementado ese manejo. Una clase nueva que soportara un nuevo
66
 * tipo de raster tendr?a que registrar su extensi?n o extensiones usando
67
 * el m?todo @see registerExtension.<br> 
68
 */
69

    
70
public abstract class RasterDataset extends GeoInfo {
71

    
72
  /**
73
   * Flag que representa a la banda del Rojo
74
   */
75
        public static final int                RED_BAND         = 0x01;
76

    
77
        /**
78
   * Flag que representa a la banda del Verde
79
   */
80
        public static final int                GREEN_BAND       = 0x02;
81

    
82
        /**
83
   * Flag que representa a la banda del Azul
84
   */
85
        public static final int                BLUE_BAND        = 0x04;
86
        private boolean                        verifySize       = false;
87
        /**
88
   * Asignaci?n de banda del Rojo a una banda de la imagen
89
   */
90
        protected int                          rBandNr          = 1;
91

    
92
        /**
93
   * Asignaci?n de banda del Verde a una banda de la imagen
94
   */
95
        protected int                          gBandNr          = 1;
96

    
97
        /**
98
   * Asignaci?n de banda del Azul a una banda de la imagen
99
   */
100
        protected int                          bBandNr          = 1;
101

    
102
        /**
103
   * N?mero de bandas de la imagen
104
   */
105
        protected int                          bandCount        = 1;
106
        private int[]                          dataType         = null;
107

    
108
        protected DatasetStatistics            stats            = new DatasetStatistics(this);
109
        protected DatasetHistogram             histogram        = null;
110
        protected Object                       param            = null;
111
        protected RmfBlocksManager             rmfBlocksManager = null;
112

    
113
        protected ColorTable                   colorTable       = null;        
114
        protected double                       noData           = 0;
115
        protected DatasetColorInterpretation   colorInterpretation = null;
116

    
117
        
118
        /*
119
         *  (non-Javadoc)
120
         * @see java.lang.Object#clone()
121
         */
122
        public Object clone() {
123
                try {
124
                        RasterDataset dataset = RasterDataset.open(proj, param);
125
                        //Estas van por referencia
126
                        dataset.histogram = histogram;
127
                        dataset.stats = stats;
128
                        return dataset;
129
                } catch (NotSupportedExtensionException e) {
130
                        e.printStackTrace();
131
                } catch (RasterDriverException e) {
132
                        e.printStackTrace();
133
                }
134
                return null;
135
        }
136
        
137
        /**
138
         * Constructor
139
         */
140
        public RasterDataset() {
141
                
142
        }
143
        
144
        /**
145
         * Factoria para abrir distintos tipos de raster.
146
         * 
147
         * @param proj Proyecci?n en la que est? el raster.
148
         * @param fName Nombre del fichero.
149
         * @return GeoRasterFile, o null si hay problemas.
150
         */
151
        public static RasterDataset open(IProjection proj, Object param) throws NotSupportedExtensionException, RasterDriverException {
152
                String idFormat = null;
153
                
154
                if(param instanceof String)
155
                        idFormat = RasterUtilities.getExtensionFromFileName(((String)param));
156
                if(param instanceof IRegistrableRasterFormat)
157
                        idFormat = ((IRegistrableRasterFormat)param).getFormatID();
158
                                
159
                RasterDataset grf = null;
160

    
161
                Class clase = null;
162
                if(param instanceof MemoryRasterDriverParam)
163
                        clase = MemoryRasterDriver.class;
164
                
165
                if(clase == null){
166
                        ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
167
                        ExtensionPoint extensionPoint = (ExtensionPoint)extensionPoints.get("RasterReader");
168
                        if(extensionPoint == null)
169
                                return null;
170
                        if(idFormat != null)
171
                                clase = (Class)extensionPoint.get(idFormat);
172
                }
173
                
174
                if(clase == null)
175
                        clase = GdalDriver.class;
176
                
177
                Class [] args = {IProjection.class, Object.class};
178
                try {
179
                        Constructor hazNuevo = clase.getConstructor(args);
180
                        Object [] args2 = {proj, param};
181
                        grf = (RasterDataset) hazNuevo.newInstance(args2);
182
                } catch (SecurityException e) {
183
                        throw new RasterDriverException("Error SecurityException in open");
184
                } catch (NoSuchMethodException e) {
185
                        throw new RasterDriverException("Error NoSuchMethodException in open");
186
                } catch (IllegalArgumentException e) {
187
                        throw new RasterDriverException("Error IllegalArgumentException in open");
188
                } catch (InstantiationException e) {
189
                        throw new RasterDriverException("Error InstantiationException in open");
190
                } catch (IllegalAccessException e) {
191
                        throw new RasterDriverException("Error IllegalAccessException in open");
192
                } catch (InvocationTargetException e) {
193
                        throw new NotSupportedExtensionException("Error in open");
194
                }
195
                return grf;
196
        }
197
                
198
        /**
199
         * Acciones de inicilizaci?n comunes a todos los drivers.
200
         * Este m?todo debe ser llamado explicitamente por el constructor de cada driver.
201
         * Estas son acciones de inicializaci?n que se ejecutan despu?s del constructor de cada driver.
202
         * Las acciones que hayan de ser realizadas antes se definen en el constructor de RasterDataset.
203
         */
204
        protected void init() {
205
                //Creamos el gestor de Rmf
206
                int last =  getFName().lastIndexOf(".");
207
                if(last == -1)
208
                        last = getFName().length();
209
                String f = getFName().substring(0, last);
210
                f = f + ".rmf";
211
                rmfBlocksManager = new RmfBlocksManager(f);
212
        }
213
        
214
        /**
215
         * Tipo de fichero soportado.
216
         * Devuelve true si el tipo de fichero (extension) est? soportado, si no
217
         * devuelve false.
218
         * 
219
         * @param fName Fichero raster
220
         * @return  true si est? soportado, si no false.
221
          */
222
        public static boolean fileIsSupported(String fName) {
223
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
224
                ExtensionPoint extensionPoint = (ExtensionPoint)extensionPoints.get("RasterReader");
225
                return (extensionPoint.get(fName.substring(fName.lastIndexOf(".") + 1, fName.length()).toLowerCase()) == null) ? false : true;
226
        }
227
        
228
    /**
229
     * Obtiene la lista de extensiones de ficheros soportadas
230
     * @return Lista de extensiones registradas
231
     */
232
    public static ArrayList getExtensionsSupported() {
233
            ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
234
            ExtensionPoint extensionPoint = (ExtensionPoint)extensionPoints.get("RasterReader");
235
                if(extensionPoint == null)
236
                        return null;
237
                Set values = extensionPoint.entrySet();
238
            ArrayList result = new ArrayList();
239
            for (Iterator it = values.iterator(); it.hasNext(); ) {
240
                    Map.Entry entry = ((Map.Entry)it.next());
241
                    String ext = (String)entry.getKey();
242
                    result.add(ext);
243
        }
244
            return result;
245
    }
246
        
247
        /**
248
         * Constructor
249
         * @param proj        Proyecci?n
250
         * @param name        Nombre del fichero de imagen.
251
         */
252
        public RasterDataset(IProjection proj, Object param) {
253
                super(proj, param);
254
                if(param instanceof String)
255
                        setFileSize(new File(getFName()).length());
256
        }
257

    
258
        
259
        /**
260
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar 
261
         * un objeto de este tipo.
262
         */
263
        abstract public GeoInfo load();
264
        
265
        /**
266
         * Cierra el fichero y libera los recursos.
267
         */
268
        abstract public void close();
269
                
270
        /**
271
         * Carga metadatos desde el fichero Rmf si estos existen
272
         * @param fName Nombre del fichero
273
         * @throws ParsingException 
274
         */
275
        public void loadFromRmf(RmfBlocksManager manager) throws ParsingException {
276
                if (!manager.checkRmf())
277
                        return;
278

    
279
                if (!new File(manager.getPath()).exists())
280
                        return;
281

    
282
                GeoInfoRmfSerializer geoInfoSerializer = new GeoInfoRmfSerializer(this);
283
                ColorTableRmfSerializer colorTableSerializer = new ColorTableRmfSerializer();
284
                NoDataRmfSerializer noDataSerializer = new NoDataRmfSerializer();
285
                ColorInterpretationRmfSerializer colorInterpSerializer = new ColorInterpretationRmfSerializer();
286

    
287
                manager.addClient(geoInfoSerializer);
288
                manager.addClient(colorTableSerializer);
289
                manager.addClient(noDataSerializer);
290
                manager.addClient(colorInterpSerializer);
291

    
292
                manager.read(null);
293

    
294
                manager.removeClient(geoInfoSerializer.getClass());
295
                manager.removeClient(colorTableSerializer.getClass());
296
                manager.removeClient(noDataSerializer.getClass());
297
                manager.removeClient(colorInterpSerializer.getClass());
298

    
299
                if (colorTableSerializer.getResult() != null)
300
                        setColorTable((ColorTable) colorTableSerializer.getResult());
301

    
302
                if (noDataSerializer.getResult() != null)
303
                        noData = ((Double) noDataSerializer.getResult()).doubleValue();
304
                
305
                if(colorInterpSerializer.getResult() != null) {
306
                        DatasetColorInterpretation ci = (DatasetColorInterpretation)colorInterpSerializer.getResult();
307
                        setColorInterpretation(ci);
308
                        if(ci.getBand(DatasetColorInterpretation.ALPHA_BAND) != -1) 
309
                                getTransparencyDatasetStatus().setTransparencyBand(ci.getBand(DatasetColorInterpretation.ALPHA_BAND));
310
                }
311
        }
312
        
313
        /**
314
         * Salva la georreferenciaci?n a fichero rmf.
315
         * @param fName
316
         * @throws IOException  
317
         */
318
        public void saveToRmf(RmfBlocksManager manager) throws IOException {
319
                GeoInfoRmfSerializer ser = new GeoInfoRmfSerializer(this);
320
                if(!manager.checkRmf())
321
                        return;
322
                manager.addClient(ser);
323
                RasterUtilities.copyFile(manager.getPath(), manager.getPath() + "~");
324
                manager.write();
325
                manager.removeClient(ser.getClass());
326
        }        
327
        
328
        /**
329
         * Salva la georreferenciaci?n a fichero rmf.
330
         * @param fName
331
         * @throws IOException  
332
         */
333
        public void saveGeoToRmf() throws IOException {
334
                saveToRmf(rmfBlocksManager);
335
        }
336
                                
337
        /**
338
         * Obtiene el ancho de la imagen
339
         * @return Ancho de la imagen
340
         */
341
        abstract public int getWidth();
342
        
343
        /**
344
         * Obtiene el ancho de la imagen
345
         * @return Ancho de la imagen
346
         */
347
        abstract public int getHeight();
348

    
349
        /**
350
         * Reproyecci?n.
351
         * @param rp        Coordenadas de la transformaci?n
352
         */
353
        abstract public void reProject(ICoordTrans rp);
354

    
355
        /**
356
         * Asigna un nuevo Extent 
357
         * @param e        Extent
358
         */
359
        abstract public void setView(Extent e);
360
        
361
        /**
362
         * Obtiene el extent asignado
363
         * @return        Extent
364
         */
365
        abstract public Extent getView();
366
                                
367
        /**
368
         * Obtiene el valor del raster en la coordenada que se le pasa.
369
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
370
         * raster.
371
         * @param x        coordenada X
372
         * @param y coordenada Y
373
         * @return
374
         */
375
        abstract public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
376

    
377
        /**
378
         * Obtiene el n?nero de bandas del fichero
379
         * @return Entero que representa el n?mero de bandas
380
         */
381
        public int getBandCount() { 
382
                return bandCount; 
383
        }
384
                
385
        /**
386
         * @return Returns the dataType.
387
         */
388
        public int[] getDataType() {
389
                return dataType;
390
        }
391
        
392
        /**
393
         * @param dataType The dataType to set.
394
         */
395
        public void setDataType(int[] dataType) {
396
                this.dataType = dataType;
397
        }
398
   
399
        /**
400
         * Obtiene el tama?o de pixel en X
401
         * @return tama?o de pixel en X
402
         */
403
        public double getPixelSizeX() {
404
                return externalTransformation.getScaleX();
405
        }
406
        
407
        /**
408
         * Obtiene el tama?o de pixel en Y
409
         * @return tama?o de pixel en Y
410
         */
411
        public double getPixelSizeY() {
412
                return externalTransformation.getScaleY();
413
        }
414
        
415
        /**
416
         * Cosulta si hay que verificar la relaci?n de aspecto de la imagen, es decir comprueba que el ancho/alto
417
         * pasados a updateImage coinciden con el ancho/alto solicitado en setView a la imagen
418
         * @return true si est? verificando la relaci?n de aspecto. 
419
         */
420
        public boolean mustVerifySize() {
421
                return verifySize;
422
        }
423

    
424
        /**
425
         * Asigna el flag que dice si hay que verificar la relaci?n de aspecto de la imagen, es decir 
426
         * comprueba que el ancho/alto pasados a updateImage coinciden con el ancho/alto solicitado 
427
         * en setView a la imagen.
428
         * @return true si est? verificando la relaci?n de aspecto. 
429
         */
430
        public void setMustVerifySize(boolean verifySize) {
431
                this.verifySize = verifySize;
432
        }
433

    
434
        /**
435
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
436
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
437
         * pixeles de disco. 
438
         * @param ulx Posici?n X superior izquierda
439
         * @param uly Posici?n Y superior izquierda
440
         * @param lrx Posici?n X inferior derecha
441
         * @param lry Posici?n Y inferior derecha
442
         * @param rasterBuf        Buffer de datos
443
         * @param bandList
444
         * @return Buffer de datos
445
         */
446
        abstract public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, BandList bandList, IBuffer rasterBuf)throws InterruptedException, RasterDriverException;
447
        
448
        /**
449
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
450
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
451
         * pixeles de disco. 
452
         * @param x Posici?n X superior izquierda
453
         * @param y Posici?n Y superior izquierda
454
         * @param w Ancho en coordenadas reales
455
         * @param h Alto en coordenadas reales
456
         * @param rasterBuf        Buffer de datos
457
         * @param bandList
458
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
459
         * @return Buffer de datos
460
         */
461
        abstract public IBuffer getWindowRaster(double x, double y, double w, double h, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent)throws InterruptedException, RasterDriverException;
462
        
463
        /**
464
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
465
         * Se aplica supersampleo o subsampleo dependiendo del tama?o del buffer especificado.
466
         * 
467
         * @param minX Posici?n m?nima X superior izquierda
468
         * @param minY Posici?n m?nima Y superior izquierda
469
         * @param maxX Posici?n m?xima X inferior derecha
470
         * @param maxY Posici?n m?xima Y inferior derecha
471
         * @param bufWidth Ancho del buffer de datos
472
         * @param bufHeight Alto del buffer de datos
473
         * @param rasterBuf        Buffer de datos
474
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
475
         * @param bandList
476
         * @return Buffer de datos
477
         */
478
        abstract public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent)throws InterruptedException, RasterDriverException;
479
        
480
        /**
481
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel. 
482
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
483
         * pixeles de disco. 
484
         * @param x Posici?n X superior izquierda
485
         * @param y Posici?n Y superior izquierda
486
         * @param w Ancho en coordenadas reales
487
         * @param h Alto en coordenadas reales
488
         * @param rasterBuf        Buffer de datos
489
         * @param bandList
490
         * @return Buffer de datos
491
         */
492
        abstract public IBuffer getWindowRaster(int x, int y, int w, int h, BandList bandList, IBuffer rasterBuf)throws InterruptedException, RasterDriverException;
493
        
494
        /**
495
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel. 
496
         * Se aplica supersampleo o subsampleo dependiendo del tama?o del buffer especificado.
497
         * 
498
         * @param x Posici?n X superior izquierda
499
         * @param y Posici?n Y superior izquierda
500
         * @param w Ancho en coordenadas reales
501
         * @param h Alto en coordenadas reales
502
         * @param bufWidth Ancho del buffer de datos
503
         * @param bufHeight Alto del buffer de datos
504
         * @param rasterBuf        Buffer de datos
505
         * @param bandList
506
         * @return Buffer de datos
507
         */
508
        abstract public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf)throws InterruptedException, RasterDriverException;
509
        
510
        abstract public int getBlockSize();
511
        
512
        /**
513
         * Obtiene el objeto que contiene los metadatos. Este m?todo debe ser redefinido por los
514
         * drivers si necesitan devolver metadatos. 
515
         * @return
516
         */
517
        public DatasetMetadata getMetadata(){
518
                return null;
519
        }
520

    
521
        /**
522
         * Obtiene el valor NoData asociado al raster. Si hay un valor en el fichero
523
         * RMF se devuelve este, sino se buscar? en la cabecera del raster o metadatos de
524
         * este. Si finalmente no encuentra ninguno se devuelve el valor por defecto
525
         * definido en la libreria.
526
         * @return
527
         */
528
        public double getNoDataValue() {
529
                return noData;
530
        }
531

    
532
        /**
533
         * Pone el valor original de noData. Primero lo consulta del valor del metadata
534
         * y luego del RMF.
535
         */
536
        public void resetNoDataValue() {
537
                /**
538
                 * Intentamos recuperar el valor del metadatas, en caso de no encontrarlo le
539
                 * asignamos el noData por defecto
540
                 */
541
                do {
542
                        if (getMetadata() == null) {
543
                                noData = RasterLibrary.defaultNoDataValue;
544
                                break;
545
                        }
546

    
547
                        if (getMetadata().getNoDataValue().length == 0) {
548
                                noData = RasterLibrary.defaultNoDataValue;
549
                                break;
550
                        }
551

    
552
                        noData = getMetadata().getNoDataValue()[0];
553
                } while (false);
554

    
555
                /**
556
                 * Miramos a ver si podemos obtener el valor del RMF, en caso de exito se
557
                 * asigna, en caso contrario, no hacemos nada.
558
                 */
559
                RmfBlocksManager manager = getRmfBlocksManager();
560

    
561
                if (!manager.checkRmf())
562
                        return;
563

    
564
                if (!new File(manager.getPath()).exists())
565
                        return;
566

    
567
                NoDataRmfSerializer noDataSerializer = new NoDataRmfSerializer();
568

    
569
                manager.addClient(noDataSerializer);
570

    
571
                try {
572
                        manager.read(null);
573
                } catch (ParsingException e) {
574
                }
575

    
576
                manager.removeClient(noDataSerializer.getClass());
577

    
578
                if (noDataSerializer.getResult() != null)
579
                        noData = ((Double) noDataSerializer.getResult()).doubleValue();
580
        }
581
        
582
        /**
583
         * Establece el valor del NoData
584
         * @param value
585
         */
586
        public void setNoDataValue(double value) {
587
                noData = value;
588
        }
589
                
590
        /**
591
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
592
         * color por banda
593
         * @return
594
         */
595
        public DatasetColorInterpretation getColorInterpretation(){
596
                return colorInterpretation;
597
        }
598
                
599
        /**
600
         * Asigna el objeto que contiene que contiene la interpretaci?n de 
601
         * color por banda
602
         * @param DatasetColorInterpretation
603
         */
604
        public void setColorInterpretation(DatasetColorInterpretation colorInterpretation){
605
                this.colorInterpretation = colorInterpretation;
606
        }
607
        
608
        /**
609
         * Dice si el fichero tiene georreferenciaci?n o no.
610
         * @return true si tiene georreferenciaci?n y false si no la tiene
611
         */
612
        public boolean isGeoreferenced(){
613
                return true;
614
        }
615

    
616
        /**
617
         * Obtiene el objeto paleta. Esta paleta es la que tiene adjunta el fichero de disco. Si es
618
         * null este objeto quiere decir que no tiene paleta para su visualizaci?n. 
619
         * @return Palette
620
         */
621
        public ColorTable getColorTable() {
622
                return colorTable;
623
        }
624

    
625
        /**
626
         * Define el objeto paleta. Si se define null quiere decir que no tiene paleta
627
         * para su visualizaci?n. 
628
         * @param value
629
         */
630
        public void setColorTable(ColorTable value) {
631
                colorTable = value;
632
        }
633
        
634
        /**
635
         * Obtiene el estado de transparencia de un GeoRasterFile. 
636
         * @return Objeto TransparencyFileStatus
637
         */
638
        public Transparency getTransparencyDatasetStatus() {
639
                return null;
640
        }
641
        
642
        /**
643
         * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster. 
644
         * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que 
645
         * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el 
646
         * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
647
         * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
648
         * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
649
         * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
650
         * el driver autom?ticamente.
651
         * @param dWorldTLX Coordenada real X superior izquierda
652
         * @param dWorldTLY Coordenada real Y superior izquierda
653
         * @param dWorldBRX Coordenada real X inferior derecha
654
         * @param dWorldBRY Coordenada real Y inferior derecha
655
         * @param nWidth Ancho del raster
656
         * @param nHeight Alto del raster
657
         * @param bufWidth Ancho del buffer
658
         * @param bufHeight Alto del buffer
659
         * @return Array de dos elementos con el desplazamiento en X e Y. 
660
         */
661
        public double[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY, 
662
                        double nWidth, double nHeight, int bufWidth, int bufHeight) {
663

    
664
                Point2D p1 = new Point2D.Double(dWorldTLX, dWorldTLY);
665
                Point2D p2 = new Point2D.Double(dWorldBRX, dWorldBRY);
666

    
667
                Point2D tl = worldToRaster(new Point2D.Double(p1.getX(), p1.getY()));
668
                Point2D br = worldToRaster(new Point2D.Double(p2.getX(), p2.getY()));
669
                
670
                double wPx = (bufWidth / Math.abs(br.getX() - tl.getX()));
671
                double hPx = (bufHeight / Math.abs(br.getY() - tl.getY()));
672
                
673
                int x = (int)((tl.getX() > br.getX()) ? Math.floor(br.getX()) : Math.floor(tl.getX()));
674
                int y = (int)((tl.getY() > br.getY()) ? Math.floor(br.getY()) : Math.floor(tl.getY()));
675
                
676
                double a = (tl.getX() > br.getX()) ? (Math.abs(br.getX() - x)) : (Math.abs(tl.getX() - x));
677
                double b = (tl.getY() > br.getY()) ? (Math.abs(br.getY() - y)) : (Math.abs(tl.getY() - y)); 
678

    
679
        double stpX = (int)((a * bufWidth) / Math.abs(br.getX() - tl.getX()));
680
                double stpY = (int)((b * bufHeight) / Math.abs(br.getY() - tl.getY()));
681
                
682
                return new double[]{stpX, stpY, wPx, hPx};
683
        }
684
        
685
        /**
686
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
687
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
688
         * @param nLine N?mero de l?nea a leer
689
         * @param band Banda requerida
690
         * @return Object que es un array unidimendional del tipo de datos del raster
691
         * @throws InvalidSetViewException
692
         * @throws FileNotOpenException
693
         * @throws RasterDriverException
694
         */
695
        abstract public Object readCompleteLine(int line, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
696
        
697
        /**
698
         * Lee un bloque completo de datos del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
699
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
700
         * @param pos Posici?n donde se empieza  a leer
701
         * @param blockHeight Altura m?xima del bloque leido
702
         * @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
703
         * @throws InvalidSetViewException
704
         * @throws FileNotOpenException
705
         * @throws RasterDriverException
706
         */
707
        abstract public Object readBlock(int pos, int blockHeight)
708
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException, InterruptedException;
709
        
710
        /**
711
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
712
         * @param pt Punto a transformar
713
         * @return punto transformado en coordenadas del mundo
714
         */
715
        public Point2D rasterToWorld(Point2D pt) {
716
                Point2D p = new Point2D.Double();
717
                externalTransformation.transform(pt, p);
718
                return p;
719
        }
720
        
721
        /**
722
         * Convierte un punto desde del mundo a coordenadas pixel.
723
         * @param pt Punto a transformar
724
         * @return punto transformado en coordenadas pixel
725
         */
726
        public Point2D worldToRaster(Point2D pt) {
727
                Point2D p = new Point2D.Double();
728
                try {
729
                        externalTransformation.inverseTransform(pt, p);
730
                } catch (NoninvertibleTransformException e) {
731
                        return pt;
732
                }
733
                return p;
734
        }
735
        
736
        /**
737
         * Calcula el extent en coordenadas del mundo real
738
         * @return Extent
739
         */
740
        public Extent getExtent() {
741
                return new Extent(        rasterToWorld(new Point2D.Double(0, 0)), 
742
                                                        rasterToWorld(new Point2D.Double(getWidth(), getHeight())),
743
                                                        rasterToWorld(new Point2D.Double(getWidth(), 0)),
744
                                                        rasterToWorld(new Point2D.Double(0, getHeight())));
745
        }
746
        
747
        /**
748
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
749
         * @return Extent
750
         */
751
        public Extent getExtentWithoutRot() {
752
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
753
                                                                                                        0, externalTransformation.getScaleY(), 
754
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
755
                Point2D p1 = new Point2D.Double(0, 0);
756
                Point2D p2 = new Point2D.Double(getWidth(), getHeight());
757
                at.transform(p1, p1);
758
                at.transform(p2, p2);
759
                return new Extent(p1, p2);
760
        }
761
        
762
        /**
763
         * ASigna el par?metro de inicializaci?n del driver.
764
         */
765
        public void setParam(Object param) {
766
                this.param = param;
767
        }
768
        
769
        /**
770
         * Obtiene las estadisticas asociadas al fichero
771
         * @return Objeto con las estadisticas
772
         */
773
        public DatasetStatistics getStatistics() {
774
                return stats;
775
        }
776
        
777
        /**
778
         * Obtiene el n?mero de overviews de una banda
779
         * @return
780
         */
781
        abstract public int getOverviewCount(int band) throws BandAccessException, RasterDriverException;
782
        
783
        /**
784
         * Informa de si el dataset soporta overviews o no.
785
         * @return true si soporta overviews y false si no las soporta.
786
         */
787
        abstract public boolean overviewsSupport();
788
        
789
        /**
790
         * Obtiene el histograma asociado al dataset. Este puede ser obtenido 
791
         * completo o seg?n una lista de clases pasada.
792
         * 
793
         * @return Histograma asociado al dataset.
794
         */
795
        public DatasetHistogram getHistogram() {
796
                if (histogram == null)
797
                        histogram = new DatasetHistogram(this);
798
                return histogram;
799
        }
800
        
801
        public void resetPercent() {
802
                if (histogram != null) histogram.resetPercent();
803
        }
804

    
805
        public int getPercent() {
806
                if (histogram != null) return histogram.getPercent();
807
                return 0;
808
        }
809

    
810
        /**
811
         * Obtiene el gestor de ficheros RMF
812
         * @return RmfBloksManager
813
         */
814
        public RmfBlocksManager getRmfBlocksManager() {
815
                return rmfBlocksManager;
816
        }
817
        
818
        /**
819
         * Escribe sobre el rmf todos los cambios que haya para salvar, es decir, para cada
820
         * Objeto registrado en el manager volcar? su contenido al fichero rmf. ANtes de salvar realizar?
821
         * una copia de seguridad sobre un fichero rmf de backup .rm~
822
         * @throws IOException
823
         */
824
        public void saveRmfModification() throws IOException {
825
                RasterUtilities.copyFile(rmfBlocksManager.getPath(), rmfBlocksManager.getPath() + "~");
826
                rmfBlocksManager.write();
827
        }
828
                
829
        /**
830
         * Informa de si el punto en coordenadas del mundo real pasado por par?metro cae dentro del 
831
         * raster o fuera. Para este calculo cogeremos el punto a averiguar si est? dentro del raster 
832
         * y le aplicaremos la transformaci?n inversa de la transformaci?n af?n aplicada. Una vez hecho 
833
         * esto ya se puede comprobar si est? dentro de los l?mites del extent del raster.
834
         * @param p Punto a comprobar en coordenadas reales
835
         * @return true si el punto est? dentro y false si est? fuera.
836
         */
837
        public boolean isInside(Point2D p){
838
                //Realizamos los calculos solo si el punto est? dentro del extent de la imagen rotada, as? nos ahorramos los calculos
839
                //cuando el puntero est? fuera
840
                
841
                Point2D pt = new Point2D.Double();
842
                try {
843
                        
844
                        getAffineTransform().inverseTransform(p, pt);
845
                        if(        pt.getX() >= 0 && pt.getX() < getWidth() &&
846
                                        pt.getY() >= 0 && pt.getY() < getHeight())
847
                                return true;
848
                } catch (NoninvertibleTransformException e) {
849
                        return false;
850
                }
851
                
852
                return false;
853
        }
854
        
855
        /**
856
         * Consulta de si un raster tiene rotaci?n o no.
857
         * @return true si tiene rotaci?n y false si no la tiene.
858
         */
859
        public boolean isRotated() {
860
                if(externalTransformation.getShearX() != 0 || externalTransformation.getShearY() != 0)
861
                        return true;
862
                return false;
863
        }
864
}