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 new featureType will need to be done according to the procedure for your WFS prior to calling addFeature.

    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 content

  • You may wish to adjust the featureType information, especially the lengths of strings prior to calling createSchema