GeoTools : ShapeReaderWriter

Basic reading/writing abilities demo: open a file, get the feature type, read the features and output a subset to a new shapefile. The hard-coded field 'HOUSHOLD' requires using the shapefile org/geotools/sampleData/statepop.shp

package org.geotools.demo.data;

import java.io.File;
import java.net.URL;
import javax.swing.JFileChooser;

//import org.geotools.data.DefaultQuery;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureType;
import org.geotools.filter.AttributeExpression;
import org.geotools.filter.BetweenFilter;
import org.geotools.filter.FilterFactory;
import org.geotools.filter.FilterFactoryFinder;
import org.geotools.filter.LiteralExpression;

/**
 * @author aaime
 * @author kablukiw
 */
public class ShapeReaderWriter {

    private static URL getResource(String path) {
        return ShapeReaderWriter.class.getClassLoader().getResource(path);
    }

    public static void main(String[] args) {
        try {

            String field = "HOUSHOLD";     //the attribute name to query on (default is "HOUSHOLD")
            double lowerBound = 100000.0;  //lower bound of query
            double upperBound = 300000.0;  //upper bound to query
            String newStoreURLString = ""; //url for output shapefile
            boolean createOutput = false;  //decide if an output shapefile should be created

            // get the shapefile URL by either loading it from the file system
            // or from the classpath
            URL shapeURL = null;
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setFileFilter(new SimpleFileFilter("shp", "Shapefile"));

            int result = fileChooser.showOpenDialog(null);

            if (result == JFileChooser.APPROVE_OPTION) {
                File f = fileChooser.getSelectedFile();
                shapeURL = f.toURL();
                // generate new shapefile filename by prepending "new_"
                newStoreURLString =
                    shapeURL.toString().substring(0,shapeURL.toString().lastIndexOf("/") + 1)
                    + "new_" +
                    shapeURL.toString().substring(shapeURL.toString().lastIndexOf("/") + 1);
                createOutput = true;
            }

            // get feature results
            ShapefileDataStore store = new ShapefileDataStore(shapeURL);
            // feature type name is defaulted to the name of shapefile (without extension)
            String name = store.getTypeNames()[0];
            FeatureSource source = store.getFeatureSource(name);
            FeatureCollection fsShape = source.getFeatures();

            // print out total number of features
            System.out.println(fsShape.size() + " features found in shapefile.");

            // get feature type to create new shapefile
            FeatureType ft = source.getSchema();

            // create filter to select only features that satify 300000 >= "field" >= 100000
            FilterFactory ff = FilterFactoryFinder.createFilterFactory();

            LiteralExpression literal200 = ff.createLiteralExpression(upperBound);
            LiteralExpression literal100 = ff.createLiteralExpression(lowerBound);
            AttributeExpression diExpression =
                ff.createAttributeExpression(field);

            BetweenFilter betweenFilter = ff.createBetweenFilter();

            betweenFilter.addLeftValue(literal100);
            betweenFilter.addMiddleValue(diExpression);
            betweenFilter.addRightValue(literal200);

            // perform query using the Query interface

            //DefaultQuery diQuery = new DefaultQuery(name, betweenFilter);
            //FeatureCollection fsFilteredShape = source.getFeatures(diQuery);

            // alternatively,

            // perform query using the Filter interface directly
            FeatureCollection fsFilteredShape = source.getFeatures(betweenFilter);

            System.out.println("Using a filter to query features with an attribute condition 300000 >= HOUSEHOLD >= 100000");
            System.out.println(fsFilteredShape.size() + " features returned from query.");
            System.out.println();

            if (createOutput) {
                // now print out the feature contents (including geometric attribute)

                // create new shapefile data store
                ShapefileDataStore newShapefileDataStore =
                    new ShapefileDataStore(new URL(newStoreURLString));

                // create the schema using from the original shapefile
                newShapefileDataStore.createSchema(ft);

                // grab the data source from the new shapefile data store
                FeatureSource newFeatureSource = newShapefileDataStore.
                getFeatureSource(name);

                // downcast FeatureSource to specific implementation of FeatureStore
                FeatureStore newFeatureStore = (FeatureStore)newFeatureSource;

                // accquire a transaction to create the shapefile from FeatureStore
                Transaction t = newFeatureStore.getTransaction();

                // add features got from the query (FeatureReader)
                //newFeatureStore.addFeatures(filteredReader);
                newFeatureStore.addFeatures(fsFilteredShape);

                // filteredReader is now exhausted and closed, commit the changes
                t.commit();
                t.close();

                System.out.println("Successfully create new shapefile "
                + newStoreURLString
                + " with " + fsFilteredShape.size()
                + " features out of " + fsShape.size()
                + " features.");
            }
        } catch (Exception e) {
            System.out.println("Ops! Something went wrong :-(");
            e.printStackTrace();
        }

        System.exit(0);
    }

}