Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / io / GdalDriver.java @ 12494

History | View | Annotate | Download (17.5 KB)

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

    
21
import java.awt.geom.NoninvertibleTransformException;
22
import java.awt.geom.Point2D;
23
import java.awt.geom.Rectangle2D;
24

    
25
import org.cresques.cts.ICoordTrans;
26
import org.cresques.cts.IProjection;
27
import org.gvsig.raster.dataset.BandList;
28
import org.gvsig.raster.dataset.FileNotOpenException;
29
import org.gvsig.raster.dataset.GeoInfo;
30
import org.gvsig.raster.dataset.IBuffer;
31
import org.gvsig.raster.dataset.InvalidSetViewException;
32
import org.gvsig.raster.dataset.NotSupportedExtensionException;
33
import org.gvsig.raster.dataset.RasterDataset;
34
import org.gvsig.raster.dataset.RasterDriverException;
35
import org.gvsig.raster.dataset.io.rmf.ParsingException;
36
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
37
import org.gvsig.raster.dataset.properties.DatasetMetadata;
38
import org.gvsig.raster.datastruct.ColorTable;
39
import org.gvsig.raster.datastruct.Extent;
40
import org.gvsig.raster.datastruct.Transparency;
41
import org.gvsig.raster.util.RasterUtilities;
42
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
43
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
44

    
45
import es.gva.cit.jgdal.GdalException;
46

    
47
/**
48
 * Clase que representa al driver de acceso a datos de gdal.
49
 * @author Luis W. Sevilla
50
 * @author Nacho Brodin (nachobrodin@gmail.com)
51
 */
52
public class GdalDriver extends RasterDataset {
53
        public final static int         BAND_HEIGHT = 64;
54
        protected GdalNative                 file = null;
55

    
56
        public GdalDriver(){super(null, null);}
57
        
58
        private Extent viewRequest = null;
59
        
60
        public static void register() {
61
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
62
                extensionPoints.add("RasterReader", "bmp", GdalDriver.class);
63
                extensionPoints.add("RasterReader", "gif", GdalDriver.class);
64
                extensionPoints.add("RasterReader", "tif", GdalDriver.class);
65
                extensionPoints.add("RasterReader", "tiff",GdalDriver.class);
66
                extensionPoints.add("RasterReader", "jpg", GdalDriver.class);
67
                extensionPoints.add("RasterReader", "png", GdalDriver.class);
68
                extensionPoints.add("RasterReader", "vrt", GdalDriver.class);
69
                extensionPoints.add("RasterReader", "dat", GdalDriver.class); // Envi
70
                extensionPoints.add("RasterReader", "lan", GdalDriver.class); // Erdas
71
                extensionPoints.add("RasterReader", "gis", GdalDriver.class); // Erdas
72
                extensionPoints.add("RasterReader", "img", GdalDriver.class); // Erdas
73
                extensionPoints.add("RasterReader", "pix", GdalDriver.class); // PCI Geomatics
74
                extensionPoints.add("RasterReader", "aux", GdalDriver.class); // PCI Geomatics
75
                extensionPoints.add("RasterReader", "adf", GdalDriver.class); // ESRI Grids
76
                extensionPoints.add("RasterReader", "mpr", GdalDriver.class); // Ilwis
77
                extensionPoints.add("RasterReader", "mpl", GdalDriver.class); // Ilwis
78
                extensionPoints.add("RasterReader", "map", GdalDriver.class); // PC Raster
79
                extensionPoints.add("RasterReader", "asc", GdalDriver.class);
80
                extensionPoints.add("RasterReader", "pgm", GdalDriver.class); //Ficheros PNM en escala de grises
81
                extensionPoints.add("RasterReader", "ppm", GdalDriver.class); //Ficheros PNM en RGB
82
                extensionPoints.add("RasterReader", "rst", GdalDriver.class); //IDRISIS
83
                extensionPoints.add("RasterReader", "rmf", GdalDriver.class); //Raster Matrix Format
84
                extensionPoints.add("RasterReader", "nos", GdalDriver.class);
85
                extensionPoints.add("RasterReader", "kap", GdalDriver.class); 
86
        }
87
        
88
        public GdalDriver(IProjection proj, Object param)throws NotSupportedExtensionException {
89
                super(proj, param);
90
                setParam(param);
91
                extent = new Extent();
92
                try {
93
                        if(param instanceof String) {
94
                                file = new GdalNative(((String)param));
95
                                load();                        
96
                        }else {
97
                                //TODO: FUNCIONALIDAD: Formatos gestionados por gdal que no tienen extensi?n. Estos tendr?n un objeto IRegistrableRasterFormat Por ej: Grass
98
                        }
99
                        bandCount = file.getRasterCount(); 
100
                } catch (GdalException e) {
101
                        e.printStackTrace();
102
                        throw new NotSupportedExtensionException("Extension not supported");
103
                } catch(Exception e) {
104
                          System.out.println("Error en GdalOpen");
105
                          e.printStackTrace();
106
                          file = null;
107
                }
108
                
109
                //Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
110
                setDataType(RasterUtilities.getRasterBufTypeFromGdalType(file.getDataType()));
111
                
112
                super.init();
113
                
114
                try {
115
                        loadFromRmf(getRmfBlocksManager());
116
                } catch (ParsingException e) {
117
                        //No lee desde rmf
118
                }        
119
        }
120
        
121
        /**
122
         * Obtenemos o calculamos el extent de la imagen.
123
         */
124
        public GeoInfo load() {
125
                extent = new Extent(file.bBoxRot.minX, file.bBoxRot.minY, file.bBoxRot.maxX, file.bBoxRot.maxY);
126
                requestExtent = new Extent(file.bBoxWithoutRot.minX, file.bBoxWithoutRot.minY, file.bBoxWithoutRot.maxX, file.bBoxWithoutRot.maxY);
127
                return this;
128
        }
129
        
130
        /**
131
         * Cierra el fichero de imagen
132
         */
133
        public void close() {
134
                try {
135
                        if(file != null){
136
                                file.close();
137
                                file = null;
138
                        }
139
                } catch (GdalException e) {
140
                        e.printStackTrace();
141
                }
142
        }
143
                
144
        /**
145
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci?n
146
         * de la vista asignada ya que la petici?n viene en coordenadas del fichero .rmf y la vista (v)
147
         * ha de estar en coordenadas del fichero.
148
         */
149
        public void setView(Extent e) { 
150
                if(rmfExists) {
151
                        
152
                        Point2D.Double petInit = null, petEnd = null;
153
                        try {
154
                                petInit = new Point2D.Double(e.minX(), e.maxY());
155
                                petEnd = new Point2D.Double(e.maxX(), e.minY());
156
                                transformRMF.inverseTransform(petInit, petInit);
157
                                transformRMF.inverseTransform(petEnd, petEnd);
158
                                transformTFW.transform(petInit, petInit);
159
                                transformTFW.transform(petEnd, petEnd);
160
                        } catch(NoninvertibleTransformException ex) {
161
                                
162
                        }
163
                        
164
                        if(!file.georeferenced) {
165
                                double h = file.bBoxWithoutRot.maxY - file.bBoxWithoutRot.minY;
166
                                viewRequest = new Extent(petInit.getX(), h - petInit.getY(), petEnd.getX(), h - petEnd.getY()); 
167
                        } else
168
                                viewRequest = new Extent(petInit.getX(), petInit.getY(), petEnd.getX(), petEnd.getY());
169
                        
170
                }else
171
                        viewRequest = new Extent(e.minX(), e.minY(), e.maxX(), e.maxY());        
172
        }
173
                
174
         /**
175
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
176
         * asociado. En Gdal el origen de coordenadas en Y es el valor m?nimo y crece hasta el m?ximo. De la
177
         * misma forma calcula la matriz de transformaci?n de la cabecera del fichero o del world file asociado
178
         * @param originX Origen de la imagen en la coordenada X
179
         * @param originY Origen de la imagen en la coordenada Y
180
         */
181
        public void setExtentTransform(double originX, double originY, double psX, double psY) {                
182
                transformRMF.setToTranslation(originX, originY);
183
                transformRMF.scale(psX, psY);
184
                
185
                if(file.trans != null){        
186
                        transformTFW.setToTranslation(file.trans.adfgeotransform[0], file.trans.adfgeotransform[3]);
187
                        transformTFW.scale(file.trans.adfgeotransform[1], file.trans.adfgeotransform[5]);
188
                }                
189
        }
190
        
191
        /**
192
         * Obtiene extent de la vista actual
193
         */
194
        public Extent getView() { 
195
                return viewRequest; 
196
        }
197
        
198
        /**
199
         * Obtiene la anchura del fichero
200
         */
201
        public int getWidth() {        
202
                return file.width; 
203
        }
204
        
205
        /**
206
         * Obtiene la altura del fichero
207
         */
208
        public int getHeight() { 
209
                return file.height;
210
        }
211
        
212
        /**
213
         * Obtiene la orientaci?n de la imagen a partir del signo del tama?o de pixel para poder
214
         * asignarlo en el setView. Esto es util para poder conocer como debe leerse la image, 
215
         * de abajo a arriba, de arriba a abajo, de izquierda a derecha o de derecha a izquierda. 
216
         * La posici?n habitual es la que el pixel size en X es positivo y en Y negativo leyendose 
217
         * en este caso las X de menor a mayor y las Y de mayor a menor. Los casos posibles son:
218
         * <UL>
219
         * <LI><B>X > 0; Y < 0;</B> {true, false}</LI>
220
         * <LI><B>X > 0; Y > 0;</B> {true, true}</LI>
221
         * <LI><B>X < 0; Y > 0;</B> {false, true}</LI>
222
         * <LI><B>X < 0; Y < 0;</B> {false, false}</LI>
223
         * </UL>
224
         *  
225
         * @return
226
         */
227
        private boolean[] getOrientation(){
228
                boolean[] orientation = {true, false};
229
                if(!rmfExists){
230
                        if(file.trans != null && file.trans.adfgeotransform != null && file.trans.adfgeotransform[5] > 0)
231
                                orientation[1] = true;
232
                        if(file.trans != null && file.trans.adfgeotransform != null && file.trans.adfgeotransform[1] < 0)
233
                                orientation[0] = false;
234
                }else{
235
                        if(rmfTransform.getScaleY() > 0)
236
                                orientation[1] = true;
237
                        if(rmfTransform.getScaleX() < 0)
238
                                orientation[0] = false;
239
                }
240
                return orientation;
241
        }
242
        
243
        /*
244
         *  (non-Javadoc)
245
         * @see org.gvsig.fmap.driver.GeoRasterFile#readCompletetLine(int, int)
246
         */
247
        public Object readCompleteLine(int line, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
248
                if(line > this.getHeight() || band > this.getBandCount())
249
                        throw new InvalidSetViewException("Request out of grid");
250
                
251
                try{
252
                        return file.readCompleteLine(line, band);
253
                }catch(GdalException e){
254
                        throw new RasterDriverException("Error reading data from Gdal library");
255
                }
256
        }
257
        
258
        /*
259
         *  (non-Javadoc)
260
         * @see org.gvsig.raster.dataset.RasterDataset#readBlock(int, int)
261
         */         
262
        public Object readBlock(int pos, int blockHeight) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
263
                if(pos < 0)
264
                        throw new InvalidSetViewException("Request out of grid");
265
                
266
                if((pos + blockHeight) > getHeight())
267
                        blockHeight = Math.abs(getHeight() - pos);
268
                try{
269
                        return file.readBlock(pos, blockHeight);
270
                }catch(GdalException e){
271
                        throw new RasterDriverException("Error reading data from Gdal library");
272
                }
273
        }
274
                        
275
        /* (non-Javadoc)
276
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
277
         */
278
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
279
                if(file != null){
280
                        if(x < 0 || y < 0 || x >= file.width || y >= file.height)
281
                                throw new InvalidSetViewException("Request out of grid");
282
                        Object[] data = file.getData(x, y);
283
                        return data[band];
284
                }
285
                throw new FileNotOpenException("GdalNative not exist");
286
        }
287
        
288
        /*
289
         *  (non-Javadoc)
290
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(double, double, double, double, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
291
         */
292
        public IBuffer getWindowRaster(double x, double y, double w, double h, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) {                
293
                Extent selectedExtent = new Extent(x, y, x + w, y - h);
294
                setView(selectedExtent);
295
                                
296
                try {
297
                        file.readWindow(rasterBuf, bandList, viewRequest.minX(), viewRequest.maxY(), viewRequest.maxX(), viewRequest.minY(), rasterBuf.getWidth(), rasterBuf.getHeight(), adjustToExtent);
298
                } catch (Exception e) {
299
                        e.printStackTrace();
300
                }
301
                
302
                return rasterBuf;
303
        }
304
                        
305
        /*
306
         *  (non-Javadoc)
307
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
308
         */
309
        public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) {                
310
                Extent selectedExtent = new Extent(minX, minY, maxX, maxY);
311
                setView(selectedExtent);
312
                
313
                double width = 0;
314
                double height = 0;
315
                if(getTransform() != null){
316
                        width = (double)(Math.abs(viewRequest.width() / getTransform()[1]));//(int)(selectedExtent.width() * file.width) / extent.width();
317
                        height = (double)(Math.abs(viewRequest.height() / getTransform()[5]));
318
                }else{
319
                        width = (double)Math.abs(viewRequest.width());
320
                        height = (double)Math.abs(viewRequest.height());
321
                }
322
                                
323
                try {
324
                        file.readWindow(rasterBuf, bandList, viewRequest.minX(), viewRequest.maxY(), viewRequest.maxX(), viewRequest.minY(), width, height, bufWidth, bufHeight, adjustToExtent);
325
                } catch (Exception e) {
326
                        e.printStackTrace();
327
                }
328
                
329
                return rasterBuf;
330
        }
331
        
332
        /*
333
         *  (non-Javadoc)
334
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(int, int, int, int, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
335
         */
336
        public IBuffer getWindowRaster(int x, int y, int w, int h, BandList bandList, IBuffer rasterBuf) {
337
                try {
338
                        setView(
339
                        new Extent( RasterUtilities.getMapRectFromPxRect(getExtent().toRectangle2D(), 
340
                                                getWidth(), 
341
                                                getHeight(),
342
                                                new Rectangle2D.Double(x, y, w, h)))
343
                        );
344
                        file.readWindow(rasterBuf, bandList, x, y, w, h);
345
                } catch (Exception e) {
346
                        e.printStackTrace();
347
                }
348
                return rasterBuf;
349
        }
350
        
351
        /*
352
         *  (non-Javadoc)
353
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(int, int, int, int, int, int, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
354
         */
355
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf) {
356
                try {
357
                        setView(
358
                        new Extent( RasterUtilities.getMapRectFromPxRect(getExtent().toRectangle2D(), 
359
                                                getWidth(), 
360
                                                getHeight(),
361
                                                new Rectangle2D.Double(x, y, w, h)))
362
                        );
363
                        file.readWindow(rasterBuf, bandList, x, y, w, h, bufWidth, bufHeight);
364
                } catch (Exception e) {
365
                        e.printStackTrace();
366
                }
367
                return rasterBuf;
368
        }
369
                
370
        /**
371
         * Devuelve el tama?o de bloque
372
         * @return Tama?o de bloque
373
         */
374
        public int getBlockSize(){
375
                if(file != null)
376
                        return file.getBlockSize();
377
                else
378
                        return 0;
379
        }
380
        
381
        /**
382
         * Obtiene el objeto que contiene los metadatos
383
         */
384
        public DatasetMetadata getMetadata() {
385
                if(file != null)
386
                        return file.metadata;
387
                else
388
                        return null;
389
        }
390
        
391
        /**
392
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
393
         * color por banda
394
         * @return
395
         */
396
        public DatasetColorInterpretation getColorInterpretation(){
397
                if(file != null)
398
                        return file.colorInterpr;
399
                return null;
400
        }
401
        
402
        /**
403
         * Obtiene el objeto que contiene el estado de la transparencia
404
         */
405
        public Transparency getTransparencyDatasetStatus() {
406
                return file.fileTransparency;
407
        }
408
        
409
        /**
410
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
411
         * @return true si est? georreferenciada y false si no lo est?.
412
         */
413
        public boolean isGeoreferenced() {
414
                if(file != null)
415
                        return file.georeferenced;
416
                else 
417
                        return false;
418
        }
419
    
420
        /**
421
         * Obtiene el objeto que contiene la paleta de color.
422
         */
423
        public ColorTable getColorTable() {
424
                if(file != null)
425
                        return file.palette;
426
                else
427
                        return null;
428
        }
429
        
430
        /**
431
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
432
         * el valor de esta variable cada vez que dibuja. 
433
         * @return true si se ha supersampleado y false si no se ha hecho.
434
         */
435
        public boolean isSupersampling() {
436
                if(file != null)
437
                        return file.isSupersampling;
438
                else 
439
                        return false;
440
        }
441
        
442
        /**
443
         * Obtiene los par?metros de la transformaci?n af?n que corresponde con los elementos de
444
         * un fichero tfw.
445
         * <UL> 
446
         * <LI>[1]tama?o de pixel en X</LI>
447
         * <LI>[2]rotaci?n en X</LI>
448
         * <LI>[4]rotaci?n en Y</LI>
449
         * <LI>[5]tama?o de pixel en Y</LI>
450
         * <LI>[0]origen en X</LI>
451
         * <LI>[3]origen en Y</LI>
452
         * </UL>
453
         * Este m?todo debe ser reimplementado por el driver si tiene esta informaci?n. En principio
454
         * Gdal es capaz de proporcionarla de esta forma.
455
         * 
456
         * En caso de que exista fichero .rmf asociado al raster pasaremos de la informaci?n de georreferenciaci?n
457
         * del .tfw y devolveremos la que est? asociada al rmf
458
         * @return vector de double con los elementos de la transformaci?n af?n.
459
         */
460
        public double[] getTransform(){
461
                if(file != null && file.trans != null && !rmfExists())
462
                        return file.trans.adfgeotransform;
463
                else{
464
                        if(this.rmfExists){
465
                                double[] rmfGeoref = {        rmfTransform.getTranslateX(), 
466
                                                                                rmfTransform.getScaleX(),
467
                                                                                rmfTransform.getShearX(), 
468
                                                                                rmfTransform.getTranslateY(),
469
                                                                                rmfTransform.getShearY(),
470
                                                                                rmfTransform.getScaleY()};
471
                                return rmfGeoref;
472
                        }
473
                        return null;
474
                }
475
                
476
        }
477
        
478
        /*
479
         *  (non-Javadoc)
480
         * @see org.gvsig.fmap.driver.GeoRasterFile#rasterToWorld(java.awt.geom.Point2D)
481
         */
482
        public Point2D rasterToWorld(Point2D pt) {
483
                return file.rasterToWorld(pt);
484
        }
485
        
486
        /*
487
         *  (non-Javadoc)
488
         * @see org.gvsig.fmap.driver.GeoRasterFile#worldToRaster(java.awt.geom.Point2D)
489
         */
490
        public Point2D worldToRaster(Point2D pt){
491
                return file.worldToRaster(pt);
492
        }
493
                
494
        public GdalNative getNative(){
495
                return file;
496
        }
497

    
498
        /**
499
         * Obtiene el nombre del driver
500
         */
501
        public String getName() {
502
                return "gvSIG Gdal Raster Driver";
503
        }
504
        
505
        /*
506
         * (non-Javadoc)
507
         * @see org.gvsig.raster.driver.GeoData#getStringProjection()
508
         */
509
        public String getWktProjection() throws RasterDriverException{
510
                try {
511
                        return file.getProjectionRef();
512
                } catch (GdalException e) {
513
                        throw new RasterDriverException("Error getting projection");
514
                }
515
        }
516

    
517
        /*
518
         *  (non-Javadoc)
519
         * @see org.gvsig.raster.dataset.RasterDataset#setCanceled(boolean, int)
520
         */
521
        public void setCanceled(boolean value, int process) {
522
                super.setCanceled(value, process);
523
                
524
                if(process == CANCEL_READ || process == 0)
525
                        file.readCancel = value;
526
        }
527

    
528
        /*
529
         *  (non-Javadoc)
530
         * @see org.gvsig.raster.dataset.RasterDataset#isCanceled(int)
531
         */
532
        public boolean isCanceled(int process) {
533
                if(process == CANCEL_READ) {
534
                        return file.readCancel;
535
                } else
536
                        return super.isCanceled(process);
537
        }
538
        
539
        public void reProject(ICoordTrans rp) {
540

    
541
        }
542
}
543

    
544

    
545