Statistics
| Revision:

gvsig-raster / org.gvsig.raster.gdal / trunk / org.gvsig.raster.gdal / org.gvsig.raster.gdal.io / src / main / java / org / gvsig / raster / gdal / io / GdalProvider.java @ 4181

History | View | Annotate | Download (18.8 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.gdal.io;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.io.BufferedReader;
26
import java.io.File;
27
import java.io.FileNotFoundException;
28
import java.io.FileReader;
29
import java.io.IOException;
30
import java.net.URI;
31
import java.net.URISyntaxException;
32

    
33
import org.gvsig.fmap.dal.DALFileLocator;
34
import org.gvsig.fmap.dal.DALLocator;
35
import org.gvsig.fmap.dal.DataStore;
36
import org.gvsig.fmap.dal.coverage.RasterLocator;
37
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
38
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
39
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
40
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
41
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
42
import org.gvsig.fmap.dal.coverage.exception.InvalidSourceException;
43
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
44
import org.gvsig.fmap.dal.coverage.exception.ParsingException;
45
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
46
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
47
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
48
import org.gvsig.fmap.dal.exception.OpenException;
49
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
50
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
51
import org.gvsig.jgdal.GdalException;
52
import org.gvsig.metadata.MetadataLocator;
53
import org.gvsig.raster.cache.tile.provider.TileServer;
54
import org.gvsig.raster.impl.buffer.SpiRasterQuery;
55
import org.gvsig.raster.impl.datastruct.ExtentImpl;
56
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
57
import org.gvsig.raster.impl.provider.RasterProvider;
58
import org.gvsig.raster.impl.provider.tile.FileTileServer;
59
import org.gvsig.raster.impl.store.AbstractRasterDataParameters;
60
import org.gvsig.raster.impl.store.DefaultRasterStore;
61
import org.gvsig.raster.impl.store.DefaultStoreFactory;
62
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
63
import org.gvsig.tools.ToolsLocator;
64
import org.gvsig.tools.dynobject.DynObject;
65
import org.gvsig.tools.extensionpoint.ExtensionPoint;
66
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
67

    
68
import org.apache.commons.io.FilenameUtils;
69
import org.slf4j.Logger;
70
import org.slf4j.LoggerFactory;
71
/**
72
 * This class represents the data access for gdal formats.
73
 *
74
 * @author Nacho Brodin (nachobrodin@gmail.com)
75
 */
76
public class GdalProvider extends AbstractRasterProvider {
77
        public static String        NAME                     = "Gdal Store";
78
        public static String        DESCRIPTION              = "Gdal Raster file";
79
        public static final String  METADATA_DEFINITION_NAME = "GdalStore";
80
        private static final Logger logger                   = LoggerFactory.getLogger(GdalProvider.class);
81

    
82
        public static final String  FORMAT_GTiff    = "GTiff";
83
        public static final String  FORMAT_VRT      = "VRT";
84
        public static final String  FORMAT_NITF     = "NITF";
85
        public static final String  FORMAT_HFA      = "HFA";
86
        public static final String  FORMAT_ELAS     = "ELAS";
87
        public static final String  FORMAT_MEM      = "MEM";
88
        public static final String  FORMAT_BMP      = "BMP";
89
        public static final String  FORMAT_PCIDSK   = "PCIDSK";
90
        public static final String  FORMAT_ILWIS    = "ILWIS";
91
        public static final String  FORMAT_HDF4     = "HDF4Image";
92
        public static final String  FORMAT_PNM      = "PNM";
93
        public static final String  FORMAT_ENVI     = "ENVI";
94
        public static final String  FORMAT_EHDR     = "EHdr";
95
        public static final String  FORMAT_PAUX     = "PAux";
96
        public static final String  FORMAT_MFF      = "MFF";
97
        public static final String  FORMAT_MFF2     = "MFF2";
98
        public static final String  FORMAT_BT       = "BT";
99
        public static final String  FORMAT_IDA      = "IDA";
100
        public static final String  FORMAT_RMF      = "RMF";
101
        public static final String  FORMAT_RST      = "RST";
102
        public static final String  FORMAT_LEVELLER = "Leveller";
103
        public static final String  FORMAT_TERRAGEN = "Terragen";
104
        public static final String  FORMAT_ERS      = "ERS";
105
        public static final String  FORMAT_INGR     = "INGR";
106
        public static final String  FORMAT_GSAG     = "GSAG";
107
        public static final String  FORMAT_GSBG     = "GSBG";
108
        public static final String  FORMAT_ADRG     = "ADRG";
109
        public static final String  FORMAT_JP2      = "JPEG2000";
110
        public static final String  FORMAT_GRD      = "GRD";
111
        public static final int     BAND_HEIGHT     = 64;
112
        protected GdalNative        file            = null;
113
        private Extent              viewRequest     = null;
114
        protected static String[]   formatList      = null;
115

    
116
        public static void register() {
117
                ExtensionPointManager extensionPoints = ToolsLocator.getExtensionPointManager();
118
                registerFormats();
119

    
120
                ExtensionPoint point = extensionPoints.get("DefaultRasterProvider");
121
                point.append("reader", GdalProvider.NAME, GdalProvider.class);
122

    
123
                RasterLocator.getManager().getProviderServices().registerFileProvidersTiled(GdalProvider.class);
124

    
125
                DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
126
                if (dataman != null && !dataman.getStoreProviders().contains(NAME)) {
127
                        dataman.registerStoreProvider(NAME,
128
                                        GdalProvider.class, GdalDataParameters.class);
129
                }
130

    
131
                if(DALFileLocator.getFilesystemServerExplorerManager() != null)
132
                        DALFileLocator.getFilesystemServerExplorerManager().registerProvider(
133
                                        NAME, DESCRIPTION,
134
                                        GdalFilesystemServerExplorer.class);
135

    
136
                dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
137
        }
138

    
139
        private static void registerFormats() {
140
                formatList      = new String[] {
141
                                "bmp",
142
                                "gif",
143
                                "tif",
144
                                "tiff",
145
                                "jpg",
146
                                "jpeg",
147
                                "png",
148
                                "vrt",
149
                                "dat", // Envi
150
                                "lan", // Erdas
151
                                "gis", // Erdas
152
                                "img", // Erdas
153
                                "pix", // PCI Geomatics
154
                                "aux", // PCI Geomatics
155
                                "adf", // ESRI Grids
156
                                "mpr", // Ilwis
157
                                "mpl", // Ilwis
158
                                "map", // PC Raster
159
                                "asc",
160
                                "pgm", //Ficheros PNM en escala de grises
161
                                "ppm", //Ficheros PNM en RGB
162
                                "rst", //IDRISIS
163
                                "rmf", //Raster Matrix Format
164
                                "nos",
165
                                "kap",
166
                                "hdr",
167
                                "raw",
168
                                "ers",
169
                                "xml",
170
                                "grd",
171
                                "txt"/*,
172
                                "jp2"*/};
173
                for (int i = 0; i < formatList.length; i++)
174
                        RasterLocator.getManager().getProviderServices().addFormat(formatList[i], GdalProvider.class);
175
        }
176

    
177
        public String[] getFormatList() {
178
                return formatList;
179
        }
180

    
181
        /**
182
         * Returns true if the extension is supported and false if doesn't
183
         * @param ext
184
         * @return
185
         */
186
        public boolean isExtensionSupported(String ext) {
187
                if(ext.indexOf(".") != -1)
188
                        ext = ext.substring(ext.lastIndexOf(".") + 1, ext.length());
189
                for (int i = 0; i < formatList.length; i++) {
190
                        if(formatList[i].compareTo(ext) == 0)
191
                                return true;
192
                }
193
                return false;
194
        }
195

    
196
        /**
197
         * Mandatory constructor to instantiate an empty provider
198
         */
199
        public GdalProvider() {
200
        }
201

    
202
        /**
203
         * Constructor. Abre el dataset.
204
         * @param proj Proyecci?n
205
         * @param fName Nombre del fichero
206
         * @throws NotSupportedExtensionException
207
         * @throws OpenException
208
     * @deprecated use {@link #GdalProvider(URI)}, this constructor will be removed in gvSIG 2.5
209
         */
210
        public GdalProvider(String params) throws NotSupportedExtensionException, OpenException {
211
                super(params);
212
        logger.info("Deprecated use of GdalProvider constructor");
213
                if(params instanceof String) {
214
                        GdalDataParameters p = new GdalDataParameters();
215
                        URI uriParam;
216
            try {
217
                uriParam = new URI((String)params);
218
            } catch (URISyntaxException e) {
219
                throw new OpenException("Can't create uri from "+(String)params, e);
220
            }
221
                        p.setURI(uriParam);
222
                        super.init(p, null, ToolsLocator.getDynObjectManager()
223
                                        .createDynObject(
224
                                                        MetadataLocator.getMetadataManager().getDefinition(
225
                                                                        DataStore.METADATA_DEFINITION_NAME)));
226
                        init(p, null);
227
                }
228
        }
229

    
230
         /**
231
     * Constructor. Abre el dataset.
232
     * @param proj Proyecci?n
233
     * @param fName Nombre del fichero
234
     * @throws NotSupportedExtensionException
235
     */
236
    public GdalProvider(URI uri) throws NotSupportedExtensionException {
237
        super(uri);
238
        GdalDataParameters p = new GdalDataParameters();
239
        p.setURI(uri);
240
        super.init(
241
            p,
242
            null,
243
            ToolsLocator.getDynObjectManager().createDynObject(
244
                MetadataLocator.getMetadataManager().getDefinition(DataStore.METADATA_DEFINITION_NAME)));
245
        init(p, null);
246
    }
247

    
248
    public GdalProvider (GdalDataParameters params,
249
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
250
                super(params, storeServices, ToolsLocator.getDynObjectManager()
251
                                .createDynObject(
252
                                                MetadataLocator.getMetadataManager().getDefinition(
253
                                                                DataStore.METADATA_DEFINITION_NAME)));
254
                init(params, storeServices);
255
        }
256

    
257
        public GdalProvider(AbstractRasterDataParameters params,
258
                        DataStoreProviderServices storeServices, DynObject metadata) {
259
                super(params, storeServices, metadata);
260
        }
261

    
262
        /**
263
         * Creates file references and loads structures with the information and metadata
264
         * @param params load parameters
265
         * @throws NotSupportedExtensionException
266
         */
267
        public void init (AbstractRasterDataParameters params,
268
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
269
                try {
270
                        setParam(storeServices, params);
271
                        validRmf(params.getURI().getPath());
272
                        setFName(translateFileName(params.getURI().getPath()));
273
//                        GdalNative aux = new GdalNative(translateFileName(params.getURI()));
274
//                        long ptro = aux.getPtro();
275
//                        aux.delete();
276
                        file = new GdalNative(translateFileName(params.getURI().getPath()));
277
                        setColorInterpretation(file.colorInterpr);
278
                        setColorTable(file.palette);
279
                        noData = file.getNoDataValue();
280
                        String wktProjection = file.getProjectionRef();
281
                        if(wktProjection != null && wktProjection != "") {
282
                                try {
283
                                        if(RasterLocator.getManager().isCRSUtilSupported())
284
                                                proj = RasterLocator.getManager().getCRSUtils().convertWktToIProjection(wktProjection);
285
                                } catch (Exception e) {
286
                                        logger.info("Error reading WKT from the raster provider", e);
287
                                }
288
                        }
289
                        //CrsWkt crs = new CrsWkt(wktProjection);
290
                        //IProjection proj = CRSFactory.getCRS("EPSG:23030");
291
                        ownTransformation = file.getOwnTransformation();
292
                        externalTransformation = (AffineTransform)ownTransformation.clone();
293
                        load();
294

    
295
                        if(file != null)
296
                                bandCount = file.getRasterCount();
297
                } catch (GdalException e) {
298
                        throw new NotSupportedExtensionException("Extension not supported", e);
299
                } catch(Exception e) {
300
                        System.out.println("Error en GdalOpen");
301
                        e.printStackTrace();
302
                        file = null;
303
                }
304

    
305
                //Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
306
                int[] dt = new int[file.getDataType().length];
307
                for (int i = 0; i < dt.length; i++)
308
                        dt[i] = GdalNative.getRasterBufTypeFromGdalType(file.getDataType()[i]);
309
                setDataType(dt);
310

    
311
                super.init();
312

    
313
                try {
314
                        loadFromRmf(getRmfBlocksManager());
315
                } catch (ParsingException e) {
316
                        //No lee desde rmf
317
                        logger.debug("Problems reading from the RMF file", e);
318
                }
319
        }
320

    
321
        /**
322
         * Comprueba si el fichero abierto es un RasterMetaFile o una imagen
323
         * raster.
324
         * @throws GdalException
325
         */
326
        private void validRmf(String file) throws GdalException {
327
                if(file.endsWith(".rmf")) {
328
                        File f = new File(file);
329
                        try {
330
                                FileReader fr = new FileReader(f);
331
                                BufferedReader br = new BufferedReader(fr);
332
                                char[] buffer = new char[5];
333
                                br.read(buffer);
334
                                StringBuffer st = new StringBuffer(new String(buffer));
335
                                br.close();
336
                                fr.close();
337
                                if(st.toString().equals("<?xml"))
338
                                        throw new GdalException("RasterMetaFile");
339
                        } catch (FileNotFoundException e) {
340
                                throw new GdalException("File Not Found");
341
                        } catch (IOException e) {
342
                                throw new GdalException("");
343
                        }
344
                }
345
        }
346

    
347
        public RasterProvider load() {
348
                return this;
349
        }
350

    
351
        public boolean isOpen() {
352
                if(file != null && file.isOpen())
353
                        return true;
354
                return false;
355
        }
356

    
357
        public URI translateURI(URI uri) {
358
        if ("hdr".equalsIgnoreCase(FilenameUtils.getExtension(uri.getPath()))) {
359
            File file = new File(FilenameUtils.removeExtension(uri.getPath()));
360
            return file.toURI();
361
        }
362
                return uri;
363
        }
364

    
365
        /**
366
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci?n
367
         * de la vista asignada ya que la petici?n viene en coordenadas del fichero .rmf y la vista (v)
368
         * ha de estar en coordenadas del fichero.
369
         */
370
        public void setView(Extent e) {
371
                viewRequest = new ExtentImpl(e);
372
        }
373

    
374
        public Extent getView() {
375
                return viewRequest;
376
        }
377

    
378
        public double getWidth() {
379
                return file.width;
380
        }
381

    
382
        public double getHeight() {
383
                return file.height;
384
        }
385

    
386
        /**
387
         * Read a line from the file
388
         * @param line
389
         * @param band
390
         * @return
391
         * @throws InvalidSetViewException
392
         * @throws FileNotOpenException
393
         * @throws RasterDriverException
394
         * @Deprecated This operation is deprecated because is not useful and in the future
395
         * it will not be maintained. The abstract operation has dissapear
396
         */
397
        public Object readCompleteLine(int line, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
398
                if(line > this.getHeight() || band > this.getBandCount())
399
                        throw new InvalidSetViewException("Request out of grid");
400

    
401
                try{
402
                        return file.readCompleteLine(line, band);
403
                }catch(GdalException e){
404
                        throw new RasterDriverException("Error reading data from Gdal library");
405
                }
406
        }
407

    
408
        public Object readBlock(int pos, int blockHeight, double scale)
409
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
410
                if(pos < 0)
411
                        throw new InvalidSetViewException("Request out of grid");
412

    
413
                if((pos + blockHeight) > getHeight())
414
                        blockHeight = Math.abs(((int)getHeight()) - pos);
415
                try{
416
                        return file.readBlock(pos, blockHeight, scale);
417
                }catch(GdalException e){
418
                        throw new RasterDriverException("Error reading data from Gdal library");
419
                }
420
        }
421

    
422
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
423
                if(file != null){
424
                        if(x < 0 || y < 0 || x >= file.width || y >= file.height)
425
                                throw new InvalidSetViewException("Request out of grid");
426
                        Object[] data = file.getData(x, y);
427
                        return data[band];
428
                }
429
                throw new FileNotOpenException("GdalNative not exist");
430
        }
431

    
432
        @Override
433
        public void loadBuffer(SpiRasterQuery q)
434
                        throws ProcessInterruptedException, RasterDriverException {
435
                setView(q.getAdjustedRequestBoundingBox());
436

    
437
                try {
438
                        file.readWindow(q.getBufferForProviders(),
439
                                        q.getBandList(),
440
                                        q.getAdjustedRequestBoundingBox(),
441
                                        q.getAdjustedRequestPxWindow(),
442
                                        q.getTaskStatus());
443
                } catch (GdalException e) {
444
                        throw new RasterDriverException("Error reading data", e);
445
                }
446

    
447
        }
448

    
449
        public int getBlockSize(){
450
                if(file != null)
451
                        return file.getBlockSize();
452
                else
453
                        return 0;
454
        }
455

    
456
        public DataStoreMetadata getMetadata() {
457
                if(file != null)
458
                        return file.metadata;
459
                else
460
                        return null;
461
        }
462

    
463
        public Transparency getTransparency() {
464
                return file.fileTransparency;
465
        }
466

    
467
        public boolean isGeoreferenced() {
468
                if(file != null)
469
                        return file.georeferenced;
470
                else
471
                        return false;
472
        }
473

    
474
        /**
475
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
476
         * el valor de esta variable cada vez que dibuja.
477
         * @return true si se ha supersampleado y false si no se ha hecho.
478
         */
479
        public boolean isSupersampling() {
480
                if(file != null)
481
                        return file.isSupersampling;
482
                else
483
                        return false;
484
        }
485

    
486
        public GdalNative getNative(){
487
                return file;
488
        }
489

    
490
        public void setAffineTransform(AffineTransform t){
491
                super.setAffineTransform(t);
492
                file.setExternalTransform(t);
493
        }
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
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
506
                if (band >= getBandCount())
507
                        throw new BandAccessException("Wrong band");
508
                try {
509
                        if (overview >= file.getRasterBand(band + 1).getOverviewCount())
510
                                throw new BandAccessException("Wrong overview count");
511
                        return file.getRasterBand(band + 1).getOverview(overview).getRasterBandXSize();
512
                } catch (GdalException e) {
513
                        throw new RasterDriverException("");
514
                }
515
        }
516

    
517
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
518
                if (band >= getBandCount())
519
                        throw new BandAccessException("Wrong band");
520
                try {
521
                        if (overview >= file.getRasterBand(band + 1).getOverviewCount())
522
                                throw new BandAccessException("Wrong overview count");
523
                        return file.getRasterBand(band + 1).getOverview(overview).getRasterBandYSize();
524
                } catch (GdalException e) {
525
                        throw new RasterDriverException("");
526
                }
527
        }
528

    
529
        public boolean isOverviewsSupported() {
530
                return true;
531
        }
532

    
533
        public boolean isReproyectable() {
534
                return true;
535
        }
536

    
537
        public boolean needEnhanced() {
538
                return (getDataType()[0] != Buffer.TYPE_BYTE);
539
                //Desconozco pq raz?n estaba esta condici?n. Quiz?s haya que volver a a?adirla
540
                //Eliminada 30/5/2013
541
                //|| (getBandCount() == 1 && getDataType()[0] == Buffer.TYPE_BYTE));
542
        }
543

    
544
        public String getProviderName() {
545
                return NAME;
546
        }
547

    
548
        public void setStatus(RasterProvider provider) {
549
                if(provider instanceof GdalProvider) {
550
                        //Not implemented yet
551
                }
552
        }
553

    
554
        public TileServer getTileServer() {
555
                if(tileServer == null) {
556
                        DefaultRasterStore store = new DefaultRasterStore();
557
                        store.setProvider(this);
558
                        tileServer = new FileTileServer(store);
559
//                        tileServer.setFileSuffix("rmf");
560
                }
561
                return tileServer;
562
        }
563

    
564
        public void close() {
565
                if(file != null){
566
                        file.dispose();
567
                }
568
                try {
569
                        finalize();
570
                } catch (Throwable e) {
571
                }
572
        }
573

    
574
        protected void finalize() throws Throwable {
575
                file           = null;
576
                viewRequest    = null;
577
                if(formatList != null) {
578
                        for (int i = 0; i < formatList.length; i++) {
579
                                formatList[i] = null;
580
                        }
581
                        formatList = null;
582
                }
583
                super.finalize();
584
        }
585

    
586
    public void addFile(File file) throws InvalidSourceException {
587
        // Do nothing
588
    }
589

    
590
    public void removeFile(File file) {
591
        // Do nothing
592
    }
593
}