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;

import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
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.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.NameImpl;
import org.geotools.feature.collection.BaseFeatureCollection;
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.gml3.v3_2.GML;
import org.geotools.xs.XS;
import org.opengis.feature.Attribute;
import org.opengis.feature.Feature;
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.AttributeType;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.FeatureTypeFactory;
import org.opengis.feature.type.Name;
import org.opengis.feature.type.Schema;

/**
* Wrapping feature collection used by GetPropertyValue operation.
* <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>
*
* @author Justin Deoliveira, OpenGeo
*
*
*/
public class PropertyValueCollection extends BaseFeatureCollection {
public class PropertyValueCollection extends AbstractCollection<Attribute> {

static FeatureTypeFactory typeFactory = new FeatureTypeFactoryImpl();

static FeatureFactory factory = CommonFactoryFinder.getFeatureFactory(null);

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

List<Schema> typeMappingProfiles = new ArrayList<Schema>();

private SimpleFeatureCollection delegate;

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

this.typeMappingProfiles.add(XS.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();
}

/**
* Look in the {@link #typeMappingProfiles} for the official AttributeType for the provided java class.
*
* @param binding Java class being represented
* @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
public int size() {
//JD: this is a lie, since we skip over features without the attribute
return delegate.size();
}

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

class PropertyValueIterator implements SimpleFeatureIterator {
SimpleFeatureIterator it;

SimpleFeature next;

SimpleFeatureBuilder builder;

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

class PropertyValueIterator implements Iterator {

FeatureIterator it;
Feature next;

PropertyValueIterator(FeatureIterator it) {
this.it = it;
}

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

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

Object value = next.getAttribute(descriptor.getName());
String fid = next.getID();
//close the iterator
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;

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

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

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)) {
return ((ValueCollectionType)object).getMember().iterator().next();
}
else {
return WFSParsingUtils.FeatureCollectionType_getProperty((EObject)object, name);
}
return null;
//else {
// return WFSParsingUtils.FeatureCollectionType_getProperty((EObject)object, name);
//}
}

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

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

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

import java.util.NoSuchElementException;

import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.Feature;
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
*
*
*
*
* @source $URL$
*/
public class FilteringFeatureIterator implements SimpleFeatureIterator {
public class FilteringFeatureIterator<F extends Feature> implements FeatureIterator<F> {

/**
* delegate iterator
*/
protected SimpleFeatureIterator delegate;
protected FeatureIterator<F> delegate;
/**
* The Filter
*/
protected Filter filter;
/**
* 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.filter = filter;
}
Expand All @@ -59,7 +56,7 @@ public boolean hasNext() {
}

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

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

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

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() {
return new FilteringFeatureIterator( collection.features(), filter());
return new FilteringSimpleFeatureIterator( collection.features(), filter());
}

public int size() {
Expand Down

0 comments on commit 11d582c

Please sign in to comment.