Statistics
| Revision:

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

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

    
528
        public String getName() {
529
                return "gvSIG Gdal Raster Driver";
530
        }
531
        
532
        /*
533
         * (non-Javadoc)
534
         * @see org.gvsig.raster.driver.GeoData#getStringProjection()
535
         */
536
        public String getStringProjection() throws RasterDriverException{
537
                try {
538
                        return file.getProjectionRef();
539
                } catch (GdalException e) {
540
                        throw new RasterDriverException("Error getting projection");
541
                }
542
        }
543

    
544
        public void reProject(ICoordTrans rp) {
545
                // TODO Auto-generated method stub
546
                
547
        }
548
}
549

    
550

    
551