Exporting¶
One common thing people want to do is grab data existing data and export to a shapefile or PostGIS. A lot of desktop and server applications work very well with shapefiles.
There are a few tricks to keep in mind when taking information between different formats and we cover a few examples on this page.
References:
- doc:
/tutorial/geometry/geometrycrs tutorial covers transforming a shapefile
Memory¶
When working on your own application you will often store your data in a MemoryDataStore it is under construction.
The following example shows how to export out a MemoryDataStore as a single shapefile:
DataStore exportToShapefile(MemoryDataStore memory, String typeName, File directory) throws IOException { // existing feature source from MemoryDataStore SimpleFeatureSource featureSource = memory.getFeatureSource(typeName); SimpleFeatureType ft = featureSource.getSchema(); String fileName = ft.getTypeName(); File file = new File(directory, fileName + ".shp"); Map<String, java.io.Serializable> creationParams = new HashMap<>(); creationParams.put("url", URLs.fileToUrl(file)); FileDataStoreFactorySpi factory = FileDataStoreFinder.getDataStoreFactory("shp"); DataStore dataStore = factory.createNewDataStore(creationParams); dataStore.createSchema(ft); // The following workaround to write out the prj is no longer needed // ((ShapefileDataStore)dataStore).forceSchemaCRS(ft.getCoordinateReferenceSystem()); SimpleFeatureStore featureStore = (SimpleFeatureStore) dataStore.getFeatureSource(typeName); Transaction t = new DefaultTransaction(); try { SimpleFeatureCollection collection = featureSource.getFeatures(); // grab all features featureStore.addFeatures(collection); t.commit(); // write it out } catch (IOException eek) { eek.printStackTrace(); try { t.rollback(); } catch (IOException doubleEeek) { // rollback failed? } } finally { t.close(); } return dataStore; }
We also have an alternative example (thanks Gaby) using FeatureWriter.
FeatureSource and FeatureCollection are high level API, to get down and dirty you can use the low-level FeatureReader / FeatureWriter API.
DataStore exportToShapefile2(MemoryDataStore memory, String typeName, File directory) throws IOException { // existing feature source from MemoryDataStore SimpleFeatureSource featureSource = memory.getFeatureSource(typeName); SimpleFeatureType ft = featureSource.getSchema(); String fileName = ft.getTypeName(); File file = new File(directory, fileName + ".shp"); Map<String, java.io.Serializable> creationParams = new HashMap<>(); creationParams.put("url", URLs.fileToUrl(file)); FileDataStoreFactorySpi factory = FileDataStoreFinder.getDataStoreFactory("shp"); DataStore dataStore = factory.createNewDataStore(creationParams); dataStore.createSchema(ft); SimpleFeatureStore featureStore = (SimpleFeatureStore) dataStore.getFeatureSource(typeName); try (Transaction t = new DefaultTransaction()) { SimpleFeatureCollection collection = featureSource.getFeatures(); // grab all features FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter(typeName, t); SimpleFeatureIterator iterator = collection.features(); SimpleFeature feature; try { while (iterator.hasNext()) { feature = iterator.next(); // Step1: create a new empty feature on each call to next SimpleFeature aNewFeature = writer.next(); // Step2: copy the values in aNewFeature.setAttributes(feature.getAttributes()); // Step3: write out the feature writer.write(); } } catch (IOException eek) { eek.printStackTrace(); try { t.rollback(); } catch (IOException doubleEeek) { // rollback failed? } } } return dataStore; }
A couple of hints:
Shapefile does note support “Geometry” so if you are working with mixed content you will need to export out three shapefiles, one for point, line and polygon.
WFS¶
You can use the above technique to copy from a WFS to a Shapefile.
A couple of hints:
Please be advised that WFS TypeNames are not always valid filenames; you should take a moment to change non alphanumeric characters to “_” before generating the filename.:
.. literalinclude:: /../src/main/java/org/geotools/data/DataExamples.java :language: java :start-after: // fixWFSTypeName start :end-before: // fixWFSTypeName end
The WFS-T protocol does not allow us to implement
createSchema
so creating a newfeatureType
will need to be done according to the procedure for your WFS prior to callingaddFeature
.As an example GeoServer supports the use of a REST API for this purpose.
PostGIS¶
To copy information into PostGIS:
You can export from PostGIS as expected using the examples above
PostGIS also supports
createSchema
allowing you to create a new table to hold the contentYou may wish to adjust the
featureType
information, especially the lengths of strings prior to callingcreateSchema