Statistics
| Revision:

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

History | View | Annotate | Download (17.1 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.AffineTransform;
22
import java.awt.geom.Point2D;
23
import java.awt.geom.Rectangle2D;
24
import java.io.BufferedReader;
25
import java.io.File;
26
import java.io.FileNotFoundException;
27
import java.io.FileReader;
28
import java.io.IOException;
29

    
30
import org.cresques.cts.ICoordTrans;
31
import org.cresques.cts.IProjection;
32
import org.gvsig.raster.dataset.BandAccessException;
33
import org.gvsig.raster.dataset.BandList;
34
import org.gvsig.raster.dataset.FileNotOpenException;
35
import org.gvsig.raster.dataset.GeoInfo;
36
import org.gvsig.raster.dataset.IBuffer;
37
import org.gvsig.raster.dataset.InvalidSetViewException;
38
import org.gvsig.raster.dataset.NotSupportedExtensionException;
39
import org.gvsig.raster.dataset.RasterDataset;
40
import org.gvsig.raster.dataset.io.rmf.ParsingException;
41
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
42
import org.gvsig.raster.dataset.properties.DatasetMetadata;
43
import org.gvsig.raster.datastruct.Extent;
44
import org.gvsig.raster.datastruct.Transparency;
45
import org.gvsig.raster.util.RasterUtilities;
46
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
47
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
48

    
49
import es.gva.cit.jgdal.GdalException;
50

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

    
60
        public GdalDriver(){super(null, null);}
61
        
62
        private Extent viewRequest = null;
63
        
64
        public static void register() {
65
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
66
                extensionPoints.add("RasterReader", "bmp", GdalDriver.class);
67
                extensionPoints.add("RasterReader", "gif", GdalDriver.class);
68
                extensionPoints.add("RasterReader", "tif", GdalDriver.class);
69
                extensionPoints.add("RasterReader", "tiff",GdalDriver.class);
70
                extensionPoints.add("RasterReader", "jpg", GdalDriver.class);
71
                extensionPoints.add("RasterReader", "jpeg", GdalDriver.class);
72
                extensionPoints.add("RasterReader", "png", GdalDriver.class);
73
                extensionPoints.add("RasterReader", "vrt", GdalDriver.class);
74
                extensionPoints.add("RasterReader", "dat", GdalDriver.class); // Envi
75
                extensionPoints.add("RasterReader", "lan", GdalDriver.class); // Erdas
76
                extensionPoints.add("RasterReader", "gis", GdalDriver.class); // Erdas
77
                extensionPoints.add("RasterReader", "img", GdalDriver.class); // Erdas
78
                extensionPoints.add("RasterReader", "pix", GdalDriver.class); // PCI Geomatics
79
                extensionPoints.add("RasterReader", "aux", GdalDriver.class); // PCI Geomatics
80
                extensionPoints.add("RasterReader", "adf", GdalDriver.class); // ESRI Grids
81
                extensionPoints.add("RasterReader", "mpr", GdalDriver.class); // Ilwis
82
                extensionPoints.add("RasterReader", "mpl", GdalDriver.class); // Ilwis
83
                extensionPoints.add("RasterReader", "map", GdalDriver.class); // PC Raster
84
                extensionPoints.add("RasterReader", "asc", GdalDriver.class);
85
                extensionPoints.add("RasterReader", "pgm", GdalDriver.class); //Ficheros PNM en escala de grises
86
                extensionPoints.add("RasterReader", "ppm", GdalDriver.class); //Ficheros PNM en RGB
87
                extensionPoints.add("RasterReader", "rst", GdalDriver.class); //IDRISIS
88
                extensionPoints.add("RasterReader", "rmf", GdalDriver.class); //Raster Matrix Format
89
                extensionPoints.add("RasterReader", "nos", GdalDriver.class);
90
                extensionPoints.add("RasterReader", "kap", GdalDriver.class); 
91
                extensionPoints.add("RasterReader", "hdr", GdalDriver.class);
92
                extensionPoints.add("RasterReader", "raw", GdalDriver.class);
93
        }
94
        
95
        /**
96
         * Constructor del driver de Gdal. Crea las referencias al fichero y carga
97
         * las estructuras con la informaci?n y los metadatos. 
98
         * @param proj Proyecci?n
99
         * @param param Parametros de carga
100
         * @throws NotSupportedExtensionException
101
         */
102
        public GdalDriver(IProjection proj, Object param)throws NotSupportedExtensionException {
103
                super(proj, param);
104
                try {
105
                        if(param instanceof String) {
106
                                setParam(translateFileName((String)param));
107
                                validRmf(((String)param));
108
                                file = new GdalNative(translateFileName((String)param));
109
                                setColorTable(file.palette);
110
                                noData = file.getNoDataValue();
111
                                ownTransformation = file.getOwnTransformation();
112
                                externalTransformation = (AffineTransform)ownTransformation.clone();
113
                                load();                        
114
                        }else {
115
                                setParam(param);
116
                                //TODO: FUNCIONALIDAD: Formatos gestionados por gdal que no tienen extensi?n. Estos tendr?n un objeto IRegistrableRasterFormat Por ej: Grass
117
                        }
118
                        bandCount = file.getRasterCount(); 
119
                } catch (GdalException e) {
120
                        e.printStackTrace();
121
                        throw new NotSupportedExtensionException("Extension not supported");
122
                } catch(Exception e) {
123
                          System.out.println("Error en GdalOpen");
124
                          e.printStackTrace();
125
                          file = null;
126
                }
127
                
128
                //Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
129
                int[] dt = new int[file.getDataType().length];
130
                for (int i = 0; i < dt.length; i++) 
131
                        dt[i] = RasterUtilities.getRasterBufTypeFromGdalType(file.getDataType()[i]);
132
                setDataType(dt);
133
                
134
                super.init();
135
                
136
                try {
137
                        loadFromRmf(getRmfBlocksManager());
138
                } catch (ParsingException e) {
139
                        //No lee desde rmf
140
                }        
141
        }
142
        
143
        /**
144
         * Comprueba si el fichero abierto es un RasterMetaFile o una imagen
145
         * raster. 
146
         * @throws GdalException
147
         */
148
        private void validRmf(String file) throws GdalException {
149
                if(file.endsWith(".rmf")) {
150
                        File f = new File(file);
151
                        FileReader fr;
152
                        try {
153
                                fr = new FileReader(f);
154
                                BufferedReader br = new BufferedReader(fr);
155
                                char[] buffer = new char[5];
156
                            br.read(buffer);
157
                            StringBuffer st = new StringBuffer(new String(buffer));
158
                            if(st.toString().equals("<?xml"))
159
                                    throw new GdalException("RasterMetaFile");
160
                        } catch (FileNotFoundException e) {
161
                                throw new GdalException("File Not Found");
162
                        } catch (IOException e) {
163
                                throw new GdalException("");
164
                        } 
165
                }
166
        }
167
        /**
168
         * Obtenemos o calculamos el extent de la imagen.
169
         */
170
        public GeoInfo load() {
171
                return this;
172
        }
173
        
174
        /**
175
         * Cierra el fichero de imagen
176
         */
177
        public void close() {
178
                try {
179
                        if(file != null){
180
                                file.close();
181
                                file = null;
182
                        }
183
                } catch (GdalException e) {
184
                        e.printStackTrace();
185
                }
186
        }
187
                
188
        /*
189
         * (non-Javadoc)
190
         * @see org.gvsig.raster.dataset.RasterDataset#translateFileName(java.lang.String)
191
         */
192
        public String translateFileName(String fileName) {
193
                if(fileName.endsWith("hdr"))
194
                        return fileName.substring(0, fileName.lastIndexOf("."));
195
                return fileName;
196
        }
197
        
198
        /**
199
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci?n
200
         * de la vista asignada ya que la petici?n viene en coordenadas del fichero .rmf y la vista (v)
201
         * ha de estar en coordenadas del fichero.
202
         */
203
        public void setView(Extent e) { 
204
                viewRequest = e;        
205
        }
206
                
207
        /**
208
         * Obtiene extent de la vista actual
209
         */
210
        public Extent getView() { 
211
                return viewRequest; 
212
        }
213
        
214
        /**
215
         * Obtiene la anchura del fichero
216
         */
217
        public int getWidth() {        
218
                return file.width; 
219
        }
220
        
221
        /**
222
         * Obtiene la altura del fichero
223
         */
224
        public int getHeight() { 
225
                return file.height;
226
        }
227
        
228
        /*
229
         *  (non-Javadoc)
230
         * @see org.gvsig.fmap.driver.GeoRasterFile#readCompletetLine(int, int)
231
         */
232
        public Object readCompleteLine(int line, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
233
                if(line > this.getHeight() || band > this.getBandCount())
234
                        throw new InvalidSetViewException("Request out of grid");
235
                
236
                try{
237
                        return file.readCompleteLine(line, band);
238
                }catch(GdalException e){
239
                        throw new RasterDriverException("Error reading data from Gdal library");
240
                }
241
        }
242
        
243
        /*
244
         *  (non-Javadoc)
245
         * @see org.gvsig.raster.dataset.RasterDataset#readBlock(int, int)
246
         */         
247
        public Object readBlock(int pos, int blockHeight) 
248
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException, InterruptedException {
249
                if(pos < 0)
250
                        throw new InvalidSetViewException("Request out of grid");
251
                
252
                if((pos + blockHeight) > getHeight())
253
                        blockHeight = Math.abs(getHeight() - pos);
254
                try{
255
                        return file.readBlock(pos, blockHeight);
256
                }catch(GdalException e){
257
                        throw new RasterDriverException("Error reading data from Gdal library");
258
                }
259
        }
260
                        
261
        /* (non-Javadoc)
262
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
263
         */
264
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
265
                if(file != null){
266
                        if(x < 0 || y < 0 || x >= file.width || y >= file.height)
267
                                throw new InvalidSetViewException("Request out of grid");
268
                        Object[] data = file.getData(x, y);
269
                        return data[band];
270
                }
271
                throw new FileNotOpenException("GdalNative not exist");
272
        }
273
        
274
        /*
275
         * (non-Javadoc)
276
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer)
277
         */
278
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, BandList bandList, IBuffer rasterBuf) throws InterruptedException, RasterDriverException {
279
                Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
280
                setView(selectedExtent);
281
                                
282
                try {
283
                        file.readWindow(rasterBuf, bandList, viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), rasterBuf.getWidth(), rasterBuf.getHeight(), true);
284
                } catch (GdalException e) {
285
                        throw new RasterDriverException("Error reading data");
286
                }
287
                
288
                return rasterBuf;
289
        }
290
        
291
        /*
292
         *  (non-Javadoc)
293
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(double, double, double, double, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
294
         */
295
        public IBuffer getWindowRaster(double ulx, double uly, double w, double h, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) throws InterruptedException, RasterDriverException {
296
                //El incremento o decremento de las X e Y depende de los signos de rotaci?n y escala en la matriz de transformaci?n. Por esto
297
                //tenemos que averiguar si lrx es x + w o x -w, asi como si lry es y + h o y - h 
298
                Extent ext = getExtent();
299
                Point2D pInit = rasterToWorld(new Point2D.Double(0, 0));
300
                Point2D pEnd = rasterToWorld(new Point2D.Double(getWidth(), getHeight()));
301
                double wRaster = Math.abs(pEnd.getX() - pInit.getX());
302
                double hRaster = Math.abs(pEnd.getY() - pInit.getY());
303
                double lrx = (((ext.getULX() - wRaster) > ext.maxX()) || ((ext.getULX() - wRaster) < ext.minX())) ? (ulx + w) : (ulx - w);
304
                double lry = (((ext.getULY() - hRaster) > ext.maxY()) || ((ext.getULY() - hRaster) < ext.minY())) ? (uly + h) : (uly - h); 
305
                                
306
                Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
307
                setView(selectedExtent);
308
                                
309
                try {
310
                        file.readWindow(rasterBuf, bandList, viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), rasterBuf.getWidth(), rasterBuf.getHeight(), adjustToExtent);
311
                } catch (GdalException e) {
312
                        throw new RasterDriverException("Error reading data");
313
                }
314
                
315
                return rasterBuf;
316
        }
317
                        
318
        /*
319
         *  (non-Javadoc)
320
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
321
         */
322
        public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) throws InterruptedException, RasterDriverException {                
323
                Extent selectedExtent = new Extent(minX, minY, maxX, maxY);
324
                setView(selectedExtent);
325
                
326
                double width = 0;
327
                double height = 0;
328
                
329
                Point2D ul = new Point2D.Double(viewRequest.getULX(), viewRequest.getULY());
330
                Point2D lr = new Point2D.Double(viewRequest.getLRX(), viewRequest.getLRY());
331
                ul = worldToRaster(ul);
332
                lr = worldToRaster(lr);
333
                width = Math.abs(lr.getX() - ul.getX());
334
                height = Math.abs(lr.getY() - ul.getY());
335
                                                
336
                try {
337
                        file.readWindow(rasterBuf, bandList, viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), width, height, bufWidth, bufHeight, adjustToExtent);
338
                } catch (GdalException e) {
339
                        throw new RasterDriverException("Error reading data");
340
                }
341
                
342
                return rasterBuf;
343
        }
344
        
345
        /*
346
         *  (non-Javadoc)
347
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(int, int, int, int, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
348
         */
349
        public IBuffer getWindowRaster(int x, int y, int w, int h, BandList bandList, IBuffer rasterBuf) throws InterruptedException, RasterDriverException {
350
                try {
351
                        setView(
352
                        new Extent( RasterUtilities.getMapRectFromPxRect(getExtent().toRectangle2D(), 
353
                                                getWidth(), 
354
                                                getHeight(),
355
                                                new Rectangle2D.Double(x, y, w, h)))
356
                        );
357
                        file.readWindow(rasterBuf, bandList, x, y, w, h);
358
                } catch (GdalException e) {
359
                        throw new RasterDriverException("Error reading data");
360
                }
361
                return rasterBuf;
362
        }
363
        
364
        /*
365
         *  (non-Javadoc)
366
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(int, int, int, int, int, int, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
367
         */
368
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf) throws InterruptedException, RasterDriverException {
369
                try {
370
                        setView(
371
                        new Extent( RasterUtilities.getMapRectFromPxRect(getExtent().toRectangle2D(), 
372
                                                getWidth(), 
373
                                                getHeight(),
374
                                                new Rectangle2D.Double(x, y, w, h)))
375
                        );
376
                        file.readWindow(rasterBuf, bandList, x, y, w, h, bufWidth, bufHeight);
377
                } catch (GdalException e) {
378
                        throw new RasterDriverException("Error reading data");
379
                }
380
                return rasterBuf;
381
        }
382
                
383
        /**
384
         * Devuelve el tama?o de bloque
385
         * @return Tama?o de bloque
386
         */
387
        public int getBlockSize(){
388
                if(file != null)
389
                        return file.getBlockSize();
390
                else
391
                        return 0;
392
        }
393
        
394
        /**
395
         * Obtiene el objeto que contiene los metadatos
396
         */
397
        public DatasetMetadata getMetadata() {
398
                if(file != null)
399
                        return file.metadata;
400
                else
401
                        return null;
402
        }
403
        
404
        /**
405
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
406
         * color por banda
407
         * @return
408
         */
409
        public DatasetColorInterpretation getColorInterpretation(){
410
                if(file != null)
411
                        return file.colorInterpr;
412
                return null;
413
        }
414
        
415
        /**
416
         * Asigna el objeto que contiene que contiene la interpretaci?n de 
417
         * color por banda
418
         * @param DatasetColorInterpretation
419
         */
420
        public void setColorInterpretation(DatasetColorInterpretation colorInterpretation){
421
                if(file != null)
422
                        file.colorInterpr = colorInterpretation;
423
        }
424
        
425
        /**
426
         * Obtiene el objeto que contiene el estado de la transparencia
427
         */
428
        public Transparency getTransparencyDatasetStatus() {
429
                return file.fileTransparency;
430
        }
431
        
432
        /**
433
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
434
         * @return true si est? georreferenciada y false si no lo est?.
435
         */
436
        public boolean isGeoreferenced() {
437
                if(file != null)
438
                        return file.georeferenced;
439
                else 
440
                        return false;
441
        }
442
    
443
        /**
444
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
445
         * el valor de esta variable cada vez que dibuja. 
446
         * @return true si se ha supersampleado y false si no se ha hecho.
447
         */
448
        public boolean isSupersampling() {
449
                if(file != null)
450
                        return file.isSupersampling;
451
                else 
452
                        return false;
453
        }
454
                                
455
        public GdalNative getNative(){
456
                return file;
457
        }
458

    
459
        /**
460
         * Obtiene el nombre del driver
461
         */
462
        public String getName() {
463
                return "gvSIG Gdal Raster Driver";
464
        }
465
        
466
        /*
467
         * (non-Javadoc)
468
         * @see org.gvsig.raster.driver.GeoData#getStringProjection()
469
         */
470
        public String getWktProjection() throws RasterDriverException {
471
                try {
472
                        return file.getProjectionRef();
473
                } catch (GdalException e) {
474
                        throw new RasterDriverException("Error getting projection");
475
                }
476
        }
477
        
478
        public void reProject(ICoordTrans rp) {
479

    
480
        }
481
        
482
        /*
483
         * (non-Javadoc)
484
         * @see org.gvsig.raster.dataset.RasterDataset#setAffineTransform(java.awt.geom.AffineTransform)
485
         */
486
        public void setAffineTransform(AffineTransform t){
487
                super.setAffineTransform(t);
488
                file.setExternalTransform(t);
489
        }
490

    
491
        /*
492
         * (non-Javadoc)
493
         * @see org.gvsig.raster.dataset.RasterDataset#getOverviewCount(int)
494
         */
495
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
496
                if(band >= getBandCount())
497
                        throw new BandAccessException("Wrong band");
498
                try {
499
                        return file.getRasterBand(band + 1).getOverviewCount();
500
                } catch (GdalException e) {
501
                        throw new RasterDriverException("");
502
                }
503
        }
504
        
505
        /*
506
         * (non-Javadoc)
507
         * @see org.gvsig.raster.dataset.RasterDataset#overviewsSupport()
508
         */
509
        public boolean overviewsSupport() {
510
                return true;
511
        }
512
}
513

    
514

    
515