Statistics
| Revision:

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

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

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

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

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

    
506
        /*
507
         * (non-Javadoc)
508
         * @see org.gvsig.raster.dataset.RasterDataset#getOverviewWidth(int, int)
509
         */
510
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
511
                if (band >= getBandCount())
512
                        throw new BandAccessException("Wrong band");
513
                try {
514
                        if (overview >= file.getRasterBand(band + 1).getOverviewCount())
515
                                throw new BandAccessException("Wrong overview count");
516
                        return file.getRasterBand(band + 1).getOverview(overview).getRasterBandXSize();
517
                } catch (GdalException e) {
518
                        throw new RasterDriverException("");
519
                }
520
        }
521

    
522
        /*
523
         * (non-Javadoc)
524
         * @see org.gvsig.raster.dataset.RasterDataset#getOverviewWidth(int, int)
525
         */
526
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
527
                if (band >= getBandCount())
528
                        throw new BandAccessException("Wrong band");
529
                try {
530
                        if (overview >= file.getRasterBand(band + 1).getOverviewCount())
531
                                throw new BandAccessException("Wrong overview count");
532
                        return file.getRasterBand(band + 1).getOverview(overview).getRasterBandYSize();
533
                } catch (GdalException e) {
534
                        throw new RasterDriverException("");
535
                }
536
        }
537

    
538
        /*
539
         * (non-Javadoc)
540
         * @see org.gvsig.raster.dataset.RasterDataset#overviewsSupport()
541
         */
542
        public boolean overviewsSupport() {
543
                return true;
544
        }
545
        
546
        /*
547
         * (non-Javadoc)
548
         * @see org.gvsig.raster.dataset.RasterDataset#isReproyectable()
549
         */
550
        public boolean isReproyectable() {
551
                return true;
552
        }
553
}