Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.raster.gdal / org.gvsig.raster.gdal.provider / src / main / java / org / gvsig / raster / gdal / provider / AbstractFileRasterGdalStoreProvider.java @ 8697

History | View | Annotate | Download (18.5 KB)

1 6298 dmartinezizquierdo
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2016 gvSIG Association
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., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.raster.gdal.provider;
24
25 6335 dmartinezizquierdo
import java.io.BufferedOutputStream;
26
import java.io.DataOutputStream;
27 6298 dmartinezizquierdo
import java.io.File;
28 6335 dmartinezizquierdo
import java.io.FileOutputStream;
29
import java.io.IOException;
30 6298 dmartinezizquierdo
import java.util.ArrayList;
31
import java.util.Arrays;
32
import java.util.List;
33
import java.util.Vector;
34
35 6696 fdiaz
import org.apache.commons.io.FileUtils;
36 6298 dmartinezizquierdo
import org.apache.commons.io.FilenameUtils;
37 6335 dmartinezizquierdo
import org.apache.commons.lang3.StringUtils;
38 6696 fdiaz
import org.cresques.cts.ICRSFactory;
39 6298 dmartinezizquierdo
import org.cresques.cts.IProjection;
40 6335 dmartinezizquierdo
import org.gdal.gdal.Driver;
41 6298 dmartinezizquierdo
import org.gdal.gdal.GCP;
42
import org.gdal.gdal.gdal;
43
import org.gdal.gdalconst.gdalconstConstants;
44 6527 fdiaz
import org.slf4j.Logger;
45
import org.slf4j.LoggerFactory;
46
47 6298 dmartinezizquierdo
import org.gvsig.fmap.dal.DALLocator;
48
import org.gvsig.fmap.dal.DataManager;
49
import org.gvsig.fmap.dal.DataServerExplorer;
50
import org.gvsig.fmap.dal.DataStore;
51 6335 dmartinezizquierdo
import org.gvsig.fmap.dal.DataStoreParameters;
52
import org.gvsig.fmap.dal.exception.CreateException;
53 6298 dmartinezizquierdo
import org.gvsig.fmap.dal.exception.DataException;
54
import org.gvsig.fmap.dal.exception.InitializeException;
55
import org.gvsig.fmap.dal.exception.OpenException;
56
import org.gvsig.fmap.dal.exception.ReadException;
57
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
58
import org.gvsig.fmap.dal.resource.ResourceAction;
59
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
60
import org.gvsig.fmap.dal.resource.file.FileResource;
61
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
62
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
63
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
64
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
65
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
66 6335 dmartinezizquierdo
import org.gvsig.fmap.geom.DataTypes;
67 6298 dmartinezizquierdo
import org.gvsig.fmap.geom.Geometry;
68 6335 dmartinezizquierdo
import org.gvsig.fmap.geom.Geometry.DIMENSIONS;
69 6298 dmartinezizquierdo
import org.gvsig.fmap.geom.GeometryLocator;
70 6547 fdiaz
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
71 6298 dmartinezizquierdo
import org.gvsig.fmap.geom.primitive.Envelope;
72
import org.gvsig.raster.lib.buffer.api.Buffer;
73 6335 dmartinezizquierdo
import org.gvsig.tools.dynobject.DynClass;
74
import org.gvsig.tools.dynobject.DynClass_v2;
75
import org.gvsig.tools.dynobject.DynField;
76 6298 dmartinezizquierdo
import org.gvsig.tools.dynobject.DynObject;
77 6335 dmartinezizquierdo
import org.gvsig.tools.dynobject.Tags;
78 6298 dmartinezizquierdo
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
79 6547 fdiaz
import org.gvsig.tools.locator.LocatorException;
80 6298 dmartinezizquierdo
81
/**
82
 * Provider for Raster GDAL files
83
 * @author dmartinezizquierdo
84
 *
85
 */
86 6335 dmartinezizquierdo
public abstract class AbstractFileRasterGdalStoreProvider extends AbstractRasterGdalStoreProvider implements
87 6298 dmartinezizquierdo
ResourceConsumer{
88
89
    private static final Logger logger =
90 6335 dmartinezizquierdo
        LoggerFactory.getLogger(AbstractFileRasterGdalStoreProvider.class);
91 6298 dmartinezizquierdo
92
93 6335 dmartinezizquierdo
    /**
94
     * Constructor
95
     * @param params
96
     * @param storeServices
97
     * @throws InitializeException
98
     */
99
    public AbstractFileRasterGdalStoreProvider(RasterGdalFileStoreParameters params,
100 6298 dmartinezizquierdo
        DataStoreProviderServices storeServices)
101
        throws InitializeException {
102
        super(
103
                params,
104 6335 dmartinezizquierdo
                storeServices);
105
106 6298 dmartinezizquierdo
    }
107
108 6335 dmartinezizquierdo
    protected AbstractFileRasterGdalStoreProvider(RasterGdalFileStoreParameters params,
109 6298 dmartinezizquierdo
            DataStoreProviderServices storeServices, DynObject metadata)
110
            throws InitializeException {
111
        super(params, storeServices, metadata);
112
    }
113
114 6335 dmartinezizquierdo
    protected AbstractFileRasterGdalStoreProvider(NewRasterGdalStoreParameters params, Driver gdalDriver) {
115
        //PARA Exportar
116
        super(params,gdalDriver);
117
    }
118
119
    @Override
120
    protected void init(DataStoreParameters params,
121 6298 dmartinezizquierdo
        DataStoreProviderServices storeServices) throws InitializeException {
122 6335 dmartinezizquierdo
        super.init(params, storeServices);
123 6298 dmartinezizquierdo
        File file = getRasterGdalParameters().getFile();
124
        if (file == null) {
125
            throw new InitializeException(
126
                new NullPointerException("Raster GDAL file is null"));
127
        }
128
129 6335 dmartinezizquierdo
        this.projection=getRasterGdalParameters().getCRS();
130 6298 dmartinezizquierdo
131
        resource = this.createResource(
132
            FileResource.NAME,
133
            new Object[] { file.getAbsolutePath() }
134
        );
135
        resource.addConsumer(this);
136
137
    }
138
139 6335 dmartinezizquierdo
    protected RasterGdalFileStoreParameters getRasterGdalParameters() {
140
        return (RasterGdalFileStoreParameters) this.getParameters();
141 6298 dmartinezizquierdo
    }
142
143
    @Override
144 6335 dmartinezizquierdo
    public Object getDynValue(String name) throws DynFieldNotFoundException {
145
        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
146
            return this.envelope;
147
        } else if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
148
            IProjection pro = this.getRasterGdalParameters().getCRS();
149
            if (pro != null) {
150
                return pro;
151 6298 dmartinezizquierdo
            }
152
        }
153 6335 dmartinezizquierdo
        return super.getDynValue(name);
154 6298 dmartinezizquierdo
    }
155
156 6302 llmarques
    @Override
157 6298 dmartinezizquierdo
    public DataServerExplorer getExplorer()
158
        throws ReadException, ValidateDataParametersException {
159
        DataManager manager = DALLocator.getDataManager();
160
        FilesystemServerExplorerParameters params;
161
        try {
162
            params = (FilesystemServerExplorerParameters) manager
163
            .createServerExplorerParameters(FilesystemServerExplorer.NAME);
164
            params.setRoot(this.getRasterGdalParameters().getFile().getParent());
165
            return manager.openServerExplorer(FilesystemServerExplorer.NAME,params);
166
        } catch (DataException e) {
167
            throw new ReadException(this.getProviderName(), e);
168
        } catch (ValidateDataParametersException e) {
169
            throw new ReadException(this.getProviderName(), e);
170
        }
171
172
    }
173
174 6335 dmartinezizquierdo
    /**
175
     * Used to obtain the specific options for a specific driver
176
     * Not in use yet. Used as example.
177
     * @return options used to open a specific driver in format ("optionName=optionValue")
178
     */
179
    private String [] getParametersDriverOptions(){
180
        ArrayList<String> optionsList=new ArrayList<String>();
181
        DynClass dynClass = getRasterGdalParameters().getDynClass();
182
        DynField[] fields = dynClass.getDynFields();
183
        for (DynField field:fields){
184
            String fieldName = field.getName();
185
            String gdalOption = fieldName.toUpperCase();
186
            Object dynValue = getRasterGdalParameters().getDynValue(fieldName);
187
188
            if (dynValue!=null && field.getGroup().equalsIgnoreCase(RasterGdalFileStoreParameters.OPEN_OPTIONS_GROUP)){
189
                if(field.getType() == DataTypes.BOOLEAN) {
190
                    if((Boolean)dynValue){
191
                        optionsList.add(gdalOption+"=YES");
192
                    }else{
193
                        optionsList.add(gdalOption+"=NO");
194
                    }
195
196
                } else {
197
                    optionsList.add(gdalOption+"="+dynValue);
198
                }
199
            }
200 6298 dmartinezizquierdo
        }
201 6335 dmartinezizquierdo
        String[]options=new String[optionsList.size()];
202
        optionsList.toArray(options);
203
        return options;
204 6298 dmartinezizquierdo
    }
205
206 6335 dmartinezizquierdo
    private String getOpeningString(File file, String[] driverOptions){
207
        String openingString="PDF:"+"\""+file.getAbsolutePath()+"\"";
208
        for (String option:driverOptions){
209
            openingString+=" "+option;
210
        }
211
        return openingString;
212
    }
213
214
    @Override
215
    protected void openEver() throws OpenException {
216 6298 dmartinezizquierdo
        try {
217
            getResource().execute(new ResourceAction() {
218
219
                public Object run() throws Exception {
220
221 6335 dmartinezizquierdo
                    //Used in a future when we could use them
222
                    String[] driverOptions=getParametersDriverOptions();
223 6298 dmartinezizquierdo
224 6335 dmartinezizquierdo
                    if (driverOptions!=null && driverOptions.length>0){
225
                        //If we have driver specific opening options
226
                        //FIXME: Use "driverOptions" properly
227
                        String openingString=getOpeningString(getRasterGdalParameters().getFile(), driverOptions);
228
                        gdalDataSet = gdal.Open(
229
                            openingString,
230
                            gdalconstConstants.GA_ReadOnly);
231
                    }else{
232
                        //If we don't have driver specific opening options
233
                        gdalDataSet = gdal.Open(
234
                            getRasterGdalParameters().getFile().getAbsolutePath(),
235
                            gdalconstConstants.GA_ReadOnly);
236
                    }
237 6340 dmartinezizquierdo
                    if (gdalDataSet==null){
238
                        String errorMsg=gdal.GetLastErrorMsg();
239
                        logger.info(errorMsg);
240
                    }
241 6335 dmartinezizquierdo
242 6298 dmartinezizquierdo
                    resource.notifyOpen();
243
244
                    envelope = createEnvelope(getGeoTransform());
245
246
                    if (envelope == null) {
247
                        // If couldn't be possible to create an envelope,
248
                        // this is created at 0,0 coordinates.
249
                        envelope = GeometryLocator.getGeometryManager()
250
                            .createEnvelope(0, 0, gdalDataSet.getRasterXSize(),
251
                                gdalDataSet.getRasterYSize(),
252
                                Geometry.SUBTYPES.GEOM2D);
253
                    }
254
255
                    resource.notifyClose();
256
257
                    resource.setData(gdalDataSet);
258
259
                    return null;
260
                }
261
262
            });
263
        } catch (Exception e) {
264
            this.gdalDataSet = null;
265
            try {
266
                throw new OpenException(resource.getName(), e);
267
            } catch (AccessResourceException e1) {
268
                throw new OpenException(getProviderName(), e);
269
            }
270
        } finally {
271
            this.taskStatus.remove();
272
        }
273
    }
274
275
    private double[] getGeoTransform(){
276
        double[] geotransform = null;
277
        double[] defaultGeotransform =
278 6335 dmartinezizquierdo
            { 0.0, 1.0, 0.0, 0.0, 0.0, -1.0 };
279
        boolean geoTransformCreated=false;
280 6298 dmartinezizquierdo
        // Try to create an Envelope through geolocalization
281
        // methods
282
        if (getRasterGdalParameters().getWldParams() != null) {
283
284
            // Try to get a geotransform from wld file
285
            List<String> wldParams =
286
                getRasterGdalParameters().getWldParams();
287
            double pixelSizeX =
288
                Double.valueOf(wldParams.get(0));
289
            double rotationAxisY =
290
                Double.valueOf(wldParams.get(1));
291
            double rotationAxisX =
292
                Double.valueOf(wldParams.get(2));
293
            double pixelSizeY =
294 6673 fdiaz
                Double.valueOf(wldParams.get(3));
295 6298 dmartinezizquierdo
            double upperLeftPixelCenterCoordX =
296
                Double.valueOf(wldParams.get(4));
297
            double upperLeftPixelCenterCoordY =
298
                Double.valueOf(wldParams.get(5));
299
300
            geotransform = new double[6];
301
            // Info found at:
302
            // http://www.gdal.org/gdal_8h.html#adae2ed5807e4ec288812b54c6fccda1e
303
            // and http://www.gdal.org/gdal_tutorial.html
304
            // GDALReadWorldFile
305 6335 dmartinezizquierdo
306 6298 dmartinezizquierdo
            geotransform[0] = upperLeftPixelCenterCoordX
307
                - (pixelSizeX * 0.5) - (rotationAxisX * 0.5);
308
            geotransform[1] = pixelSizeX;
309
            geotransform[2] = rotationAxisX;
310
            geotransform[3] = upperLeftPixelCenterCoordY
311
                - (pixelSizeY * 0.5) - (rotationAxisY * 0.5);
312 6335 dmartinezizquierdo
            geotransform[4] = rotationAxisY;
313
            geotransform[5] = pixelSizeY;
314 6298 dmartinezizquierdo
315 6335 dmartinezizquierdo
            geoTransformCreated=true;
316
317
        }
318
319
        if (!geoTransformCreated) {
320 6298 dmartinezizquierdo
            // Try to get a geotransform from the file
321
            geotransform = gdalDataSet.GetGeoTransform();
322 6335 dmartinezizquierdo
            if (Arrays.equals(defaultGeotransform, geotransform) ){
323
                geoTransformCreated=false;
324
            }
325 6298 dmartinezizquierdo
        }
326
327
        // Try to get a geotransform from GCPs in the file
328 6335 dmartinezizquierdo
        if (!geoTransformCreated) {
329 6298 dmartinezizquierdo
            Vector vectorGCPs = gdalDataSet.GetGCPs();
330
            GCP[] gcps = new GCP[gdalDataSet.GetGCPCount()];
331
            for (int i = 0; i < gdalDataSet
332
                .GetGCPCount(); i++) {
333
                gcps[i] = (GCP) vectorGCPs.get(i);
334
            }
335
            double[] gcpsGeotransform = new double[6];
336
            int isOK =
337
                gdal.GCPsToGeoTransform(gcps, gcpsGeotransform);
338
            if (isOK != 0) {
339
                geotransform = gcpsGeotransform;
340
            }
341
        }
342
343
        return geotransform;
344
    }
345
346 6335 dmartinezizquierdo
    protected void createWorldFile(File file, Buffer buffer) throws IOException {
347
        String fileName=file.getAbsolutePath();
348
        File tfw = null;
349 6298 dmartinezizquierdo
350 6335 dmartinezizquierdo
        String extWorldFile = ".wld";
351
        Tags paramsTags=((DynClass_v2)getParameters().getDynClass()).getTags();
352
        if (paramsTags!=null && paramsTags.has(RasterGdalFileStoreParameters.WLD_EXTENSION_TAG_NAME)){
353
            String tagWorldFile=(String)paramsTags.get(RasterGdalFileStoreParameters.WLD_EXTENSION_TAG_NAME);
354
            if (StringUtils.isNotEmpty(tagWorldFile)){
355
                extWorldFile=FilenameUtils.EXTENSION_SEPARATOR_STR+tagWorldFile;
356
            }
357 6298 dmartinezizquierdo
        }
358
359 6335 dmartinezizquierdo
        tfw = new File(FilenameUtils.removeExtension(fileName) + extWorldFile);
360 6547 fdiaz
        Envelope envelope;
361
        try {
362
            envelope = buffer.getEnvelope();
363
        } catch (LocatorException | CreateEnvelopeException e) {
364
            logger.warn("Can't get the buffer envelope", e);
365
            return;
366
        }
367 6298 dmartinezizquierdo
368 6335 dmartinezizquierdo
        double pixelSizeX = buffer.getPixelSizeX();//(envelope.getMaximum(DIMENSIONS.X) - envelope.getMinimum(DIMENSIONS.X)) / (gdalDataSet.getRasterXSize());
369
        double pixelSizeY = -buffer.getPixelSizeY();//(envelope.getMinimum(DIMENSIONS.Y) - envelope.getMaximum(DIMENSIONS.Y)) / (gdalDataSet.getRasterYSize());
370
        double upperLeftPixelCenterCoordX = envelope.getMinimum(DIMENSIONS.X)+pixelSizeX/2;//+gdalDataSet.getRasterXSize()/2;
371
        double upperLeftPixelCenterCoordY = envelope.getMaximum(DIMENSIONS.Y)+pixelSizeY/2;//gdalDataSet.getRasterYSize()/2;
372 6298 dmartinezizquierdo
373 6335 dmartinezizquierdo
        // Generamos un world file para gdal
374
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(tfw)));
375
        dos.writeBytes(pixelSizeX + "\n");
376
        dos.writeBytes("0.0\n");//rotationAxisY:Not implemented yet
377
        dos.writeBytes("0.0\n");//rotationAxisX:Not implemented yet
378
        dos.writeBytes(pixelSizeY + "\n");//Negative value
379
        dos.writeBytes("" + upperLeftPixelCenterCoordX + "\n");
380
        dos.writeBytes("" + upperLeftPixelCenterCoordY + "\n");
381
        dos.close();
382 6298 dmartinezizquierdo
    }
383
384
    @Override
385
    public Object getSourceId() {
386
        return this.getRasterGdalParameters().getFile();
387
    }
388
389
    @Override
390
    public String getName() {
391
        String name = this.getRasterGdalParameters().getFile().getName();
392
        return FilenameUtils.getBaseName(name);
393
    }
394
395
    @Override
396
    public String getFullName() {
397
        return this.getRasterGdalParameters().getFile().getAbsolutePath();
398
    }
399
400
    @Override
401
    public boolean closeResourceRequested(ResourceProvider resource) {
402 6340 dmartinezizquierdo
        gdalDataSet.delete();
403
        gdalDataSet=null;
404 6298 dmartinezizquierdo
        return true;
405
    }
406
407 6335 dmartinezizquierdo
408
    /**
409
     * Stores a buffer into a new file
410
     * @param newRasterParams
411
     * @param overwrite
412
     * @throws CreateException
413 6298 dmartinezizquierdo
     */
414 6335 dmartinezizquierdo
    public void store(boolean overwrite)
415
        throws CreateException {
416
        //This method must be overwritten by subclasses than can be stored
417
        throw new UnsupportedOperationException("This provider can't store the raster");
418 6298 dmartinezizquierdo
    }
419
420 6335 dmartinezizquierdo
421
    /**
422
     * Creates a Geotransform (Geolocalization data in Gdal formal) from  buffer envelope
423
     * @param buffer
424
     * @return
425 6298 dmartinezizquierdo
     */
426 6335 dmartinezizquierdo
    protected double[] createGeoTransform(Buffer buffer){
427
        double[] result=new double[6];
428 6547 fdiaz
        try {
429
            result[0]=buffer.getEnvelope().getMinimum(DIMENSIONS.X);
430
        } catch (LocatorException | CreateEnvelopeException e) {
431
            result[0]=0;
432
        }
433 6335 dmartinezizquierdo
        result[1]=buffer.getPixelSizeX();
434
        //TODO: Rotation not implemented yet
435
        result[2]=0;
436 6547 fdiaz
        try {
437
            result[3]=buffer.getEnvelope().getMaximum(DIMENSIONS.Y);
438
        } catch (LocatorException | CreateEnvelopeException e) {
439
            result[3]=0;
440
        }
441 6335 dmartinezizquierdo
        //TODO: Rotation not implemented yet
442
        result[4]=0;
443
        result[5]=-buffer.getPixelSizeY();
444
        return result;
445 6298 dmartinezizquierdo
    }
446
447
    /**
448 6335 dmartinezizquierdo
     * Extracts the options to create a new raster, if any of them exist
449
     * @param newRasterParams
450
     * @return
451 6298 dmartinezizquierdo
     */
452 6335 dmartinezizquierdo
    protected String[] getStoringOptions(
453
        NewRasterGdalStoreParameters newRasterParams) {
454
        //Specific params from the driver are readed
455
        //IMPORTANT:Param names defined in the XML must be the same that the properties used for the driver
456
        ArrayList<String> optionsList=new ArrayList<String>();
457
        DynClass dynClass = newRasterParams.getDynClass();
458
        DynField[] fields = dynClass.getDynFields();
459
        for (DynField field:fields){
460
            String fieldName = field.getName();
461
            String gdalOption = fieldName.toUpperCase();
462
            Object dynValue = newRasterParams.getDynValue(fieldName);
463 6298 dmartinezizquierdo
464 6335 dmartinezizquierdo
            if (dynValue!=null && field.getGroup().equalsIgnoreCase(NewRasterGdalStoreParameters.CREATE_OPTIONS_GROUP)){
465
                if(field.getType() == DataTypes.BOOLEAN) {
466
                    if((Boolean)dynValue){
467
                        optionsList.add(gdalOption+"=YES");
468
                    }else{
469
                        optionsList.add(gdalOption+"=NO");
470
                    }
471 6298 dmartinezizquierdo
472 6335 dmartinezizquierdo
                } else {
473
                    optionsList.add(gdalOption+"="+dynValue);
474
                }
475
            }
476 6298 dmartinezizquierdo
        }
477 6335 dmartinezizquierdo
        String[]options=new String[optionsList.size()];
478
        optionsList.toArray(options);
479
        return options;
480 6298 dmartinezizquierdo
    }
481 6335 dmartinezizquierdo
482 6696 fdiaz
    protected void savePrjFile(File dataFile, IProjection proj) throws IOException {
483 8697 omartinez
        if (proj == null) {
484
            return;
485
        }
486 6696 fdiaz
        File file = new File(FilenameUtils.removeExtension(dataFile.getAbsolutePath()) + ".prj");
487
        String export = proj.export(ICRSFactory.FORMAT_WKT_ESRI);
488
        if (export != null) {
489
            FileUtils.writeStringToFile(file, export);
490
        }
491
    }
492
493 6298 dmartinezizquierdo
}