Statistics
| Revision:

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

History | View | Annotate | Download (18.2 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.properties.DatasetColorInterpretation;
36
import org.gvsig.raster.dataset.properties.DatasetMetadata;
37
import org.gvsig.raster.dataset.properties.DatasetPalette;
38
import org.gvsig.raster.dataset.properties.DatasetTransparency;
39
import org.gvsig.raster.shared.Extent;
40
import org.gvsig.raster.util.RasterUtilities;
41
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
42
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
43

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

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

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

    
550
        public String getName() {
551
                return "gvSIG Gdal Raster Driver";
552
        }
553
        
554
        /*
555
         * (non-Javadoc)
556
         * @see org.gvsig.raster.driver.GeoData#getStringProjection()
557
         */
558
        public String getStringProjection() throws RasterDriverException{
559
                try {
560
                        return file.getProjectionRef();
561
                } catch (GdalException e) {
562
                        throw new RasterDriverException("Error getting projection");
563
                }
564
        }
565

    
566
        public void reProject(ICoordTrans rp) {
567
                // TODO Auto-generated method stub
568
                
569
        }
570

    
571
        
572
}
573

    
574

    
575