GeoTools : The shapefile filter tool Example

If the above information is a little overwhelming, don't worry. The following example should help illustrate how this can be accomplished.

Let's look at a simple demo app that allows the user to write a new shapefile from the result of filtering an input shapefile (based on ShapeReader class). This example uses the FeatureStore::addFeatures() method to add Features to a new Shapefile. The Features (in a FeatureReader) that are added to the new shapefile are obtained from a Filter on an existing shapefile.

  • creates a shapefile datastore from the URL and gets out the single feature type in this datastore;
// get feature results
DataStore store = new ShapefileDataStore(shapeURL);
String name = store.getTypeNames()[0];
FeatureSource source = store.getFeatureSource(name);
FeatureResults fsShape = source.getFeatures();

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

// get feature type to create the new shapefile
FeatureType ft = source.getSchema();
  • here we assume the shapefile contains an attribute named "DI" and we would like to create a new shapefile only for those features that has DI between 100 and 200;
// create filter to select only features that satify 200 >= DI >= 100
FilterFactory ff = FilterFactory.createFilterFactory();

LiteralExpression literal200 = ff.createLiteralExpression(200.0);
LiteralExpression literal100 = ff.createLiteralExpression(100.0);
AttributeExpression diExpression = ff.createAttributeExpression(ft, "DI");

BetweenFilter betweenFilter = ff.createBetweenFilter();

  • next, we will perform the query using the created Filter object;
// perform query using the Filter interface directly
FeatureResults fsFilteredShape = source.getFeatures(betweenFilter);
System.out.println(fsFilteredShape.getCount() + " features returned from query.");

  • additionally, we could use a Query object to limit the number of features the query returns;
// perform query using the Query interface

DefaultQuery diQuery = new DefaultQuery(betweenFilter);
FeatureResults fsFilteredShape = source.getFeatures(name, diQuery);
  • finally, create a new ShapefileDataStore and write out the feature query results;
// now, create a FeatureReader to get the queried features
FeatureReader filteredReader = fsFilteredShape.reader();

// generate new shapefile filename by prepending "new_"
String newStoreURLString =
	shapeURL.toString().substring(0, shapeURL.toString().lastIndexOf("/") + 1)
	+ "new_" +
	shapeURL.toString().substring(shapeURL.toString().lastIndexOf("/") + 1);

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

// create the schema based on the original shapefile

// grab the feature 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)

// filteredReader is now exhausted and closed, commit the changes

That's it! Hope you enjoy it.