Statistics
| Revision:

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

History | View | Annotate | Download (29.7 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.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.DatasetPalette;
42
import org.gvsig.raster.dataset.properties.DatasetStatistics;
43
import org.gvsig.raster.dataset.properties.DatasetTransparency;
44
import org.gvsig.raster.shared.Extent;
45
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
46
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
47
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
48
import org.kxml2.io.KXmlParser;
49
import org.xmlpull.v1.XmlPullParserException;
50

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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