Statistics
| Revision:

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

History | View | Annotate | Download (29.8 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.Point2D;
23
import java.io.BufferedReader;
24
import java.io.File;
25
import java.io.FileInputStream;
26
import java.io.FileNotFoundException;
27
import java.io.FileReader;
28
import java.io.IOException;
29
import java.lang.reflect.Constructor;
30
import java.lang.reflect.InvocationTargetException;
31

    
32
import org.cresques.cts.ICoordTrans;
33
import org.cresques.cts.IProjection;
34
import org.gvsig.i18n.Messages;
35
import org.gvsig.raster.dataset.io.GdalDriver;
36
import org.gvsig.raster.dataset.io.IRegistrableRasterFormat;
37
import org.gvsig.raster.dataset.io.MemoryRasterDriver;
38
import org.gvsig.raster.dataset.io.MemoryRasterDriverParam;
39
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
40
import org.gvsig.raster.dataset.properties.DatasetHistogram;
41
import org.gvsig.raster.dataset.properties.DatasetMetadata;
42
import org.gvsig.raster.dataset.properties.DatasetPalette;
43
import org.gvsig.raster.dataset.properties.DatasetStatistics;
44
import org.gvsig.raster.dataset.properties.DatasetTransparency;
45
import org.gvsig.raster.shared.Extent;
46
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
47
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
48
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
49
import org.kxml2.io.KXmlParser;
50
import org.xmlpull.v1.XmlPullParserException;
51

    
52
import es.gva.cit.jgdal.GdalException;
53

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

    
66
public abstract class RasterDataset extends GeoInfo {
67
        
68
        /**
69
         * Flag que representa a la banda del Rojo
70
         */
71
        public static final int                                 RED_BAND        = 0x01;
72
        
73
        /**
74
         * Flag que representa a la banda del Verde
75
         */
76
        public static final int                                 GREEN_BAND        = 0x02;
77
        
78
        /**
79
         * Flag que representa a la banda del Azul
80
         */
81
        public static final int                                 BLUE_BAND        = 0x04;
82
        private boolean                                                        verifySize = false;
83
        /**
84
         * Par?metros de transformaci?n del fichero .rmf. Esta ser? distinta
85
         * de la identidad si la funci?n rmfExists() devuelve true.
86
         */
87
        protected AffineTransform                                rmfTransform = new AffineTransform();
88
                        
89
        /**
90
         * Asignaci?n de banda del Rojo a una banda de la imagen
91
         */
92
        protected int                                                         rBandNr = 1;
93
        
94
        /**
95
         * Asignaci?n de banda del Verde a una banda de la imagen
96
         */
97
        protected int                                                         gBandNr = 1;
98
        
99
        /**
100
         * Asignaci?n de banda del Azul a una banda de la imagen
101
         */
102
        protected int                                                         bBandNr = 1;
103
        
104
        /**
105
         * N?mero de bandas de la imagen
106
         */
107
        protected int                                                         bandCount = 1;
108
        private int                                                         dataType = IBuffer.TYPE_BYTE;        
109

    
110
        /**
111
         * Par?metros de transformaci?n del fichero .rmf. Estas variables tendr?n valores distinto
112
         * de 0 si la funci?n rmfExists() devuelve true.
113
         */
114
        protected double                                                 imageWidth = 0D, imageHeight = 0D;
115
        protected DatasetStatistics                                stats = new DatasetStatistics(this);
116
        protected DatasetHistogram                                histogram = null;
117
        
118
        //TODO: ARQUITECTURA: Los drivers se registran siempre y cuando antes de hacer un openFile se haya llamado a XXDriver.class. Esto hay que revisarlo.
119
        
120
        static {
121
                Messages.addResourceFamily("org.cresques.translations.text", "org.cresques.ui");
122

    
123
                //Punto de extensi?n para registro de drivers
124
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
125
                if (!extensionPoints.containsKey("RasterDriver")) {
126
                        extensionPoints.put(
127
                                new ExtensionPoint(
128
                                        "RasterDriver",
129
                                        "Raster Drivers for gvSIG raster library")
130
                        );
131
                }
132
        }
133
        
134
        /**
135
         * Factoria para abrir distintos tipos de raster.
136
         * 
137
         * @param proj Proyecci?n en la que est? el raster.
138
         * @param fName Nombre del fichero.
139
         * @return GeoRasterFile, o null si hay problemas.
140
         */
141
        public static RasterDataset open(IProjection proj, Object param) throws NotSupportedExtensionException, RasterDriverException{
142
                String idFormat = null;
143
        
144
                if(param instanceof String)
145
                        idFormat = ((String)param).toLowerCase().substring(((String)param).lastIndexOf('.') + 1);
146
                if(param instanceof IRegistrableRasterFormat)
147
                        idFormat = ((IRegistrableRasterFormat)param).getFormatID();
148
                                
149
                RasterDataset grf = null;
150

    
151
                Class clase = null;
152
                if(param instanceof MemoryRasterDriverParam)
153
                        clase = MemoryRasterDriver.class;
154
                
155
                if(clase == null){
156
                        ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
157
                        ExtensionPoint extensionPoint = (ExtensionPoint)extensionPoints.get("RasterDriver");
158
                        if(extensionPoint == null)
159
                                return null;
160
                        clase = (Class)extensionPoint.get(idFormat);
161
                }
162
                
163
                if(clase == null)
164
                        clase = GdalDriver.class;
165
                
166
                Class [] args = {IProjection.class, Object.class};
167
                try {
168
                        Constructor hazNuevo = clase.getConstructor(args);
169
                        Object [] args2 = {proj, param};
170
                        grf = (RasterDataset) hazNuevo.newInstance(args2);
171
                } catch (SecurityException e) {
172
                        throw new RasterDriverException("Error SecurityException in open");
173
                } catch (NoSuchMethodException e) {
174
                        throw new RasterDriverException("Error NoSuchMethodException in open");
175
                } catch (IllegalArgumentException e) {
176
                        throw new RasterDriverException("Error IllegalArgumentException in open");
177
                } catch (InstantiationException e) {
178
                        throw new RasterDriverException("Error InstantiationException in open");
179
                } catch (IllegalAccessException e) {
180
                        throw new RasterDriverException("Error IllegalAccessException in open");
181
                } catch (InvocationTargetException e) {
182
                        throw new NotSupportedExtensionException("Error in open");
183
                }
184
                return grf;
185
        }
186
                
187
        /**
188
         * Tipo de fichero soportado.
189
         * Devuelve true si el tipo de fichero (extension) est? soportado, si no
190
         * devuelve false.
191
         * 
192
         * @param fName Fichero raster
193
         * @return  true si est? soportado, si no false.
194
          */
195
        public static boolean fileIsSupported(String fName) {
196
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
197
                ExtensionPoint extensionPoint = (ExtensionPoint)extensionPoints.get("RasterDriver");
198
                return (extensionPoint.get(fName.substring(fName.lastIndexOf(".") + 1, fName.length())) == null) ? false : true;
199
        }
200
        
201
        /**
202
         * Constructor
203
         * @param proj        Proyecci?n
204
         * @param name        Nombre del fichero de imagen.
205
         */
206
        public RasterDataset(IProjection proj, Object param) {
207
                super(proj, param);
208
                if(param instanceof String)
209
                        setFileSize(new File(((String)param)).length());
210
        }
211
        
212
        /**
213
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar 
214
         * un objeto de este tipo.
215
         */
216
        abstract public GeoInfo load();
217
        
218
        /**
219
         * Cierra el fichero y libera los recursos.
220
         */
221
        abstract public void close();
222
        
223
        /**
224
         * Obtiene la codificaci?n del fichero XML
225
         * @param file Nombre del fichero XML
226
         * @return Codificaci?n
227
         */
228
        private String readFileEncoding(String file){
229
                FileReader fr;
230
                String encoding = null;
231
                try
232
            {
233
                        fr = new FileReader(file);
234
                    BufferedReader br = new BufferedReader(fr);
235
                    char[] buffer = new char[100];
236
                    br.read(buffer);
237
                    StringBuffer st = new StringBuffer(new String(buffer));
238
                    String searchText = "encoding=\"";
239
                    int index = st.indexOf(searchText);
240
                    if (index>-1) {
241
                            st.delete(0, index+searchText.length());
242
                            encoding = st.substring(0, st.indexOf("\""));
243
                    }
244
                    fr.close();
245
            } catch(FileNotFoundException ex)        {
246
                    ex.printStackTrace();
247
            } catch (IOException e) {
248
                        e.printStackTrace();
249
                }
250
            return encoding;
251
        }
252
        
253
        private double[] parserExtent(KXmlParser parser) throws XmlPullParserException, IOException {                
254
                double originX = 0D, originY = 0D, w = 0D, h = 0D;
255
                double pixelSizeX = 0D, pixelSizeY = 0D;
256
                double shearX = 0D, shearY = 0D;
257
                
258
                boolean end = false;
259
            int tag = parser.next();
260
            while (!end) {
261
                    switch(tag) {
262
                        case KXmlParser.START_TAG:
263
                                if(parser.getName() != null){        
264
                                                if (parser.getName().equals(RasterMetaFileTags.POSX)){
265
                                                        originX = Double.parseDouble(parser.nextText());
266
                                                }else if (parser.getName().equals(RasterMetaFileTags.POSY)){
267
                                                        originY = Double.parseDouble(parser.nextText());
268
                                                }else if (parser.getName().equals(RasterMetaFileTags.PX_SIZE_X)){
269
                                                        pixelSizeX = Double.parseDouble(parser.nextText());
270
                                                }else if (parser.getName().equals(RasterMetaFileTags.PX_SIZE_Y)){
271
                                                        pixelSizeY = Double.parseDouble(parser.nextText());
272
                                                }else if (parser.getName().equals(RasterMetaFileTags.ROTX)){
273
                                                        shearX = Double.parseDouble(parser.nextText());
274
                                                }else if (parser.getName().equals(RasterMetaFileTags.ROTY)){
275
                                                        shearY = Double.parseDouble(parser.nextText());
276
                                                }else if (parser.getName().equals(RasterMetaFileTags.WIDTH)){
277
                                                        w = Double.parseDouble(parser.nextText());
278
                                                }else if (parser.getName().equals(RasterMetaFileTags.HEIGHT)){
279
                                                        h = Double.parseDouble(parser.nextText());
280
                                                }
281
                                        }                                
282
                                        break;
283
                         case KXmlParser.END_TAG:
284
                                 if (parser.getName().equals(RasterMetaFileTags.BBOX))
285
                                         end = true;
286
                                break;
287
                        case KXmlParser.TEXT:
288
                                break;
289
                    }
290
                    tag = parser.next();
291
            }
292
                
293
            double[] values = {originX, originY, w, h, pixelSizeX, pixelSizeY, shearX, shearY};
294
                return values;
295
        }
296
        
297
        /**
298
         * Obtiene la informaci?n de georreferenciaci?n asociada a la imagen en un fichero .rmf. Esta 
299
         * georreferenciaci?n tiene la caracteristica de que tiene prioridad sobre la de la imagen.
300
         * Es almacenada en la clase GeoFile en la variable virtualExtent.
301
         * @param file Fichero de metadatos .rmf
302
         */
303
        protected void readGeoInfo(String file){
304
                String rmf = file.substring(0, file.lastIndexOf(".") + 1) + "rmf";
305
                File rmfFile = new File(rmf);
306
                if(!rmfFile.exists())
307
                        return;
308
                
309
                boolean georefOk = false;
310
                
311
                FileReader fr = null;
312
                String v = null;
313
                try {
314
                        fr = new FileReader(rmf);
315
                        KXmlParser parser = new KXmlParser();
316
                        parser.setInput(new FileInputStream(rmf), readFileEncoding(rmf));
317
                        int tag = parser.nextTag();
318
                        if ( parser.getEventType() != KXmlParser.END_DOCUMENT ){                    
319
                                parser.require(KXmlParser.START_TAG, null, RasterMetaFileTags.MAIN_TAG);                            
320
                                while(tag != KXmlParser.END_DOCUMENT) {
321
                                        switch(tag) {
322
                                                case KXmlParser.START_TAG:
323
                                                        if (parser.getName().equals(RasterMetaFileTags.LAYER)) {
324
                                                                int layerListTag = parser.next();
325
                                                                boolean geoRefEnd = false;
326
                                                                while (!geoRefEnd){
327
                                                                        if(parser.getName() != null){
328
                                                                                if (parser.getName().equals(RasterMetaFileTags.PROJ)){
329
                                                                                        //System.out.println("PROJ:"+parser.nextText());
330
                                                                                } else if (parser.getName().equals(RasterMetaFileTags.BBOX)){
331
                                                                                        double[] values = parserExtent(parser);
332
                                                                                        rmfTransform = new AffineTransform(        values[4], values[7],
333
                                                                                                                                           values[6], values[5],
334
                                                                                                                                                                   values[0], values[1]);
335
                                                                                        georefOk = true;
336
                                                                                } else if (parser.getName().equals(RasterMetaFileTags.DIM)){
337
                                                                                        boolean DimEnd = false;
338
                                                                                        while (!DimEnd){
339
                                                                                                layerListTag = parser.next();
340
                                                                                                if(parser.getName() != null){        
341
                                                                                                        if (parser.getName().equals(RasterMetaFileTags.PX_WIDTH)){
342
                                                                                                                imageWidth = Double.parseDouble(parser.nextText());
343
                                                                                                        }else if (parser.getName().equals(RasterMetaFileTags.PX_HEIGHT)){
344
                                                                                                                imageHeight = Double.parseDouble(parser.nextText());
345
                                                                                                                DimEnd = true;
346
                                                                                                        }                                                                                                        
347
                                                                                                }
348
                                                                                        }
349
                                                                                        geoRefEnd = true;
350
                                                                                }
351
                                                                        }
352
                                                                        layerListTag = parser.next();
353
                                                                }
354
                                                        }
355
                                                        break;
356
                                                case KXmlParser.END_TAG:                                                        
357
                                                        break;
358
                                                case KXmlParser.TEXT:                                                        
359
                                                        break;
360
                                        }
361
                                        tag = parser.next();
362
                                }
363
                                parser.require(KXmlParser.END_DOCUMENT, null, null);
364
                        }
365
                        
366
                        if(georefOk){
367
                                rmfExists = true;
368
                                setExtentTransform(        rmfTransform.getTranslateX(), rmfTransform.getTranslateY(), 
369
                                                                        rmfTransform.getScaleX(), rmfTransform.getScaleY());
370
                                createExtentsFromRMF(        rmfTransform.getTranslateX(), rmfTransform.getTranslateY(), 
371
                                                                                rmfTransform.getScaleX(), rmfTransform.getScaleY(), 
372
                                                                                imageWidth, imageHeight, 
373
                                                                                rmfTransform.getShearX(), rmfTransform.getShearY());
374
                        }
375
                        
376
                } catch (FileNotFoundException fnfEx) {
377
                } catch (XmlPullParserException xmlEx) {
378
                        xmlEx.printStackTrace();
379
                } catch (IOException e) {
380
                } 
381
                try{
382
                        if(fr != null)
383
                                fr.close();
384
                }catch(IOException ioEx){
385
                        //No est? abierto el fichero por lo que no hacemos nada
386
                }
387
        }
388

    
389
        /**
390
         * Asigna una transformaci?n al raster para que se tenga en cuenta en la asignaci?n del setView. 
391
         * Esta asignaci?n recalcula el extent, el requestExtent y asigna el AffineTransform que se 
392
         * usar? para la transformaci?n. Esta transformaci?n ser? considerada como si la imagen tuviera 
393
         * asociado un rmf.
394
         * @param t Transformaci?n af?n a aplicar
395
         */
396
        public void setAffineTransform(AffineTransform t){
397
                rmfExists = true;
398
                rmfTransform = (AffineTransform)t.clone();
399
                setExtentTransform(t.getTranslateX(), t.getTranslateY(), t.getScaleX(), t.getScaleY());
400
                createExtentsFromRMF(        t.getTranslateX(), t.getTranslateY(), t.getScaleX(), t.getScaleY(), 
401
                                                                this.getWidth(), this.getHeight(), 
402
                                                                t.getShearX(), t.getShearY());
403
        }
404
        
405
        /**
406
         * Asigna una transformaci?n al raster para que se tenga en cuenta en la asignaci?n del setView. 
407
         * Esta asignaci?n recalcula el extent, el requestExtent y asigna el AffineTransform que se 
408
         * usar? para la transformaci?n. Esta transformaci?n ser? considerada como si la imagen tuviera 
409
         * asociado un rmf.
410
         * @param originX Coordenada X de origen del raster
411
         * @param originY Coordenada Y de origen del raster
412
         * @param pixelSizeX Tama?o de pixel en X
413
         * @param pixelSizeY Tama?o de pixel en Y
414
         * @param imageWidth Ancho del raster en pixels
415
         * @param imageHeight Alto del raster en pixels
416
         * @param shearX Shearing en X
417
         * @param shearY Shearing en Y
418
         */
419
        public void setAffineTransform(        double originX, double originY, double pixelSizeX, 
420
                                                                                double pixelSizeY, double shearX, double shearY){
421
                rmfExists = true;
422
                rmfTransform.setToTranslation(originX, originY);
423
                rmfTransform.shear(shearX, shearY);
424
                rmfTransform.scale(pixelSizeX, pixelSizeY);
425
                setExtentTransform(originX, originY, pixelSizeX, pixelSizeY);
426
                createExtentsFromRMF(        originX, originY, pixelSizeX, pixelSizeY, 
427
                                                                imageWidth, imageHeight, shearX, shearY);
428
        }
429
        
430
        /**
431
         * Obtiene la matriz de transformaci?n que se aplica sobre la visualizaci?n 
432
         * del raster.
433
         * @return Matriz de transformaci?n.
434
         */
435
        public AffineTransform getAffineTransform(){
436
                return rmfTransform;
437
        }
438
        
439
        /**
440
         * Elimina la matriz de transformaci?n asociada al raster y que se tiene en cuenta para
441
         * el setView. Este reseteo tendr? en cuenta que si el raster tiene asociado un rmf
442
         * esta transformaci?n no ser? eliminada sino que se asignar? la correspondiente al rmf
443
         * existente.  
444
         * @return devuelve true si tiene fichero rmf asociado y false si no lo tiene.
445
         */
446
        public boolean resetAffineTransform(){
447
                rmfExists = false;
448
                rmfTransform.setToIdentity();
449
                
450
                //Crea los extent iniciales
451
                load();
452
                
453
                //Lee y carga el rmf si existe
454
                readGeoInfo(this.getFName());
455
                
456
                if(rmfExists)
457
                        return true;
458
                else
459
                        return false;
460
        }
461
        
462
        /**
463
         * <P>
464
         * Calcula el extent de la imagen a partir del fichero rmf con y sin rotaci?n. El extent con rotaci?n corresponde
465
         * a la variable extent que contiene el extent verdadero marcado por el fichero de georreferenciaci?n .rmf. El extent
466
         * sin rotaci?n requestExtent es utilizado para realizar la petici?n ya que la petici?n al driver no se puede
467
         * hacer con coordenadas rotadas.
468
         * 
469
         * El calculo de la bounding box rotada lo hace con los valores de transformaci?n leidos desde el fichero .rmf.
470
         * </p>
471
         * <P>
472
         * Para el calculo de una esquina aplicamos la formula siguiente:<BR>
473
         * PtoX = originX + pixelSizeX * x + shearX * y;<BR>
474
         * PtoY = originY + shearY * x + pixelSizeY * y;<BR>
475
         * Aplicandolo a las cuatro esquinas sustituimos en cada una de ellas por.
476
         * </P>
477
         * <UL> 
478
         * <LI>Esquina superior izquierda: x = 0; y = 0;</LI>
479
         * <LI>Esquina superior derecha: x = MaxX; y = 0;</LI>
480
         * <LI>Esquina inferior izquierda: x = 0; y = MaxY;</LI>
481
         * <LI>Esquina inferior derecha: x = MaxX; y = MaxY;</LI>
482
         * </UL> 
483
         * <P>
484
         * quedandonos en los cuatro casos:
485
         * </P>
486
         * <UL> 
487
         * <LI>Esquina superior izquierda: originX; originY;</LI>
488
         * <LI>Esquina superior derecha: PtoX = originX + pixelSizeX * x; PtoY = originY + shearY * x;</LI>
489
         * <LI>Esquina inferior izquierda:  PtoX = originX + shearX * y; PtoY = originY + pixelSizeY * y;</LI>
490
         * <LI>Esquina inferior derecha: PtoX = originX + pixelSizeX * x + shearX * y; PtoY = originY + shearY * x + pixelSizeY * y;</LI>
491
         * </UL>
492
         * 
493
         * <P>
494
         * El calculo de la bounding box se realizar? de la misma forma pero anulando los parametros de shearing.
495
         * </P>
496
         * 
497
         * @param originX Coordenada X de origen del raster
498
         * @param originY Coordenada Y de origen del raster
499
         * @param pixelSizeX Tama?o de pixel en X
500
         * @param pixelSizeY Tama?o de pixel en Y
501
         * @param imageWidth Ancho del raster en pixels
502
         * @param imageHeight Alto del raster en pixels
503
         * @param shearX Shearing en X
504
         * @param shearY Shearing en Y
505
         */
506
        private void createExtentsFromRMF(        double originX, double originY, double pixelSizeX, double pixelSizeY, 
507
                                                                                double imageWidth, double imageHeight, double shearX, double shearY){
508
                                
509
                Point2D p1 = new Point2D.Double(originX, originY);
510
                Point2D p2 = new Point2D.Double(originX + shearX * imageHeight, originY + pixelSizeY * imageHeight);
511
                Point2D p3 = new Point2D.Double(originX + pixelSizeX * imageWidth, originY + shearY * imageWidth);
512
                Point2D p4 = new Point2D.Double(originX + pixelSizeX * imageWidth + shearX * imageHeight, originY + pixelSizeY * imageHeight + shearY * imageWidth);
513
                
514
                double minX = Math.min(Math.min(p1.getX(), p2.getX()), Math.min(p3.getX(), p4.getX()));
515
                double minY = Math.min(Math.min(p1.getY(), p2.getY()), Math.min(p3.getY(), p4.getY()));
516
                double maxX = Math.max(Math.max(p1.getX(), p2.getX()), Math.max(p3.getX(), p4.getX()));
517
                double maxY = Math.max(Math.max(p1.getY(), p2.getY()), Math.max(p3.getY(), p4.getY()));
518
                extent = new Extent(minX, minY, maxX, maxY);
519
                requestExtent = new Extent(originX, originY, originX + (pixelSizeX * imageWidth), originY + (pixelSizeY * imageHeight));
520
        }
521
        
522
        /**
523
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
524
         * asociado. Esta transformaci?n tiene diferencias entre los distintos formatos por lo que debe calcularla
525
         * el driver correspondiente.
526
         * @param originX Origen de la imagen en la coordenada X
527
         * @param originY Origen de la imagen en la coordenada Y
528
         */
529
        abstract public void setExtentTransform(double originX, double originY, double psX, double psY);
530
                        
531
        /**
532
         * Obtiene el ancho de la imagen
533
         * @return Ancho de la imagen
534
         */
535
        abstract public int getWidth();
536
        
537
        /**
538
         * Obtiene el ancho de la imagen
539
         * @return Ancho de la imagen
540
         */
541
        abstract public int getHeight();
542

    
543
        /**
544
         * Reproyecci?n.
545
         * @param rp        Coordenadas de la transformaci?n
546
         */
547
        abstract public void reProject(ICoordTrans rp);
548

    
549
        /**
550
         * Asigna un nuevo Extent 
551
         * @param e        Extent
552
         */
553
        abstract public void setView(Extent e);
554
        
555
        /**
556
         * Obtiene el extent asignado
557
         * @return        Extent
558
         */
559
        abstract public Extent getView();
560
                                
561
        /**
562
         * Obtiene el valor del raster en la coordenada que se le pasa.
563
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
564
         * raster.
565
         * @param x        coordenada X
566
         * @param y coordenada Y
567
         * @return
568
         */
569
        abstract public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
570

    
571
        /**
572
         * Obtiene el n?nero de bandas del fichero
573
         * @return Entero que representa el n?mero de bandas
574
         */
575
        public int getBandCount() { 
576
                return bandCount; 
577
        }
578
                
579
        /**
580
         * @return Returns the dataType.
581
         */
582
        public int getDataType() {
583
                return dataType;
584
        }
585
        
586
        /**
587
         * @param dataType The dataType to set.
588
         */
589
        public void setDataType(int dataType) {
590
                this.dataType = dataType;
591
        }
592
   
593
        /**
594
         * Cosulta si hay que verificar la relaci?n de aspecto de la imagen, es decir comprueba que el ancho/alto
595
         * pasados a updateImage coinciden con el ancho/alto solicitado en setView a la imagen
596
         * @return true si est? verificando la relaci?n de aspecto. 
597
         */
598
        public boolean mustVerifySize() {
599
                return verifySize;
600
        }
601

    
602
        /**
603
         * Asigna el flag que dice si hay que verificar la relaci?n de aspecto de la imagen, es decir 
604
         * comprueba que el ancho/alto pasados a updateImage coinciden con el ancho/alto solicitado 
605
         * en setView a la imagen.
606
         * @return true si est? verificando la relaci?n de aspecto. 
607
         */
608
        public void setMustVerifySize(boolean verifySize) {
609
                this.verifySize = verifySize;
610
        }
611

    
612
        /**
613
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
614
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
615
         * pixeles de disco. 
616
         * @param x Posici?n X superior izquierda
617
         * @param y Posici?n Y superior izquierda
618
         * @param w Ancho en coordenadas reales
619
         * @param h Alto en coordenadas reales
620
         * @param rasterBuf        Buffer de datos
621
         * @param bandList
622
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
623
         * @return Buffer de datos
624
         */
625
        abstract public IBuffer getWindowRaster(double x, double y, double w, double h, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent);
626
        
627
        /**
628
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
629
         * Se aplica supersampleo o subsampleo dependiendo del tama?o del buffer especificado.
630
         * 
631
         * @param minX Posici?n m?nima X superior izquierda
632
         * @param minY Posici?n m?nima Y superior izquierda
633
         * @param maxX Posici?n m?xima X inferior derecha
634
         * @param maxY Posici?n m?xima Y inferior derecha
635
         * @param bufWidth Ancho del buffer de datos
636
         * @param bufHeight Alto del buffer de datos
637
         * @param rasterBuf        Buffer de datos
638
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
639
         * @param bandList
640
         * @return Buffer de datos
641
         */
642
        abstract public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent);
643
        
644
        /**
645
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel. 
646
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
647
         * pixeles de disco. 
648
         * @param x Posici?n X superior izquierda
649
         * @param y Posici?n Y superior izquierda
650
         * @param w Ancho en coordenadas reales
651
         * @param h Alto en coordenadas reales
652
         * @param rasterBuf        Buffer de datos
653
         * @param bandList
654
         * @return Buffer de datos
655
         */
656
        abstract public IBuffer getWindowRaster(int x, int y, int w, int h, BandList bandList, IBuffer rasterBuf);
657
        
658
        /**
659
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel. 
660
         * Se aplica supersampleo o subsampleo dependiendo del tama?o del buffer especificado.
661
         * 
662
         * @param x Posici?n X superior izquierda
663
         * @param y Posici?n Y superior izquierda
664
         * @param w Ancho en coordenadas reales
665
         * @param h Alto en coordenadas reales
666
         * @param bufWidth Ancho del buffer de datos
667
         * @param bufHeight Alto del buffer de datos
668
         * @param rasterBuf        Buffer de datos
669
         * @param bandList
670
         * @return Buffer de datos
671
         */
672
        abstract public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf);
673
        
674
        abstract public int getBlockSize();
675
        
676
        /**
677
         * Obtiene el objeto que contiene los metadatos. Este m?todo debe ser redefinido por los
678
         * drivers si necesitan devolver metadatos. 
679
         * @return
680
         */
681
        public DatasetMetadata getMetadata(){
682
                return null;
683
        }
684
        
685
        /**
686
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
687
         * color por banda
688
         * @return
689
         */
690
        public DatasetColorInterpretation getColorInterpretation(){
691
                return null;
692
        }
693
        
694
        /**
695
         * Asigna un extent temporal que puede coincidir con el de la vista. Esto es 
696
         * util para cargar imagenes sin georreferenciar ya que podemos asignar el extent
697
         * que queramos para ajustarnos a una vista concreta
698
         * @param tempExtent The tempExtent to set.
699
         */
700
        public void setExtent(Extent ext) {
701
                this.extent = ext;
702
        }
703
        
704
        /**
705
         * Dice si el fichero tiene georreferenciaci?n o no.
706
         * @return true si tiene georreferenciaci?n y false si no la tiene
707
         */
708
        public boolean isGeoreferenced(){
709
                return true;
710
        }
711

    
712
        /**
713
         * Obtiene el objeto paleta. Esta paleta es la que tiene adjunta el fichero de disco. Si es
714
         * null este objeto quiere decir que no tiene paleta para su visualizaci?n. 
715
         * @return Palette
716
         */
717
        public DatasetPalette getPalette() {
718
                return null;
719
        }
720
        
721
        /**
722
         * M?todo que indica si existe un fichero .rmf asociado al GeoRasterFile.
723
         * @return
724
         */
725
        public boolean rmfExists(){
726
                return this.rmfExists;
727
        }
728
                
729
        /**
730
         * Obtiene los par?metros de la transformaci?n af?n que corresponde con los elementos de
731
         * un fichero tfw.
732
         * <UL> 
733
         * <LI>[1]tama?o de pixel en X</LI>
734
         * <LI>[2]rotaci?n en X</LI>
735
         * <LI>[4]rotaci?n en Y</LI>
736
         * <LI>[5]tama?o de pixel en Y</LI>
737
         * <LI>[0]origen en X</LI>
738
         * <LI>[3]origen en Y</LI>
739
         * </UL>
740
         * Este m?todo debe ser reimplementado por el driver si tiene esta informaci?n. En principio
741
         * Gdal es capaz de proporcionarla de esta forma.
742
         * @return vector de double con los elementos de la transformaci?n af?n.
743
         */
744
        public double[] getTransform(){
745
                return null;
746
        }
747

    
748
        /**
749
         * Obtiene el estado de transparencia de un GeoRasterFile. 
750
         * @return Objeto TransparencyFileStatus
751
         */
752
        public DatasetTransparency getTransparencyDatasetStatus() {
753
                return null;
754
        }
755
        
756
        /**
757
         * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster. 
758
         * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que 
759
         * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el 
760
         * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
761
         * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
762
         * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
763
         * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
764
         * el driver autom?ticamente.
765
         * @param dWorldTLX Coordenada real X superior izquierda
766
         * @param dWorldTLY Coordenada real Y superior izquierda
767
         * @param dWorldBRX Coordenada real X inferior derecha
768
         * @param dWorldBRY Coordenada real Y inferior derecha
769
         * @param nWidth Ancho del raster
770
         * @param nHeight Alto del raster
771
         * @param bufWidth Ancho del buffer
772
         * @param bufHeight Alto del buffer
773
         * @return Array de dos elementos con el desplazamiento en X e Y. 
774
         */
775
        public int[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY, 
776
                        double nWidth, double nHeight, int bufWidth, int bufHeight){
777
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
778
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
779
                                
780
        int x = (int) tl.getX();
781
        int y = (int) tl.getY();
782

    
783
                int stpX = (int)(((tl.getX() - x) * bufWidth) / Math.abs(br.getX() - tl.getX()));
784
                int stpY = (int)(((tl.getY() - y) * bufHeight) / Math.abs(br.getY() - tl.getY()));
785
                
786
                return new int[]{stpX, stpY};
787
        }
788
        
789
        /**
790
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
791
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
792
         * @param nLine N?mero de l?nea a leer
793
         * @param band Banda requerida
794
         * @return Object que es un array unidimendional del tipo de datos del raster
795
         * @throws GdalException
796
         */
797
        abstract public Object readCompleteLine(int line, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException;
798
        
799
        /**
800
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
801
         * @param pt Punto a transformar
802
         * @return punto transformado en coordenadas del mundo
803
         */
804
        abstract public Point2D rasterToWorld(Point2D pt);
805
        
806
        /**
807
         * Convierte un punto desde del mundo a coordenadas pixel.
808
         * @param pt Punto a transformar
809
         * @return punto transformado en coordenadas pixel
810
         */
811
        abstract public Point2D worldToRaster(Point2D pt);
812

    
813
        /**
814
         * Obtiene las estadisticas asociadas al fichero
815
         * @return Objeto con las estadisticas
816
         */
817
        public DatasetStatistics getStatistics() {
818
                return stats;
819
        }
820
        
821
        /**
822
         * Obtiene el histograma asociado al dataset. Este puede ser obtenido 
823
         * completo o seg?n una lista de clases pasada.
824
         * 
825
         * @return Histograma asociado al dataset.
826
         */
827
        public DatasetHistogram getHistogram(){
828
                if (histogram == null)
829
                        histogram = new DatasetHistogram(this);
830
                return histogram;
831
        }
832
        
833
        public void resetPercent() {
834
                if (histogram != null) histogram.resetPercent();
835
        }
836

    
837
        public int getPercent() {
838
                if (histogram != null) return histogram.getPercent();
839
                return 0;
840
        }
841
        
842
        public void setCanceled(boolean value) {
843
                if (histogram != null) histogram.setCanceled(value);
844
        }
845

    
846
        public boolean isCanceled() {
847
                if (histogram != null) return histogram.isCanceled();
848
                return false;
849
        }
850
                
851
}