Skip to content

Commit

Permalink
Merge pull request #46 from jdeolive/featurecollection_cleanup_origional
Browse files Browse the repository at this point in the history
Additional changes to feature collection cleanup branch.
  • Loading branch information
jodygarnett committed Nov 4, 2012
2 parents c0fd151 + 05a027b commit 11d582c
Show file tree
Hide file tree
Showing 15 changed files with 222 additions and 131 deletions.
Expand Up @@ -16,166 +16,144 @@
*/ */
package org.geotools.wfs; package org.geotools.wfs;


import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;


import org.geotools.data.DataUtilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.factory.CommonFactoryFinder; import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator; import org.geotools.feature.FeatureIterator;
import org.geotools.feature.NameImpl; import org.geotools.feature.NameImpl;
import org.geotools.feature.collection.BaseFeatureCollection;
import org.geotools.feature.collection.DecoratingFeatureCollection; import org.geotools.feature.collection.DecoratingFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.feature.type.FeatureTypeFactoryImpl; import org.geotools.feature.type.FeatureTypeFactoryImpl;
import org.geotools.gml3.v3_2.GML; import org.geotools.gml3.v3_2.GML;
import org.geotools.xs.XS; import org.geotools.xs.XS;
import org.opengis.feature.Attribute;
import org.opengis.feature.Feature; import org.opengis.feature.Feature;
import org.opengis.feature.FeatureFactory; import org.opengis.feature.FeatureFactory;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType; import org.opengis.feature.type.AttributeType;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.FeatureTypeFactory; import org.opengis.feature.type.FeatureTypeFactory;
import org.opengis.feature.type.Name; import org.opengis.feature.type.Name;
import org.opengis.feature.type.Schema; import org.opengis.feature.type.Schema;


/** /**
* Wrapping feature collection used by GetPropertyValue operation. * Wrapping feature collection used by GetPropertyValue operation.
* <p> * <p>
* This feature collection pulls only the specified property out of the delegate feature collection. * This feature collection pulls only the specified property out of the delegate
* feature collection.
* </p> * </p>
*
* @author Justin Deoliveira, OpenGeo * @author Justin Deoliveira, OpenGeo
* *
*/ */
public class PropertyValueCollection extends BaseFeatureCollection { public class PropertyValueCollection extends AbstractCollection<Attribute> {


static FeatureTypeFactory typeFactory = new FeatureTypeFactoryImpl(); static FeatureTypeFactory typeFactory = new FeatureTypeFactoryImpl();

static FeatureFactory factory = CommonFactoryFinder.getFeatureFactory(null); static FeatureFactory factory = CommonFactoryFinder.getFeatureFactory(null);


FeatureCollection delegate;
AttributeDescriptor descriptor; AttributeDescriptor descriptor;
List<Schema> typeMappingProfiles = new ArrayList();


List<Schema> typeMappingProfiles = new ArrayList<Schema>(); public PropertyValueCollection(FeatureCollection delegate, AttributeDescriptor descriptor) {

private SimpleFeatureCollection delegate;

public PropertyValueCollection(SimpleFeatureCollection delegate, AttributeDescriptor descriptor) {
super(null); // we will create the schema later
this.delegate = delegate; this.delegate = delegate;
this.descriptor = descriptor; this.descriptor = descriptor;

this.typeMappingProfiles.add(XS.getInstance().getTypeMappingProfile()); this.typeMappingProfiles.add(XS.getInstance().getTypeMappingProfile());
this.typeMappingProfiles.add(GML.getInstance().getTypeMappingProfile()); this.typeMappingProfiles.add(GML.getInstance().getTypeMappingProfile());

// create a new descriptor based on the xml type
Class<?> binding = descriptor.getType().getBinding();
AttributeType xmlType = findType(binding);
if (xmlType == null) {
throw new RuntimeException("Unable to map attribute " + descriptor.getName()
+ " to xml type");
}
// because simple features don't carry around their namespace, create a descriptor name
// that actually used the feature type schema namespace
SimpleFeatureType origionalSchema = delegate.getSchema();

Name name = new NameImpl(origionalSchema.getName().getNamespaceURI(),
descriptor.getLocalName());
AttributeDescriptor newDescriptor = typeFactory.createAttributeDescriptor(xmlType, name,
descriptor.getMinOccurs(), descriptor.getMaxOccurs(), descriptor.isNillable(),
descriptor.getDefaultValue());

SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(typeFactory);
builder.setName(origionalSchema.getName());
builder.add(newDescriptor);

this.schema = builder.buildFeatureType();
} }


/** @Override
* Look in the {@link #typeMappingProfiles} for the official AttributeType for the provided java class. public int size() {
* //JD: this is a lie, since we skip over features without the attribute
* @param binding Java class being represented return delegate.size();
* @return AttributeType from {@link #typeMappingProfiles} {@link XS} and {@link GML}
*/
AttributeType findType(Class<?> binding) {
for (Schema schema : typeMappingProfiles) {
for (Map.Entry<Name, AttributeType> e : schema.entrySet()) {
AttributeType at = e.getValue();
if (at.getBinding() != null && at.getBinding().equals(binding)) {
return at;
}
}
for (AttributeType at : schema.values()) {
if (binding.isAssignableFrom(at.getBinding())) {
return at;
}
}
}
return null;
} }


@Override @Override
public SimpleFeatureIterator features() { public Iterator iterator() {
return new PropertyValueIterator(delegate.features()); return new PropertyValueIterator(delegate.features());
} }


class PropertyValueIterator implements SimpleFeatureIterator { class PropertyValueIterator implements Iterator {
SimpleFeatureIterator it;

FeatureIterator it;
SimpleFeature next; Feature next;


SimpleFeatureBuilder builder; PropertyValueIterator(FeatureIterator it) {

this.it = it;
PropertyValueIterator(SimpleFeatureIterator featureIterator) {
this.it = featureIterator;
this.builder = new SimpleFeatureBuilder(schema);
} }


@Override @Override
public boolean hasNext() { public boolean hasNext() {
if (it == null) {
return false;
}
if (next == null) { if (next == null) {
while (it.hasNext()) { while(it.hasNext()) {
SimpleFeature f = it.next(); Feature f = (Feature) it.next();
if (f.getProperty(descriptor.getName()).getValue() != null) { if (f.getProperty(descriptor.getName()).getValue() != null) {
next = f; next = f;
break; break;
} }
} }
} }
return next != null;
}


@Override if (next != null) {
public SimpleFeature next() { return true;
// Object value = next.getProperty(descriptor.getName()).getValue(); }
// return (F) factory.createAttribute(value, newDescriptor, null);


Object value = next.getAttribute(descriptor.getName()); //close the iterator
String fid = next.getID(); it.close();
it = null;
return false;
}


@Override
public Object next() {
//create a new descriptor based on teh xml type
AttributeType xmlType = findType(descriptor.getType().getBinding());
if (xmlType == null) {
throw new RuntimeException("Unable to map attribute " + descriptor.getName() +
" to xml type");
}

Object value = next.getProperty(descriptor.getName()).getValue();

//because simple features don't carry around their namespace, create a descritor name
// that actually used the feature type schema namespace
Name name = new NameImpl(next.getType().getName().getNamespaceURI(), descriptor.getLocalName());
AttributeDescriptor newDescriptor = typeFactory.createAttributeDescriptor(xmlType,
name, descriptor.getMinOccurs(), descriptor.getMaxOccurs(),
descriptor.isNillable(), descriptor.getDefaultValue());

next = null; next = null;

return factory.createAttribute(value, newDescriptor, null);
builder.add(value);
SimpleFeature newFeature = builder.buildFeature(fid);
return newFeature;
} }


@Override @Override
public void close() { public void remove() {
if (it != null) { throw new UnsupportedOperationException();
it.close(); }

AttributeType findType(Class binding) {
for (Schema schema : typeMappingProfiles) {
for (Map.Entry<Name,AttributeType> e : schema.entrySet()) {
AttributeType at = e.getValue();
if (at.getBinding() != null && at.getBinding().equals(binding)) {
return at;
}
}


for (AttributeType at : schema.values()) {
if (binding.isAssignableFrom(at.getBinding())) {
return at;
}
}
} }
it = null; return null;
} }
} }

} }
Expand Up @@ -87,9 +87,10 @@ public Object getProperty(Object object, QName name) throws Exception {
if (WFS.member.equals(name)) { if (WFS.member.equals(name)) {
return ((ValueCollectionType)object).getMember().iterator().next(); return ((ValueCollectionType)object).getMember().iterator().next();
} }
else { return null;
return WFSParsingUtils.FeatureCollectionType_getProperty((EObject)object, name); //else {
} // return WFSParsingUtils.FeatureCollectionType_getProperty((EObject)object, name);
//}
} }


} }
Expand Up @@ -55,7 +55,7 @@ protected void setUp() throws Exception {
public void testNothing(){ public void testNothing(){
// just to prevent build failure // just to prevent build failure
} }
public void XtestEncode() throws Exception { public void testEncode() throws Exception {
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.setName("feature"); tb.setName("feature");
tb.setNamespaceURI("http://geotools.org"); tb.setNamespaceURI("http://geotools.org");
Expand Down
Expand Up @@ -120,6 +120,10 @@ public boolean containsAll(Collection<?> c) {
return true; return true;
} }


public FeatureIterator<F> features() {
return new FilteringFeatureIterator<F>(delegate.features(), filter);
}

public FeatureReader<T, F> reader() throws IOException { public FeatureReader<T, F> reader() throws IOException {
return new DelegateFeatureReader<T, F>( getSchema(), features() ); return new DelegateFeatureReader<T, F>( getSchema(), features() );
} }
Expand Down
Expand Up @@ -18,37 +18,34 @@


import java.util.NoSuchElementException; import java.util.NoSuchElementException;


import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.FeatureIterator; import org.geotools.feature.FeatureIterator;
import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.Feature;
import org.opengis.filter.Filter; import org.opengis.filter.Filter;


/** /**
* Decorates a SimpleFeatureIterator with one that filters content. * Decorates a FeatureIterator with one that filters content.
* *
* @author Justin Deoliveira, The Open Planning Project * @author Justin Deoliveira, The Open Planning Project
* *
* *
*
*
* @source $URL$ * @source $URL$
*/ */
public class FilteringFeatureIterator implements SimpleFeatureIterator { public class FilteringFeatureIterator<F extends Feature> implements FeatureIterator<F> {


/** /**
* delegate iterator * delegate iterator
*/ */
protected SimpleFeatureIterator delegate; protected FeatureIterator<F> delegate;
/** /**
* The Filter * The Filter
*/ */
protected Filter filter; protected Filter filter;
/** /**
* Next feature * Next feature
*/ */
protected SimpleFeature next; protected F next;


public FilteringFeatureIterator( SimpleFeatureIterator delegate, Filter filter ) { public FilteringFeatureIterator( FeatureIterator<F> delegate, Filter filter ) {
this.delegate = delegate; this.delegate = delegate;
this.filter = filter; this.filter = filter;
} }
Expand All @@ -59,7 +56,7 @@ public boolean hasNext() {
} }


while( delegate.hasNext() ) { while( delegate.hasNext() ) {
SimpleFeature peek = (SimpleFeature) delegate.next(); F peek = (F) delegate.next();
if ( filter.evaluate( peek ) ) { if ( filter.evaluate( peek ) ) {
next = peek; next = peek;
break; break;
Expand All @@ -69,8 +66,8 @@ public boolean hasNext() {
return next != null; return next != null;
} }


public SimpleFeature next() throws NoSuchElementException { public F next() throws NoSuchElementException {
SimpleFeature f = next; F f = next;
next = null; next = null;
return f; return f;
} }
Expand Down
Expand Up @@ -65,7 +65,7 @@ public FilteringSimpleFeatureCollection( SimpleFeatureCollection delegate, Filte
} }


public SimpleFeatureIterator features() { public SimpleFeatureIterator features() {
return new FilteringFeatureIterator( delegate.features(), filter ); return new FilteringSimpleFeatureIterator( delegate.features(), filter );
} }


public void close(SimpleFeatureIterator close) { public void close(SimpleFeatureIterator close) {
Expand Down
@@ -0,0 +1,37 @@
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2012, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.feature.collection;

import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.store.FilteringFeatureIterator;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;

/**
* Extension of {@link FilteringFeatureIterator} that type narrows to {@link SimpleFeature}.
*
* @author Justin Deoliveira, OpenGeo
*
*/
public class FilteringSimpleFeatureIterator extends FilteringFeatureIterator<SimpleFeature>
implements SimpleFeatureIterator {

public FilteringSimpleFeatureIterator(SimpleFeatureIterator delegate, Filter filter) {
super(delegate, filter);
}

}
Expand Up @@ -92,7 +92,7 @@ public SubFeatureCollection(SimpleFeatureCollection collection, Filter subfilter
} }


public SimpleFeatureIterator features() { public SimpleFeatureIterator features() {
return new FilteringFeatureIterator( collection.features(), filter()); return new FilteringSimpleFeatureIterator( collection.features(), filter());
} }


public int size() { public int size() {
Expand Down

0 comments on commit 11d582c

Please sign in to comment.