Package org.geoserver.wps.gs

Source Code of org.geoserver.wps.gs.IntersectionFeatureCollection$IntersectedFeatureIterator

package org.geoserver.wps.gs;

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

import org.geoserver.wps.WPSException;
import org.geoserver.wps.jts.DescribeParameter;
import org.geoserver.wps.jts.DescribeProcess;
import org.geoserver.wps.jts.DescribeResult;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.AttributeTypeBuilder;
import org.geotools.feature.collection.DecoratingSimpleFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.feature.type.GeometryTypeImpl;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Polygon;

/**
* A process providing the intersection between two feature collections
*
* @author Gianni Barrotta - Sinergis
* @author Andrea Di Nora - Sinergis
* @author Pietro Arena - Sinergis
*
*/
@DescribeProcess(title = "intersection", description = "Returns the intersections between two feature " +
    "collections adding the attributes from both of them")
public class IntersectionFeatureCollection implements GeoServerProcess {
    @DescribeResult(description = "feature collection containg the intersections between the two feature " +
        "collections and the attributes from both of them")
    public SimpleFeatureCollection execute(
            @DescribeParameter(name = "first feature collection", description = "First feature collection") SimpleFeatureCollection firstFeatures,
            @DescribeParameter(name = "second feature collection", description = "Second feature collection") SimpleFeatureCollection secondFeatures) {
        if (!(firstFeatures.features().next().getDefaultGeometry() instanceof MultiPolygon)
                && !(firstFeatures.features().next().getDefaultGeometry() instanceof Polygon)
                && !(firstFeatures.features().next().getDefaultGeometry() instanceof MultiLineString)
                && !(firstFeatures.features().next().getDefaultGeometry() instanceof LineString)) {
            throw new WPSException("First feature collection must be polygonal or linear");
        } else {
            return new IntersectedFeatureCollection(firstFeatures, secondFeatures);
        }
    }

    /**
     * Delegate that will compute the intersections on the go
     */
    static class IntersectedFeatureCollection extends DecoratingSimpleFeatureCollection {

        SimpleFeatureCollection features;

        public IntersectedFeatureCollection(SimpleFeatureCollection delegate,
                SimpleFeatureCollection features) {
            super(delegate);
            this.features = features;

        }

        @Override
        public SimpleFeatureIterator features() {
            return new IntersectedFeatureIterator(delegate.features(), delegate, features, delegate
                    .getSchema(), features.getSchema());
        }

        @Override
        public Iterator<SimpleFeature> iterator() {
            return new WrappingIterator(features());
        }

        @Override
        public void close(Iterator<SimpleFeature> close) {
            if (close instanceof WrappingIterator) {
                ((WrappingIterator) close).close();
            }
        }
    }

    /**
     * Builds the intersections while streaming
     */
    static class IntersectedFeatureIterator implements SimpleFeatureIterator {
        SimpleFeatureIterator delegate;

        SimpleFeatureCollection firstFeatures;

        SimpleFeatureCollection secondFeatures;

        SimpleFeatureCollection subFeatureCollection;

        SimpleFeatureBuilder fb;

        SimpleFeature next;

        SimpleFeature first;

        Integer iterationIndex = 0;

        boolean complete = true;

        boolean added = false;

        SimpleFeatureCollection intersectedGeometries;

        SimpleFeatureIterator iterator;

        String dataGeomName;

        public IntersectedFeatureIterator(SimpleFeatureIterator delegate,
                SimpleFeatureCollection firstFeatures, SimpleFeatureCollection secondFeatures,
                SimpleFeatureType firstFeatureCollectionSchema,
                SimpleFeatureType secondFeatureCollectionSchema) {
            this.delegate = delegate;
            this.firstFeatures = firstFeatures;
            this.secondFeatures = secondFeatures;
            SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
            GeometryDescriptor geometryDescriptor = firstFeatureCollectionSchema
                    .getGeometryDescriptor();
            // gather the attributes from the first feature collection
            for (AttributeDescriptor descriptor : firstFeatureCollectionSchema
                    .getAttributeDescriptors()) {
                if (!(descriptor.getType() instanceof GeometryTypeImpl)
                        || (!geometryDescriptor.getName().equals(descriptor.getName()))) {
                    AttributeTypeBuilder builder = new AttributeTypeBuilder();
                    builder.setName(this.firstFeatures.features().next().getFeatureType().getName()
                            .getLocalPart()
                            + "_" + descriptor.getName());
                    builder.setNillable(descriptor.isNillable());
                    builder.setBinding(descriptor.getType().getBinding());
                    builder.setMinOccurs(descriptor.getMinOccurs());
                    builder.setMaxOccurs(descriptor.getMaxOccurs());
                    builder.setDefaultValue(descriptor.getDefaultValue());
                    builder.setCRS(this.firstFeatures.features().next().getFeatureType()
                            .getCoordinateReferenceSystem());
                    AttributeDescriptor intersectionDescriptor = builder.buildDescriptor(
                            this.firstFeatures.features().next().getFeatureType().getName()
                                    .getLocalPart()
                                    + "_" + descriptor.getName(), descriptor.getType());
                    tb.add(intersectionDescriptor);
                    tb.addBinding(descriptor.getType());
                } else {
                    tb.add(descriptor);
                }

            }
            // gather the attributes from the second feature collection
            geometryDescriptor = secondFeatureCollectionSchema.getGeometryDescriptor();
            for (AttributeDescriptor descriptor : secondFeatureCollectionSchema
                    .getAttributeDescriptors()) {
                if (!(descriptor.getType() instanceof GeometryTypeImpl)
                        || (!geometryDescriptor.getName().equals(descriptor.getName()))) {
                    AttributeTypeBuilder builder = new AttributeTypeBuilder();
                    builder.setName(this.secondFeatures.features().next().getFeatureType()
                            .getName().getLocalPart()
                            + "_" + descriptor.getName());
                    builder.setNillable(descriptor.isNillable());
                    builder.setBinding(descriptor.getType().getBinding());
                    builder.setMinOccurs(descriptor.getMinOccurs());
                    builder.setMaxOccurs(descriptor.getMaxOccurs());
                    builder.setDefaultValue(descriptor.getDefaultValue());
                    builder.setCRS(this.secondFeatures.features().next().getFeatureType()
                            .getCoordinateReferenceSystem());
                    builder.setNamespaceURI(this.secondFeatures.features().next().getFeatureType()
                            .getName().getNamespaceURI());
                    builder.setDefaultValue(descriptor.getDefaultValue());
                    AttributeDescriptor intersectionDescriptor = builder.buildDescriptor(
                            this.secondFeatures.features().next().getFeatureType().getName()
                                    .getLocalPart()
                                    + "_" + descriptor.getName(), descriptor.getType());
                    tb.addBinding(descriptor.getType());
                    tb.add(intersectionDescriptor);
                }
            }
            tb.setDescription(firstFeatureCollectionSchema.getDescription());
            tb.setCRS(firstFeatureCollectionSchema.getCoordinateReferenceSystem());
            tb.setAbstract(firstFeatureCollectionSchema.isAbstract());
            tb.setSuperType((SimpleFeatureType) firstFeatureCollectionSchema.getSuper());
            tb.setName(firstFeatureCollectionSchema.getName());

            this.fb = new SimpleFeatureBuilder(tb.buildFeatureType());

            subFeatureCollection = this.secondFeatures;

            this.dataGeomName = this.firstFeatures.getSchema().getGeometryDescriptor()
                    .getLocalName();
        }

        public void close() {
            delegate.close();
        }

        public boolean hasNext() {
            while ((next == null && delegate.hasNext()) || (next == null && added)) {
                if (complete) {
                    first = delegate.next();
                    intersectedGeometries = null;
                }
                for (Object attribute : first.getAttributes()) {
                    if (attribute instanceof Geometry
                            && attribute.equals(first.getDefaultGeometry())) {
                        Geometry currentGeom = (Geometry) attribute;
                        if (intersectedGeometries == null && !added) {
                            intersectedGeometries = filteredCollection(currentGeom,
                                    subFeatureCollection);
                            iterator = intersectedGeometries.features();
                        }
                        try {
                            while (iterator.hasNext()) {
                                added = false;
                                SimpleFeature second = iterator.next();
                                if (currentGeom.getEnvelope().intersects(
                                        ((Geometry) second.getDefaultGeometry()))) {
                                    attribute = currentGeom.intersection((Geometry) second
                                            .getDefaultGeometry());
                                    if (((Geometry) attribute).getNumGeometries() > 0) {
                                        fb.add(attribute);

                                        // add first feature's attributes
                                        for (Object firstAttribute : first.getAttributes()) {
                                            if (!(firstAttribute instanceof Geometry)) {
                                                fb.add(firstAttribute);
                                            }
                                        }
                                        // add second feature's attributes
                                        for (Object secondAttribute : second.getAttributes()) {
                                            if (!(secondAttribute instanceof Geometry)) {
                                                fb.add(secondAttribute);
                                            }
                                        }
                                        next = fb.buildFeature(iterationIndex.toString());
                                        if (iterator.hasNext()) {
                                            complete = false;
                                            added = true;
                                            iterationIndex++;
                                            return next != null;
                                        }
                                        iterationIndex++;
                                    }
                                }
                                complete = false;
                            }
                            complete = true;
                        } finally {
                            if (!added) {
                                iterator.close();
                            }
                        }
                    }
                }
            }
            return next != null;
        }

        public SimpleFeature next() throws NoSuchElementException {
            if (!hasNext()) {
                throw new NoSuchElementException("hasNext() returned false!");
            }

            SimpleFeature result = next;
            next = null;
            return result;
        }

        private SimpleFeatureCollection filteredCollection(Geometry currentGeom,
                SimpleFeatureCollection subFeatureCollection) {
            FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
            Filter intersectFilter = ff.intersects(ff.property(dataGeomName), ff
                    .literal(currentGeom));
            SimpleFeatureCollection subFeatureCollectionIntersection = this.subFeatureCollection
                    .subCollection(intersectFilter);
            if (subFeatureCollectionIntersection.size() == 0) {
                subFeatureCollectionIntersection = subFeatureCollection;
            }
            return subFeatureCollectionIntersection;
        }

    }
}
TOP

Related Classes of org.geoserver.wps.gs.IntersectionFeatureCollection$IntersectedFeatureIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.