Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / RasterDataset.java @ 12749

History | View | Annotate | Download (24.5 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

    
29
import org.cresques.cts.ICoordTrans;
30
import org.cresques.cts.IProjection;
31
import org.gvsig.i18n.Messages;
32
import org.gvsig.raster.dataset.io.GdalDriver;
33
import org.gvsig.raster.dataset.io.IRegistrableRasterFormat;
34
import org.gvsig.raster.dataset.io.MemoryRasterDriver;
35
import org.gvsig.raster.dataset.io.MemoryRasterDriverParam;
36
import org.gvsig.raster.dataset.io.rmf.ParsingException;
37
import org.gvsig.raster.dataset.io.rmf.RmfBlocksManager;
38
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
39
import org.gvsig.raster.dataset.properties.DatasetHistogram;
40
import org.gvsig.raster.dataset.properties.DatasetMetadata;
41
import org.gvsig.raster.dataset.properties.DatasetStatistics;
42
import org.gvsig.raster.dataset.serializer.GeoInfoRmfSerializer;
43
import org.gvsig.raster.datastruct.ColorTable;
44
import org.gvsig.raster.datastruct.Extent;
45
import org.gvsig.raster.datastruct.Transparency;
46
import org.gvsig.raster.hierarchy.IHistogramable;
47
import org.gvsig.raster.util.RasterUtilities;
48
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
49
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
50
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
51

    
52
/**
53
 * Manejador de ficheros raster georeferenciados.
54
 * 
55
 * Esta clase abstracta es el ancestro de todas las clases que proporcionan
56
 * soporte para ficheros raster georeferenciados.<br>
57
 * Actua tambien como una 'Fabrica', ocultando al cliente la manera en que
58
 * se ha implementado ese manejo. Una clase nueva que soportara un nuevo
59
 * tipo de raster tendr?a que registrar su extensi?n o extensiones usando
60
 * el m?todo @see registerExtension.<br> 
61
 * @author "Luis W. Sevilla" <sevilla_lui@gva.es>*
62
 */
63

    
64
public abstract class RasterDataset extends GeoInfo {
65
        
66
        public static final int                CANCEL_HISTOGRAM = IHistogramable.CANCEL_HISTOGRAM;
67
        public static final int                CANCEL_READ = 2;
68
        
69
        protected boolean[]                        cancel = new boolean[1];
70
        
71
        /**
72
         * Flag que representa a la banda del Rojo
73
         */
74
        public static final int                                 RED_BAND        = 0x01;
75
        
76
        /**
77
         * Flag que representa a la banda del Verde
78
         */
79
        public static final int                                 GREEN_BAND        = 0x02;
80
        
81
        /**
82
         * Flag que representa a la banda del Azul
83
         */
84
        public static final int                                 BLUE_BAND        = 0x04;
85
        private boolean                         verifySize = false;
86
        /**
87
         * Asignaci?n de banda del Rojo a una banda de la imagen
88
         */
89
        protected int                                                         rBandNr = 1;
90
        
91
        /**
92
         * Asignaci?n de banda del Verde a una banda de la imagen
93
         */
94
        protected int                                                         gBandNr = 1;
95
        
96
        /**
97
         * Asignaci?n de banda del Azul a una banda de la imagen
98
         */
99
        protected int                                                         bBandNr = 1;
100
        
101
        /**
102
         * N?mero de bandas de la imagen
103
         */
104
        protected int                                                         bandCount = 1;
105
        private int                                                         dataType = IBuffer.TYPE_BYTE;        
106

    
107
        protected DatasetStatistics             stats = new DatasetStatistics(this);
108
        protected DatasetHistogram                                histogram = null;
109
        protected Object                                                param = null;
110
        protected RmfBlocksManager                                rmfBlocksManager = null;
111
        
112
        static {
113
                Messages.addResourceFamily("org.cresques.translations.text", "org.cresques.ui");
114
        }
115
        
116
        /*
117
         *  (non-Javadoc)
118
         * @see java.lang.Object#clone()
119
         */
120
        public Object clone() {
121
                try {
122
                        RasterDataset dataset = RasterDataset.open(proj, param);
123
                        //Estas van por referencia
124
                        dataset.histogram = histogram;
125
                        dataset.stats = stats;
126
                        return dataset;
127
                } catch (NotSupportedExtensionException e) {
128
                        e.printStackTrace();
129
                } catch (RasterDriverException e) {
130
                        e.printStackTrace();
131
                }
132
                return null;
133
        }
134
        
135
        /**
136
         * Constructor
137
         */
138
        public RasterDataset() {
139
                
140
        }
141
        
142
        /**
143
         * Factoria para abrir distintos tipos de raster.
144
         * 
145
         * @param proj Proyecci?n en la que est? el raster.
146
         * @param fName Nombre del fichero.
147
         * @return GeoRasterFile, o null si hay problemas.
148
         */
149
        public static RasterDataset open(IProjection proj, Object param) throws NotSupportedExtensionException, RasterDriverException {
150
                String idFormat = null;
151
        
152
                if(param instanceof String)
153
                        idFormat = ((String)param).toLowerCase().substring(((String)param).lastIndexOf('.') + 1);
154
                if(param instanceof IRegistrableRasterFormat)
155
                        idFormat = ((IRegistrableRasterFormat)param).getFormatID();
156
                                
157
                RasterDataset grf = null;
158

    
159
                Class clase = null;
160
                if(param instanceof MemoryRasterDriverParam)
161
                        clase = MemoryRasterDriver.class;
162
                
163
                if(clase == null){
164
                        ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
165
                        ExtensionPoint extensionPoint = (ExtensionPoint)extensionPoints.get("RasterReader");
166
                        if(extensionPoint == null)
167
                                return null;
168
                        clase = (Class)extensionPoint.get(idFormat);
169
                }
170
                
171
                if(clase == null)
172
                        clase = GdalDriver.class;
173
                
174
                Class [] args = {IProjection.class, Object.class};
175
                try {
176
                        Constructor hazNuevo = clase.getConstructor(args);
177
                        Object [] args2 = {proj, param};
178
                        grf = (RasterDataset) hazNuevo.newInstance(args2);
179
                } catch (SecurityException e) {
180
                        throw new RasterDriverException("Error SecurityException in open");
181
                } catch (NoSuchMethodException e) {
182
                        throw new RasterDriverException("Error NoSuchMethodException in open");
183
                } catch (IllegalArgumentException e) {
184
                        throw new RasterDriverException("Error IllegalArgumentException in open");
185
                } catch (InstantiationException e) {
186
                        throw new RasterDriverException("Error InstantiationException in open");
187
                } catch (IllegalAccessException e) {
188
                        throw new RasterDriverException("Error IllegalAccessException in open");
189
                } catch (InvocationTargetException e) {
190
                        throw new NotSupportedExtensionException("Error in open");
191
                }
192
                return grf;
193
        }
194
                
195
        /**
196
         * Acciones de inicilizaci?n comunes a todos los drivers.
197
         * Este m?todo debe ser llamado explicitamente por el constructor de cada driver.
198
         * Estas son acciones de inicializaci?n que se ejecutan despu?s del constructor de cada driver.
199
         * Las acciones que hayan de ser realizadas antes se definen en el constructor de RasterDataset.
200
         */
201
        protected void init() {
202
                //Creamos el gestor de Rmf
203
                String f = getFName().substring(0, getFName().lastIndexOf("."));
204
                f = f + ".rmf";
205
                rmfBlocksManager = new RmfBlocksManager(f);
206
        }
207
        
208
        /**
209
         * Tipo de fichero soportado.
210
         * Devuelve true si el tipo de fichero (extension) est? soportado, si no
211
         * devuelve false.
212
         * 
213
         * @param fName Fichero raster
214
         * @return  true si est? soportado, si no false.
215
          */
216
        public static boolean fileIsSupported(String fName) {
217
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
218
                ExtensionPoint extensionPoint = (ExtensionPoint)extensionPoints.get("RasterReader");
219
                return (extensionPoint.get(fName.substring(fName.lastIndexOf(".") + 1, fName.length())) == null) ? false : true;
220
        }
221
        
222
        /**
223
         * Constructor
224
         * @param proj        Proyecci?n
225
         * @param name        Nombre del fichero de imagen.
226
         */
227
        public RasterDataset(IProjection proj, Object param) {
228
                super(proj, param);
229
                if(param instanceof String)
230
                        setFileSize(new File(((String)param)).length());
231
        }
232
        
233
        /**
234
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar 
235
         * un objeto de este tipo.
236
         */
237
        abstract public GeoInfo load();
238
        
239
        /**
240
         * Cierra el fichero y libera los recursos.
241
         */
242
        abstract public void close();
243
                
244
        /**
245
         * Carga georreferenciaci?n desde el fichero Rmf si la hay
246
         * @param fName Nombre del fichero
247
         * @throws ParsingException 
248
         */
249
        public void loadFromRmf(RmfBlocksManager manager) throws ParsingException {
250
                GeoInfoRmfSerializer ser = new GeoInfoRmfSerializer(this);
251
                if(!manager.checkRmf())
252
                        return;
253
                if(!new File(manager.getPath()).exists())
254
                        return;
255
                manager.addClient(ser);
256
                manager.read(null);
257
                manager.removeClient(ser.getClass());
258
        }
259
        
260
        /**
261
         * Salva la georreferenciaci?n a fichero rmf.
262
         * @param fName
263
         * @throws IOException  
264
         */
265
        public void saveToRmf(RmfBlocksManager manager) throws IOException {
266
                GeoInfoRmfSerializer ser = new GeoInfoRmfSerializer(this);
267
                if(!manager.checkRmf())
268
                        return;
269
                manager.addClient(ser);
270
                RasterUtilities.copyFile(manager.getPath(), manager.getPath() + "~");
271
                manager.write();
272
                manager.removeClient(ser.getClass());
273
        }        
274
                                
275
        /**
276
         * Obtiene el ancho de la imagen
277
         * @return Ancho de la imagen
278
         */
279
        abstract public int getWidth();
280
        
281
        /**
282
         * Obtiene el ancho de la imagen
283
         * @return Ancho de la imagen
284
         */
285
        abstract public int getHeight();
286

    
287
        /**
288
         * Reproyecci?n.
289
         * @param rp        Coordenadas de la transformaci?n
290
         */
291
        abstract public void reProject(ICoordTrans rp);
292

    
293
        /**
294
         * Asigna un nuevo Extent 
295
         * @param e        Extent
296
         */
297
        abstract public void setView(Extent e);
298
        
299
        /**
300
         * Obtiene el extent asignado
301
         * @return        Extent
302
         */
303
        abstract public Extent getView();
304
                                
305
        /**
306
         * Obtiene el valor del raster en la coordenada que se le pasa.
307
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
308
         * raster.
309
         * @param x        coordenada X
310
         * @param y coordenada Y
311
         * @return
312
         */
313
        abstract public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
314

    
315
        /**
316
         * Obtiene el n?nero de bandas del fichero
317
         * @return Entero que representa el n?mero de bandas
318
         */
319
        public int getBandCount() { 
320
                return bandCount; 
321
        }
322
                
323
        /**
324
         * @return Returns the dataType.
325
         */
326
        public int getDataType() {
327
                return dataType;
328
        }
329
        
330
        /**
331
         * @param dataType The dataType to set.
332
         */
333
        public void setDataType(int dataType) {
334
                this.dataType = dataType;
335
        }
336
   
337
        /**
338
         * Cosulta si hay que verificar la relaci?n de aspecto de la imagen, es decir comprueba que el ancho/alto
339
         * pasados a updateImage coinciden con el ancho/alto solicitado en setView a la imagen
340
         * @return true si est? verificando la relaci?n de aspecto. 
341
         */
342
        public boolean mustVerifySize() {
343
                return verifySize;
344
        }
345

    
346
        /**
347
         * Asigna el flag que dice si hay que verificar la relaci?n de aspecto de la imagen, es decir 
348
         * comprueba que el ancho/alto pasados a updateImage coinciden con el ancho/alto solicitado 
349
         * en setView a la imagen.
350
         * @return true si est? verificando la relaci?n de aspecto. 
351
         */
352
        public void setMustVerifySize(boolean verifySize) {
353
                this.verifySize = verifySize;
354
        }
355

    
356
        /**
357
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
358
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
359
         * pixeles de disco. 
360
         * @param ulx Posici?n X superior izquierda
361
         * @param uly Posici?n Y superior izquierda
362
         * @param lrx Posici?n X inferior derecha
363
         * @param lry Posici?n Y inferior derecha
364
         * @param rasterBuf        Buffer de datos
365
         * @param bandList
366
         * @return Buffer de datos
367
         */
368
        abstract public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, BandList bandList, IBuffer rasterBuf);
369
        
370
        /**
371
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
372
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
373
         * pixeles de disco. 
374
         * @param x Posici?n X superior izquierda
375
         * @param y Posici?n Y superior izquierda
376
         * @param w Ancho en coordenadas reales
377
         * @param h Alto en coordenadas reales
378
         * @param rasterBuf        Buffer de datos
379
         * @param bandList
380
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
381
         * @return Buffer de datos
382
         */
383
        abstract public IBuffer getWindowRaster(double x, double y, double w, double h, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent);
384
        
385
        /**
386
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
387
         * Se aplica supersampleo o subsampleo dependiendo del tama?o del buffer especificado.
388
         * 
389
         * @param minX Posici?n m?nima X superior izquierda
390
         * @param minY Posici?n m?nima Y superior izquierda
391
         * @param maxX Posici?n m?xima X inferior derecha
392
         * @param maxY Posici?n m?xima Y inferior derecha
393
         * @param bufWidth Ancho del buffer de datos
394
         * @param bufHeight Alto del buffer de datos
395
         * @param rasterBuf        Buffer de datos
396
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
397
         * @param bandList
398
         * @return Buffer de datos
399
         */
400
        abstract public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent);
401
        
402
        /**
403
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel. 
404
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
405
         * pixeles de disco. 
406
         * @param x Posici?n X superior izquierda
407
         * @param y Posici?n Y superior izquierda
408
         * @param w Ancho en coordenadas reales
409
         * @param h Alto en coordenadas reales
410
         * @param rasterBuf        Buffer de datos
411
         * @param bandList
412
         * @return Buffer de datos
413
         */
414
        abstract public IBuffer getWindowRaster(int x, int y, int w, int h, BandList bandList, IBuffer rasterBuf);
415
        
416
        /**
417
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel. 
418
         * Se aplica supersampleo o subsampleo dependiendo del tama?o del buffer especificado.
419
         * 
420
         * @param x Posici?n X superior izquierda
421
         * @param y Posici?n Y superior izquierda
422
         * @param w Ancho en coordenadas reales
423
         * @param h Alto en coordenadas reales
424
         * @param bufWidth Ancho del buffer de datos
425
         * @param bufHeight Alto del buffer de datos
426
         * @param rasterBuf        Buffer de datos
427
         * @param bandList
428
         * @return Buffer de datos
429
         */
430
        abstract public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf);
431
        
432
        abstract public int getBlockSize();
433
        
434
        /**
435
         * Obtiene el objeto que contiene los metadatos. Este m?todo debe ser redefinido por los
436
         * drivers si necesitan devolver metadatos. 
437
         * @return
438
         */
439
        public DatasetMetadata getMetadata(){
440
                return null;
441
        }
442
        
443
        /**
444
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
445
         * color por banda
446
         * @return
447
         */
448
        public DatasetColorInterpretation getColorInterpretation(){
449
                return null;
450
        }
451
                
452
        /**
453
         * Dice si el fichero tiene georreferenciaci?n o no.
454
         * @return true si tiene georreferenciaci?n y false si no la tiene
455
         */
456
        public boolean isGeoreferenced(){
457
                return true;
458
        }
459

    
460
        /**
461
         * Obtiene el objeto paleta. Esta paleta es la que tiene adjunta el fichero de disco. Si es
462
         * null este objeto quiere decir que no tiene paleta para su visualizaci?n. 
463
         * @return Palette
464
         */
465
        public ColorTable getColorTable() {
466
                return null;
467
        }
468
        
469
        /**
470
         * Obtiene el estado de transparencia de un GeoRasterFile. 
471
         * @return Objeto TransparencyFileStatus
472
         */
473
        public Transparency getTransparencyDatasetStatus() {
474
                return null;
475
        }
476
        
477
        /**
478
         * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster. 
479
         * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que 
480
         * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el 
481
         * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
482
         * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
483
         * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
484
         * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
485
         * el driver autom?ticamente.
486
         * @param dWorldTLX Coordenada real X superior izquierda
487
         * @param dWorldTLY Coordenada real Y superior izquierda
488
         * @param dWorldBRX Coordenada real X inferior derecha
489
         * @param dWorldBRY Coordenada real Y inferior derecha
490
         * @param nWidth Ancho del raster
491
         * @param nHeight Alto del raster
492
         * @param bufWidth Ancho del buffer
493
         * @param bufHeight Alto del buffer
494
         * @return Array de dos elementos con el desplazamiento en X e Y. 
495
         */
496
        public int[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY, 
497
                        double nWidth, double nHeight, int bufWidth, int bufHeight){
498

    
499
                Point2D p1 = new Point2D.Double(dWorldTLX, dWorldTLY);
500
                Point2D p2 = new Point2D.Double(dWorldBRX, dWorldBRY);
501

    
502
                Point2D tl = worldToRaster(new Point2D.Double(p1.getX(), p1.getY()));
503
                Point2D br = worldToRaster(new Point2D.Double(p2.getX(), p2.getY()));
504
                                
505
        int x = (int) tl.getX();
506
        int y = (int) tl.getY();
507

    
508
                int stpX = (int)(((tl.getX() - x) * bufWidth) / Math.abs(br.getX() - tl.getX()));
509
                int stpY = (int)(((tl.getY() - y) * bufHeight) / Math.abs(br.getY() - tl.getY()));
510
                
511
                return new int[]{stpX, stpY};
512
        }
513
        
514
        /**
515
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
516
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
517
         * @param nLine N?mero de l?nea a leer
518
         * @param band Banda requerida
519
         * @return Object que es un array unidimendional del tipo de datos del raster
520
         * @throws InvalidSetViewException
521
         * @throws FileNotOpenException
522
         * @throws RasterDriverException
523
         */
524
        abstract public Object readCompleteLine(int line, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
525
        
526
        /**
527
         * Lee un bloque completo de datos del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
528
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
529
         * @param pos Posici?n donde se empieza  a leer
530
         * @param blockHeight Altura m?xima del bloque leido
531
         * @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
532
         * @throws InvalidSetViewException
533
         * @throws FileNotOpenException
534
         * @throws RasterDriverException
535
         */
536
        abstract public Object readBlock(int pos, int blockHeight)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
537
        
538
        /**
539
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
540
         * @param pt Punto a transformar
541
         * @return punto transformado en coordenadas del mundo
542
         */
543
        public Point2D rasterToWorld(Point2D pt) {
544
                Point2D p = new Point2D.Double();
545
                externalTransformation.transform(pt, p);
546
                return p;
547
        }
548
        
549
        /**
550
         * Convierte un punto desde del mundo a coordenadas pixel.
551
         * @param pt Punto a transformar
552
         * @return punto transformado en coordenadas pixel
553
         */
554
        public Point2D worldToRaster(Point2D pt) {
555
                Point2D p = new Point2D.Double();
556
                try {
557
                        externalTransformation.inverseTransform(pt, p);
558
                } catch (NoninvertibleTransformException e) {
559
                        return pt;
560
                }
561
                return p;
562
        }
563

    
564
        /**
565
         * Obtiene las coordenadas reales de las esquinas del raster. En un raster sin rotaci?n esta llamada no es
566
         * necesaria ya que es suficiente con el Extent pero cuando introducimos rotaci?n las coordenadas de las
567
         * 4 esquinas son diferentes entre si.
568
         * @return Point2D[] Lista de cuatro puntos que corresponden a las esquinas superior izquieda, superior derecha,
569
         * inferior derecha e inferior inquierda respectivamente.
570
         */
571
        public Point2D[] getCorners() {
572
                Point2D[] corner = new Point2D[4];
573
                corner[0] = rasterToWorld(new Point2D.Double(0, 0));
574
                corner[1] = rasterToWorld(new Point2D.Double(getWidth(), 0));
575
                corner[2] = rasterToWorld(new Point2D.Double(getWidth(), getHeight()));
576
                corner[3] = rasterToWorld(new Point2D.Double(0, getHeight()));
577
                return corner;
578
        }
579
        
580
        /**
581
         * Obtiene el Extent correspondiente a los valores m?ximos y m?nimos del raster. Este es equivalente a getExtent
582
         * en un raster sin rotaci?n pero varia en un raster rotado.
583
         * @return Extent
584
         */
585
        public Extent getLimits() {
586
                Point2D[] corner = getCorners();
587
                double minX1 = Math.min(corner[0].getX(), corner[1].getX());
588
                double minX2 = Math.min(corner[2].getX(), corner[3].getX());
589
                double minX = Math.min(minX1, minX2);
590
                
591
                double minY1 = Math.min(corner[0].getY(), corner[1].getY());
592
                double minY2 = Math.min(corner[2].getY(), corner[3].getY());
593
                double minY = Math.min(minY1, minY2);
594
                
595
                double maxX1 = Math.max(corner[0].getX(), corner[1].getX());
596
                double maxX2 = Math.max(corner[2].getX(), corner[3].getX());
597
                double maxX = Math.max(maxX1, maxX2);
598
                
599
                double maxY1 = Math.max(corner[0].getY(), corner[1].getY());
600
                double maxY2 = Math.max(corner[2].getY(), corner[3].getY());
601
                double maxY = Math.max(maxY1, maxY2);
602
                return new Extent(minX, maxY, maxX, minY);
603
        }
604
        
605
        /**
606
         * Calcula el extent en coordenadas del mundo real
607
         * @return Extent
608
         */
609
        public Extent getExtent() {
610
                return new Extent(        rasterToWorld(new Point2D.Double(0, 0)), 
611
                                                        rasterToWorld(new Point2D.Double(getWidth(), getHeight())));
612
        }
613
        
614
        /**
615
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
616
         * @return Extent
617
         */
618
        public Extent getExtentWithoutRot() {
619
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
620
                                                                                                        0, externalTransformation.getScaleY(), 
621
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
622
                Point2D p1 = new Point2D.Double(0, 0);
623
                Point2D p2 = new Point2D.Double(getWidth(), getHeight());
624
                at.transform(p1, p1);
625
                at.transform(p2, p2);
626
                return new Extent(p1, p2);
627
        }
628
        
629
        /**
630
         * ASigna el par?metro de inicializaci?n del driver.
631
         */
632
        public void setParam(Object param) {
633
                this.param = param;
634
        }
635
        
636
        /**
637
         * Obtiene las estadisticas asociadas al fichero
638
         * @return Objeto con las estadisticas
639
         */
640
        public DatasetStatistics getStatistics() {
641
                return stats;
642
        }
643
        
644
        /**
645
         * Obtiene el histograma asociado al dataset. Este puede ser obtenido 
646
         * completo o seg?n una lista de clases pasada.
647
         * 
648
         * @return Histograma asociado al dataset.
649
         */
650
        public DatasetHistogram getHistogram() {
651
                if (histogram == null)
652
                        histogram = new DatasetHistogram(this);
653
                return histogram;
654
        }
655
        
656
        public void resetPercent() {
657
                if (histogram != null) histogram.resetPercent();
658
        }
659

    
660
        public int getPercent() {
661
                if (histogram != null) return histogram.getPercent();
662
                return 0;
663
        }
664
        
665
        public void setCanceled(boolean value, int process) {
666
                if(process == CANCEL_HISTOGRAM || process == 0) {
667
                        if (histogram != null) 
668
                                histogram.setCanceled(value, DatasetHistogram.CANCEL_CREATEHISTOGRAM);
669
                }
670
        }
671

    
672
        public boolean isCanceled(int process) {
673
                if(process == CANCEL_HISTOGRAM) {
674
                        if (histogram != null) 
675
                                return histogram.isCanceled(DatasetHistogram.CANCEL_CREATEHISTOGRAM);
676
                }
677
                return false;
678
        }
679

    
680
        /**
681
         * Obtiene el gestor de ficheros RMF
682
         * @return RmfBloksManager
683
         */
684
        public RmfBlocksManager getRmfBlocksManager() {
685
                return rmfBlocksManager;
686
        }
687
        
688
        /**
689
         * Escribe sobre el rmf todos los cambios que haya para salvar, es decir, para cada
690
         * Objeto registrado en el manager volcar? su contenido al fichero rmf. ANtes de salvar realizar?
691
         * una copia de seguridad sobre un fichero rmf de backup .rm~
692
         * @throws IOException
693
         */
694
        public void saveRmfModification() throws IOException {
695
                RasterUtilities.copyFile(rmfBlocksManager.getPath(), rmfBlocksManager.getPath() + "~");
696
                rmfBlocksManager.write();
697
        }
698
                
699
        /**
700
         * Informa de si el punto en coordenadas del mundo real pasado por par?metro cae dentro del 
701
         * raster o fuera. Para este calculo cogeremos el punto a averiguar si est? dentro del raster 
702
         * y le aplicaremos la transformaci?n inversa de la transformaci?n af?n aplicada. Una vez hecho 
703
         * esto ya se puede comprobar si est? dentro de los l?mites del extent del raster.
704
         * @param p Punto a comprobar en coordenadas reales
705
         * @return true si el punto est? dentro y false si est? fuera.
706
         */
707
        public boolean isInside(Point2D p){
708
                //Realizamos los calculos solo si el punto est? dentro del extent de la imagen rotada, as? nos ahorramos los calculos
709
                //cuando el puntero est? fuera
710
                
711
                Point2D pt = new Point2D.Double();
712
                try {
713
                        
714
                        getAffineTransform().inverseTransform(p, pt);
715
                        if(        pt.getX() >= 0 && pt.getX() < getWidth() &&
716
                                        pt.getY() >= 0 && pt.getY() < getHeight())
717
                                return true;
718
                } catch (NoninvertibleTransformException e) {
719
                        return false;
720
                }
721
                
722
                return false;
723
        }
724
        
725
        /**
726
         * Consulta de si un raster tiene rotaci?n o no.
727
         * @return true si tiene rotaci?n y false si no la tiene.
728
         */
729
        public boolean isRotated() {
730
                if(externalTransformation.getShearX() != 0 || externalTransformation.getShearY() != 0)
731
                        return true;
732
                return false;
733
        }
734
}