hello all,
i'm seeing different behavior in the response to a WFS GetFeature
request when i specify a query limit v/s when i don't but only with
WFS 1.1.0; i.e. 1.0.0 returns the same (correct) result in both
cases. i'm including the test case i used to demonstrate the issue.
the code uses the GeoTools libraries version 2.5.3 and communicates
with a GeoServer 1.6.4b.
my questions which i'd appreciate an answer or guidance from a
GeoServer developer are:
* is this a known issue or i'm doing the wrong thing? if it's the
latter a push in the right direction is much appreciated.
* i thought of using the buffer-limit attribute with a WFS data
store in the hope to limit the output and allow the client side
code to close the store before getting _all_ the features this
also does not seem to fix the issue. again is it a known issue
or should i file a bug report.
* in the log/trace file with WFS 1.1 i see the following two
statements:
Supported filter: Filter.INCLUDE
Unsupported filter: Filter.INCLUDE
is it safe to ignore those statements?
here is the JUnit test case code:
// default package
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.DefaultQuery;
import org.geotools.data.FeatureSource;
import org.geotools.data.wfs.WFSDataStore;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
public class TestIncludeFilter extends TestCase {
private static final String BASE_URL =
"http://localhost:8080/geoserver/wfs?SERVICE=WFS&REQUEST=GetCapabilities";
private static final String CAPABILITIES_1_0 = BASE_URL + "&VERSION=1.0.0";
private static final String CAPABILITIES_1_1 = BASE_URL + "&VERSION=1.1.0";
private static final String LAYER_NAME = "topp:states";
private static final String ATTRIBUTE_NAMES = new String {
"STATE_NAME", "STATE_FIPS", "SUB_REGION" };
private static final int QUERY_LIMIT = 15;
// default constructor
public void testVersion1_0() throws IOException {
// Step 1 - connection parameters
final Map<String, Serializable> connectionParams =
new HashMap<String, Serializable>();
connectionParams.put(
"WFSDataStoreFactory:GET_CAPABILITIES_URL", CAPABILITIES_1_0);
_test(connectionParams, 0);
_test(connectionParams, QUERY_LIMIT);
}
public void testVersion1_1_POST() throws IOException {
// Step 1 - connection parameters
final Map<String, Serializable> connectionParams =
new HashMap<String, Serializable>();
connectionParams.put(
"WFSDataStoreFactory:GET_CAPABILITIES_URL", CAPABILITIES_1_1);
// connectionParams.put(
// "WFSDataStoreFactory:BUFFER_SIZE", 5);
connectionParams.put("WFSDataStoreFactory:PROTOCOL", Boolean.TRUE);
_test(connectionParams, 0);
_test(connectionParams, QUERY_LIMIT);
}
public void
_test(final Map<String, Serializable> connectionParams, final int limit)
throws IOException {
// Step 2 - connection
final WFSDataStore ds =
(WFSDataStore) DataStoreFinder.getDataStore(connectionParams);
assertNotNull("Data store MUST NOT be null", ds);
// Step 3 - discovery
final List<String> typeNames = Arrays.asList(ds.getTypeNames());
assertNotNull("Type names MUST NOT be null", typeNames);
assertFalse("Type names MUST NOT be empty", typeNames.isEmpty());
assertTrue(
"Type names MUST contain [" + LAYER_NAME + "]",
typeNames.contains(LAYER_NAME));
final SimpleFeatureType schema = ds.getSchema(LAYER_NAME);
assertNotNull("Feature type (schema) MUST NOT be null", schema);
final List<AttributeDescriptor> attributes =
schema.getAttributeDescriptors();
assertNotNull("Attributes list MUST NOT be null", attributes);
assertTrue(
"Attributes list MUST contain at least 3 elements",
attributes.size() > 2);
for (final String atName : ATTRIBUTE_NAMES)
assertTrue(
"Attribute named [" + atName + "] MUST be found",
contains(attributes, atName));
// Step 4 - query
final int result = process(ds, limit);
System.out.println("*** result = " + result);
assertTrue("MUST be able to find at least one feature", result > 0);
}
private boolean
contains(final List<AttributeDescriptor> attributes, final String atName) {
boolean result = false;
for (final AttributeDescriptor attribute : attributes)
if (attribute.getLocalName().equals(atName)) {
result = true;
break;
}
return result;
}
private int process(final DataStore dataStore, final int limit)
throws IOException {
final DefaultQuery q = new DefaultQuery(LAYER_NAME);
q.setPropertyNames(ATTRIBUTE_NAMES);
if (limit > 0) q.setMaxFeatures(QUERY_LIMIT);
final FeatureSource<SimpleFeatureType, SimpleFeature> fs =
dataStore.getFeatureSource(LAYER_NAME);
final FeatureCollection<SimpleFeatureType, SimpleFeature> fc =
fs.getFeatures(q);
FeatureIterator<SimpleFeature> fit = null;
int result = 0;
try {
for (fit = fc.features(); fit.hasNext() {
fit.next();
result++;
}
} finally {
if (fit != null) fc.close(fit);
}
System.out.println("*** INCLUDE filter, for "
+ ATTRIBUTE_NAMES.length + " attributes, with "
+ (limit == 0 ? "NO limit" : "a limit of (" + limit + ")")
+ ", found " + result + " feature(s)");
return result;
}
}
TIA + cheers;
rsn