Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

GEOT-4259 #27

Merged
merged 1 commit into from

3 participants

@sgraca

A fix for GEOT-4259: Under some conditions all attributes are unnecessarily read from dbf file

@jodygarnett
Owner

I kind of like this one, has a test case. I could grab it for master and try it out.

@aaime
Owner

Looks good, merged

@aaime aaime merged commit 17dd25f into geotools:8.x
@sgraca sgraca deleted the sgraca:GEOT-4259 branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 17, 2012
  1. @sgraca

    GEOT-4259 Under some conditions all attributes are unnecessarily read…

    sgraca authored Sebastian Graca committed
    … from dbf file
This page is out of date. Refresh to see the latest.
View
53 modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShapefileDataStore.java
@@ -38,6 +38,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -393,7 +394,7 @@ public boolean isLocal() {
public FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader() throws IOException {
try {
return createFeatureReader(getSchema().getTypeName(),
- getAttributesReader(true, null), schema);
+ getAttributesReader(true, null, null), schema);
} catch (SchemaException se) {
throw new DataSourceException("Error creating schema", se);
}
@@ -431,20 +432,44 @@ public boolean isLocal() {
schema, propertyNames);
return createFeatureReader(typeName,
- getAttributesReader(false, query), newSchema);
+ getAttributesReader(false, query, propertyNames), newSchema);
} catch (SchemaException se) {
throw new DataSourceException("Error creating schema", se);
}
}
try {
- return createFeatureReader(getSchema().getTypeName(),
- getAttributesReader(true, query), schema);
+ String[] requiredProperties = null;
+ SimpleFeatureType newSchema = schema;
+ if (propertyNames != null) {
+ Set<String> props = new HashSet<String>();
+ props.addAll(Arrays.asList(propertyNames));
+ if (filterAttnames != null) {
+ props.addAll(Arrays.asList(filterAttnames));
+ }
+ requiredProperties = getPropertiesInOrder(props);
+ newSchema = DataUtilities.createSubType(
+ schema, requiredProperties);
+ }
+ return createFeatureReader(typeName,
+ getAttributesReader(true, query, requiredProperties), newSchema);
} catch (SchemaException se) {
throw new DataSourceException("Error creating schema", se);
}
}
+ private String[] getPropertiesInOrder(Set<String> props) {
+ String[] properties = new String[props.size()];
+ int idx = 0;
+ for (AttributeDescriptor descriptor : schema.getAttributeDescriptors()) {
+ if (props.contains(descriptor.getLocalName())) {
+ properties[idx++] = descriptor.getLocalName();
+ }
+ }
+ return properties;
+ }
+
+
/**
* Builds the most appropriate geometry factory depending on the available query hints
* @param query
@@ -492,11 +517,12 @@ protected GeometryFactory getGeometryFactory(Hints hints) {
*
* @throws IOException
*/
- protected ShapefileAttributeReader getAttributesReader(boolean readDbf, Query q)
+ protected ShapefileAttributeReader getAttributesReader(boolean readDbf, Query q, String[] properties)
throws IOException {
List<AttributeDescriptor> atts = (schema == null) ? readAttributes()
: schema.getAttributeDescriptors();
+ atts = retainDescriptors(atts, properties);
GeometryFactory geometryFactory;
if(q != null) {
@@ -545,6 +571,21 @@ protected ShapefileAttributeReader getAttributesReader(boolean readDbf, Query q)
return result;
}
+ private static List<AttributeDescriptor> retainDescriptors(List<AttributeDescriptor> atts,
+ String[] properties) {
+ if (properties == null || properties.length == atts.size()) {
+ return atts;
+ }
+ List<AttributeDescriptor> descriptors = new ArrayList<AttributeDescriptor>(properties.length);
+ Set<String> names = new HashSet<String>(Arrays.asList(properties));
+ for (AttributeDescriptor att : atts) {
+ if (names.contains(att.getLocalName())) {
+ descriptors.add(att);
+ }
+ }
+ return descriptors;
+ }
+
/**
* Convenience method for opening a ShapefileReader.
*
@@ -702,7 +743,7 @@ protected void typeCheck(String requested) throws IOException {
typeCheck(typeName);
FeatureReader<SimpleFeatureType, SimpleFeature> featureReader;
- ShapefileAttributeReader attReader = getAttributesReader(true, null);
+ ShapefileAttributeReader attReader = getAttributesReader(true, null, null);
try {
SimpleFeatureType schema = getSchema();
if (schema == null) {
View
3  modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/indexed/IndexedShapefileDataStore.java
@@ -351,13 +351,14 @@ protected TransactionStateDiff state(Transaction transaction) {
if (query.getFilter() == Filter.EXCLUDE)
return new EmptyFeatureReader<SimpleFeatureType, SimpleFeature>(getSchema());
+ boolean allProperties = query.getPropertyNames() == null;
String[] propertyNames = query.getPropertyNames() == null ? new String[0]
: query.getPropertyNames();
String defaultGeomName = schema.getGeometryDescriptor().getLocalName();
// add the attributes we need to read to keep the filtering going
- if(propertyNames.length > 0) {
+ if(!allProperties) {
FilterAttributeExtractor fae = new FilterAttributeExtractor(schema);
query.getFilter().accept(fae, null);
View
17 modules/plugin/shapefile/src/test/java/org/geotools/data/shapefile/ShapefileDataStoreTest.java
@@ -798,7 +798,22 @@ public void testGetReaderOptimizations() throws Exception {
query = new DefaultQuery(s.getSchema().getTypeName(), cf,
new String[] { "the_geom" });
reader = s.getFeatureReader(s.getSchema().getTypeName(), query);
- assertEquals(s.getSchema(), reader.getFeatureType());
+ assertEquals(2, reader.getFeatureType().getAttributeCount());
+ assertNotNull(reader.getFeatureType().getDescriptor("the_geom"));
+ assertNotNull(reader.getFeatureType().getDescriptor("STATE_NAME"));
+ reader.close();
+ s.dispose();
+ }
+
+ public void testReadOnlyRequiredAttributes() throws Exception {
+ URL url = TestData.url(STATE_POP);
+ ShapefileDataStore s = new ShapefileDataStore(url);
+
+ Filter cf = ff.equals(ff.property("STATE_NAME"), ff.literal("Illinois"));
+ Query query = new Query(s.getSchema().getTypeName(), cf, Query.NO_PROPERTIES);
+ FeatureReader<SimpleFeatureType, SimpleFeature> reader = s.getFeatureReader(s.getSchema().getTypeName(), query);
+ assertEquals(1, reader.getFeatureType().getAttributeCount());
+ assertNotNull(reader.getFeatureType().getDescriptor("STATE_NAME"));
reader.close();
s.dispose();
}
Something went wrong with that request. Please try again.