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.
Original file line number Diff line number Diff line change
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;
}
}

}
Original file line number Diff line number Diff line change
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);
//}
}

}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
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
Loading

0 comments on commit 11d582c

Please sign in to comment.