This plugin allows the GeoTools library to interact with a Web Feature Server using the normal DataStore API.
The WFS Plugin is currently unsupported, this represents a lack of funding rather than any short fall in maturity or stability.
Resources
Maven:
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-wfs</artifactId>
<version>${geotools.version}</version>
</dependency>
The following connection parameters are defined for WFS.
| Param | Description |
|---|---|
| “WFSDataStoreFactory:GET_CAPABILITIES_URL” | Link to capabilities document. The implementation supports both WFS 1.0 (read/write) and WFS 1.1 (read-only). |
| “WFSDataStoreFactory:PROTOCOL” | Optional: True for Post, False for GET, null for auto |
| “WFSDataStoreFactory:USERNAME” | Optional |
| “WFSDataStoreFactory:PASSWORD” | Optional |
| “WFSDataStoreFactory:ENCODING” | Optional with a default of UTF-8 |
| “WFSDataStoreFactory:TIMEOUT” | Optional with a 3000ms default |
| “WFSDataStoreFactory:BUFFER_SIZE” | Optional number of features to read in one gulp, defaults of 10 |
| “WFSDataStoreFactory:TRY_GZIP” | Optional with a default of true, try compression if available |
| “WFSDataStoreFactory:LENIENT” | Optional default of true. WFS implementations are terrible for actually obeying their DescribeFeatureType schema, setting this to true will try a few tricks to support implementations that are mostly correct:
|
| “WFSDataStoreFactory:MAXFEATURES” | Limit on the number of features |
| “WFSDataStoreFactory:WFS_STRATEGY” | Optional used to engage specific work arounds for known servers.
You may need use this override if you are using mapserver with a custom URL not recognised by auto detection. WFS1.1 supports autodetection based on full capabilities doc for greater accuracy. |
| “WFSDataStoreFactory:FILTER_COMPLIANCE” | Optional used override how GetFeature operations encodes filters
In general compliance levels stress the handling of Id filters which are not allowed with other filters (AND / OR / NOT). You may relax this constraint when working with some WFS implementations such as GeoServer. |
| “WFSDataStoreFactory:USEDEFAULTSRS” | Optional used override how GetFeature operations send srs to wfs server
Choose if you prefer to always use DefaultSRS declared in capabilities and reproject using GeoTools if necessary, or use also OtherSRS if available. The false value is currently supported in 1.1.0 protocol only. |
Historical Note: We apologise for the long connection parameter keys, WFS was one of the first DataStores written and we were unsure at the time if they keys for each datastore would need to be unique or not. On the plus side you can see our devotion to stability.
Hints:
Support for Web Feature Server Example (WFS) offers access to the raw features being served up from an external server.
The following is a quick example; only the connection parameter code is specific to the WFSDataStore.
You can connect to a Web Feature Server via the DataStore API; the connection parameters are as follows:
String getCapabilities = "http://localhost:8080/geoserver/wfs?REQUEST=GetCapabilities";
Map connectionParameters = new HashMap();
connectionParameters.put("WFSDataStoreFactory:GET_CAPABILITIES_URL", getCapabilities );
// Step 2 - connection
DataStore data = DataStoreFinder.getDataStore( connectionParameters );
// Step 3 - discouvery
String typeNames[] = data.getTypeNames();
String typeName = typeNames[0];
SimpleFeatureType schema = data.getSchema( typeName );
// Step 4 - target
FeatureSource<SimpleFeatureType, SimpleFeature> source = data.getFeatureSource( typeName );
System.out.println( "Metadata Bounds:"+ source.getBounds() );
// Step 5 - query
String geomName = schema.getDefaultGeometry().getLocalName();
Envelope bbox = new Envelope( -100.0, -70, 25, 40 );
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2( GeoTools.getDefaultHints() );
Object polygon = JTS.toGeometry( bbox );
Intersects filter = ff.intersects( ff.property( geomName ), ff.literal( polygon ) );
Query query = new DefaultQuery( typeName, filter, new String[]{ geomName } );
FeatureCollection<SimpleFeatureType, SimpleFeature> features = source.getFeatures( query );
ReferencedEnvelope bounds = new ReferencedEnvelope();
Iterator<SimpleFeature> iterator = features.iterator();
try {
while( iterator.hasNext() ){
Feature feature = (Feature) iterator.next();
bounds.include( feature.getBounds() );
}
System.out.println( "Calculated Bounds:"+ bounds );
}
finally {
features.close( iterator );
}
Support for Web Feature Server Transactional (WFS-T) represents a wfs that offers read/write functionality by virtue of supporting the WFS Transaction operation.
Please note that WFS-T (ie Transaction) only works when:
you have started a GeoTools transaction.
(Transaction.AUTO_COMMIT is not supported for editing)
you use WFS 1.0
(talk to Gabriel if you would like to supply a patch; or fund the development of 1.1 WFS-T)
The usual FeatureStore methods work:
There is likely to be some additional support for WFS options involving the management of newly created FeatureIDs. Work is happening in trunk currently to support this and the GeoTools level - it is another option to talk to Gabriel if you find your organisation needs this ability.
The handling of FeatureIDs is tricky; in that he Web Feature Server does not assign an ID until you call commit(). The FeatureIDs returned by FeatureStore.addFeatures() is temporary (often beginning with “new”).
There are two ways to get advised of the official feature ids.
Listen for a BatchFeatureEvent; this contains the mapping of temporary feature id to official feature id.
Dig into the WFSTransaction for the details.
During commit() the WFSTransaction object is used to build up the Transaction request to be sent to the web feature server. When the TransactionResponse comes back, it is parsed, and some of the results (such as new feature ids) saved in the WFSTransaction where you can get at them.
Example acccessing WFSTransaction:
Transaction transaction = new transaction("insert");
try {
SimpleFeatureStore featureStore =
(SimpleFeatureStore) wfs.getFeatureSource( typeName );
featureStore.setTransaction( transaction );
featureStore.addFeatures( DataUtilities.collection( feature ) );
transaction.commit();
// get the final feature id
WFSTransactionState state = (WFSTransactionState) transaction.getState(wfs);
// In this example there is only one fid. Get it.
String[] fids = state.getFids( typeName );
String result = fids[0];
}
finally {
transaction.close();
}