Statistics
| Revision:

gvsig-gdal / trunk / org.gvsig.gdal2 / org.gvsig.gdal2.prov / org.gvsig.gdal2.prov.gml / src / main / java / org / gvsig / gdal / prov / gml / GMLDataStoreProvider.java @ 368

History | View | Annotate | Download (13.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2016 gvSIG Association
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.gdal.prov.gml;
25

    
26
import java.io.File;
27
import java.io.IOException;
28
import java.util.ArrayList;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.Vector;
32

    
33
import org.apache.commons.io.FileUtils;
34
import org.apache.commons.io.FilenameUtils;
35
import org.apache.commons.lang3.StringUtils;
36
import org.cresques.cts.ICRSFactory;
37
import org.cresques.cts.IProjection;
38
import org.gdal.gdal.gdal;
39
import org.gdal.ogr.DataSource;
40
import org.gdal.ogr.Driver;
41
import org.gdal.ogr.FeatureDefn;
42
import org.gdal.ogr.FieldDefn;
43
import org.gdal.ogr.GeomFieldDefn;
44
import org.gdal.ogr.Layer;
45
import org.gdal.ogr.ogr;
46
import org.gdal.ogr.ogrConstants;
47
import org.gdal.osr.SpatialReference;
48
import org.gvsig.fmap.dal.DataStore;
49
import org.gvsig.fmap.dal.DataStoreParameters;
50
import org.gvsig.fmap.dal.exception.CopyException;
51
import org.gvsig.fmap.dal.exception.CreateException;
52
import org.gvsig.fmap.dal.exception.DataException;
53
import org.gvsig.fmap.dal.exception.InitializeException;
54
import org.gvsig.fmap.dal.exception.WriteException;
55
import org.gvsig.fmap.dal.feature.Feature;
56
import org.gvsig.fmap.dal.feature.FeatureSet;
57
import org.gvsig.fmap.dal.feature.FeatureStore;
58
import org.gvsig.fmap.dal.feature.FeatureType;
59
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
60
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
61
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
62
import org.gvsig.fmap.geom.type.GeometryType;
63
import org.gvsig.gdal.prov.ogr.OGRConverter;
64
import org.gvsig.gdal.prov.ogr.OGRDataStoreProvider;
65
import org.gvsig.gdal.prov.ogr.OGRUnsupportedFormatException;
66
import org.gvsig.tools.dispose.DisposableIterator;
67
import org.gvsig.tools.dynobject.DynObject;
68
import org.gvsig.tools.exception.BaseException;
69
import org.slf4j.Logger;
70
import org.slf4j.LoggerFactory;
71

    
72
/**
73
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
74
 *
75
 */
76
public class GMLDataStoreProvider extends OGRDataStoreProvider {
77

    
78
    private static final Logger LOG = LoggerFactory.getLogger(GMLDataStoreProvider.class);
79

    
80
    /**
81
     *
82
     */
83
    public static final String NAME = "GMLDataStoreProvider";
84

    
85
    /**
86
     *
87
     */
88
    public static final String DESCRIPTION = "GML provider to open vectorial resources";
89

    
90
    protected GMLDataStoreProvider(DataStoreParameters dataParameters,
91
        DataStoreProviderServices storeServices, DynObject metadata) throws InitializeException {
92
        super(dataParameters, storeServices, metadata);
93
    }
94

    
95
    protected GMLDataStoreProvider(DataStoreParameters dataParameters,
96
        DataStoreProviderServices storeServices) throws InitializeException {
97
        super(dataParameters, storeServices);
98
    }
99

    
100
    @Override
101
    protected synchronized DataSource getDataSource() throws OGRUnsupportedFormatException {
102

    
103
        try {
104

    
105
            if (this.dataSource == null) {
106

    
107
                if (getGMLParameters().getXsdSchema() != null
108
                    && StringUtils.isBlank(getGMLParameters().getConnectionString())) {
109
                    StringBuilder stb = new StringBuilder();
110
                    if (StringUtils.isBlank(getGMLParameters().getConnectionString())
111
                        && getGMLParameters().getFile() != null) {
112
                        stb.append(getGMLParameters().getFile().getAbsolutePath());
113

    
114
                    } else if (StringUtils.isNotBlank(getGMLParameters().getConnectionString())) {
115
                        stb.append(getGMLParameters().getConnectionString());
116
                    }
117

    
118
                    stb.append(",xsd=");
119
                    stb.append(getGMLParameters().getXsdSchema());
120

    
121
                    getGMLParameters().setConnectionString(stb.toString());
122
                }
123

    
124
                if (getGMLParameters().getGfsSchema() != null) {
125
                    gdal.SetConfigOption("GML_GFS_TEMPLATE", getGMLParameters().getGfsSchema()
126
                        .getAbsolutePath());
127
                }
128
            }
129

    
130
            return super.getDataSource();
131

    
132
        } finally {
133
            gdal.SetConfigOption("GML_GFS_TEMPLATE", null);
134
        }
135
    }
136

    
137
    private GMLDataStoreParameters getGMLParameters() {
138
        return (GMLDataStoreParameters) this.getParameters();
139
    }
140

    
141
    @Override
142
    public boolean allowWrite() {
143
        return true;
144
    }
145

    
146
    @SuppressWarnings("rawtypes")
147
    @Override
148
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds,
149
        Iterator featureTypesChanged) throws DataException {
150

    
151
        FeatureStore store = this.getStoreServices().getFeatureStore();
152
        FeatureType defaultFeatureType = store.getDefaultFeatureType();
153

    
154
        String baseName = FilenameUtils.getBaseName(getGMLParameters().getFile().getName());
155
        File newFile = null;
156
        File newSchemaFile = null;
157
        try {
158
            newFile = File.createTempFile(baseName, null);
159
            newSchemaFile = getSchemaFile(newFile);
160
        } catch (IOException e) {
161
            String msg = String.format("Temp %1s file", new Object[] { baseName });
162
            throw new CreateException(msg, e);
163
        }
164

    
165
        Driver driver = ogr.GetDriverByName("GML");
166
        Vector<String> options = new Vector<String>(1);
167
        options.add("FORMAT=GML3.2");
168

    
169
        DataSource newDataSource = driver.CreateDataSource(newFile.getAbsolutePath(), options);
170

    
171
        // Copy other layer to new data source
172
        OGRConverter converter = new OGRConverter();
173
        for (int i = 0; i < getDataSource().GetLayerCount(); i++) {
174
            Layer tmpLayer = getDataSource().GetLayerByIndex(i);
175

    
176
            if (tmpLayer.GetName().equals(getGMLParameters().getLayerName())) {
177
                continue;
178
            }
179

    
180
            SpatialReference srs = tmpLayer.GetSpatialRef();
181
            int ogrGeomType = tmpLayer.GetGeomType();
182

    
183
            List<FieldDefn> fields = new ArrayList<FieldDefn>();
184
            FeatureDefn layerDefn = tmpLayer.GetLayerDefn();
185
            for (int j = 0; j < layerDefn.GetFieldCount(); j++) {
186
                fields.add(layerDefn.GetFieldDefn(j));
187
            }
188

    
189
            List<GeomFieldDefn> geomFields = new ArrayList<GeomFieldDefn>();
190
            for (int j = 0; j < layerDefn.GetGeomFieldCount(); j++) {
191
                geomFields.add(layerDefn.GetGeomFieldDefn(j));
192
            }
193

    
194
            List<org.gdal.ogr.Feature> ogrFeatures = new ArrayList<org.gdal.ogr.Feature>();
195
            org.gdal.ogr.Feature feature = tmpLayer.GetNextFeature();
196
            while(feature!=null){
197
                ogrFeatures.add(feature);
198
            }
199
            createLayer(newDataSource, tmpLayer.GetName(), srs, ogrGeomType, fields, geomFields,
200
                ogrFeatures);
201
        }
202

    
203
        SpatialReference srs = getLayer().GetSpatialRef();
204
        if (srs == null) {
205
            IProjection projection = defaultFeatureType.getDefaultSRS();
206
            if (projection == null) {
207
                projection = (IProjection) this.getDynValue(DataStore.METADATA_CRS);
208
                if (projection != null) {
209
                    srs = new SpatialReference(projection.export(ICRSFactory.FORMAT_WKT));
210
                }
211
            }
212
        }
213

    
214
        int ogrGeomType = -1;
215
        GeometryType geomType = defaultFeatureType.getDefaultGeometryAttribute().getGeomType();
216
        if (geomType != null) {
217
            ogrGeomType = converter.convertToOGRGeomType(geomType.getType());
218
        }
219

    
220
        List<FieldDefn> fields = converter.convertFields(defaultFeatureType);
221
        List<GeomFieldDefn> geomFields = converter.convertGeometryFields(defaultFeatureType, true);
222
        FeatureSet featureSet = getFeatureStore().getFeatureSet();
223
        createLayer(newDataSource, getLayer().GetName(), srs, ogrGeomType, fields, geomFields,
224
            featureSet);
225

    
226
        // Release native resources to close file.
227
        newDataSource.delete();
228

    
229
        // Close current file
230
        getResource().removeConsumer(this);
231
        getResource().closeRequest();
232

    
233
        // Delete current file
234
        if (getGMLParameters().getFile().delete()) {
235

    
236
            try {
237
                FileUtils.copyFile(newFile, getGMLParameters().getFile());
238
                FileUtils.copyFile(newSchemaFile, getSchemaFile(getGMLParameters().getFile()));
239
            } catch (IOException e) {
240
                throw new CopyException(newFile.getName(), e);
241
            }
242
        }
243

    
244
        this.resourceProvider = null;
245
        getResource().addConsumer(this);
246

    
247
        getResource().notifyChanges();
248
    }
249

    
250
    private Layer createLayer(DataSource dataSource, String layerName, SpatialReference srs,
251
        int ogrGeomType, List<FieldDefn> fields, List<GeomFieldDefn> geomFields,
252
        FeatureSet featureSet) throws DataException {
253

    
254
        Layer newLayer = createLayer(dataSource, layerName, srs, ogrGeomType, fields, geomFields);
255

    
256
        OGRConverter converter = new OGRConverter();
257
        DisposableIterator iterator = featureSet.fastIterator();
258

    
259
        try {
260
            while (iterator.hasNext()) {
261
                Feature feature = (Feature) iterator.next();
262
                FeatureProvider featureProvider =
263
                    getStoreServices().getFeatureProviderFromFeature(feature);
264
                org.gdal.ogr.Feature orgFeature = converter.convert(featureProvider);
265
                newLayer.CreateFeature(orgFeature);
266
            }
267
        } catch (BaseException e) {
268
            LOG.error("Can not convert featureProvider to OGR Feature", e);
269
            throw new WriteException(newLayer.GetName(), e);
270
        } finally {
271
            iterator.dispose();
272
        }
273

    
274
        return newLayer;
275
    }
276

    
277
    private Layer createLayer(DataSource dataSource, String layerName, SpatialReference srs,
278
        int ogrGeomType, List<FieldDefn> fields, List<GeomFieldDefn> geomFields,
279
        List<org.gdal.ogr.Feature> ogrFeatures) throws DataException {
280

    
281
        Layer newLayer = createLayer(dataSource, layerName, srs, ogrGeomType, fields, geomFields);
282
        OGRConverter converter = new OGRConverter();
283
        // Save features to new layer
284
        for (org.gdal.ogr.Feature feature : ogrFeatures) {
285
            org.gdal.ogr.Feature fixedFeature = converter.convert(newLayer.GetLayerDefn(), feature);
286
            newLayer.CreateFeature(fixedFeature);
287
        }
288

    
289
        return newLayer;
290
    }
291

    
292
    private Layer createLayer(DataSource dataSource, String layerName, SpatialReference srs,
293
        int ogrGeomType, List<FieldDefn> fields, List<GeomFieldDefn> geomFields) {
294

    
295
        Layer newLayer = null;
296

    
297
        // Create new layer
298
        if (srs == null) {
299
            newLayer = dataSource.CreateLayer(layerName);
300
        } else if (ogrGeomType == -1) {
301
            newLayer = dataSource.CreateLayer(layerName, srs);
302
        } else {
303
            newLayer = dataSource.CreateLayer(layerName, srs, ogrGeomType);
304
        }
305

    
306
        // Creating fields
307
        if (newLayer.TestCapability(ogrConstants.OLCCreateField)) {
308
            for (FieldDefn fieldDefn : fields) {
309
                newLayer.CreateField(fieldDefn);
310
            }
311
        } else {
312
            LOG.warn("{} driver does not support creation of fields", dataSource.GetDriver()
313
                .getName());
314
        }
315

    
316
        // Creating geometry fields
317
        if (newLayer.TestCapability(ogrConstants.OLCCreateGeomField)) {
318
            for (GeomFieldDefn geomFieldDefn : geomFields) {
319
                newLayer.CreateGeomField(geomFieldDefn);
320
            }
321
        } else {
322
            LOG.warn("{} driver does not support creation of geometry fields, only default"
323
                + " OGR geometry field has been created", dataSource.GetDriver().getName());
324
        }
325

    
326
        return newLayer;
327
    }
328

    
329
    private File getSchemaFile(File newFile) {
330
        String baseName = FilenameUtils.getBaseName(newFile.getName());
331
        File xsdFiel = new File(newFile.getParentFile(), baseName + ".xsd");
332
        return xsdFiel;
333
    }
334

    
335
    public void resourceChanged(ResourceProvider resource) {
336

    
337
        if (getGMLParameters().getXsdSchema() == null) {
338
            File schemaFile = getSchemaFile(getGMLParameters().getFile());
339
            if(schemaFile.exists()){
340
                getGMLParameters().setXsdSchema(schemaFile);
341
            } else {
342
                getGMLParameters().setXsdSchema(null);
343
            }
344
        }
345

    
346
        FeatureStore store = this.getStoreServices().getFeatureStore();
347
        FeatureType defaultFeatureType = null;
348
        try {
349
            defaultFeatureType = store.getDefaultFeatureType();
350
            getGMLParameters().setDefaultGeometryField(
351
                defaultFeatureType.getDefaultGeometryAttributeName());
352
        } catch (DataException e) {
353
            LOG.error("Can not default featury type of {}", this.getName());
354
            return;
355
        }
356
        super.resourceChanged(resource);
357
    }
358
}