Package org.geotools.data.collection

Source Code of org.geotools.data.collection.SpatialIndexFeatureCollection

package org.geotools.data.collection;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.CollectionEvent;
import org.geotools.feature.CollectionListener;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.util.NullProgressListener;
import org.geotools.util.logging.Logging;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.util.ProgressListener;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.index.ItemVisitor;
import com.vividsolutions.jts.index.strtree.STRtree;

/**
* FeatureCollection used to stage information for display using a SpatialIndex.
* <p>
* Please note that this feature collection cannot be modified after the spatial index is created.
*
* @author Jody
*
*
* @source $URL$
*/
public class SpatialIndexFeatureCollection implements SimpleFeatureCollection {

    static Logger LOGGER = Logging.getLogger(SpatialIndexFeatureCollection.class);

    /** SpatialIndex holding the contents of the FeatureCollection */
    protected STRtree index;

    protected SimpleFeatureType schema;

    /** Listeners */
    protected List<CollectionListener> listeners = null;

    public SpatialIndexFeatureCollection() {
        this.index = new STRtree();
    }
   
    public SpatialIndexFeatureCollection(SimpleFeatureType schema) {
        this.index = new STRtree();
        this.schema = schema;
    }
   
    public SpatialIndexFeatureCollection(SimpleFeatureCollection copy ) throws IOException {
        this( copy.getSchema() );
        addAll( copy );
    }
   
    public synchronized void addListener(CollectionListener listener) throws NullPointerException {
        if (listeners == null) {
            listeners = Collections.synchronizedList(new ArrayList<CollectionListener>());
        }
        listeners.add(listener);
    }

    public synchronized void removeListener(CollectionListener listener)
            throws NullPointerException {
        if (listeners == null) {
            return;
        }
        listeners.remove(listener);
    }

    protected void fire(SimpleFeature[] features, int eventType) {
        if (listeners == null || listeners.isEmpty()) {
            return;
        }
        CollectionEvent event = new CollectionEvent(this, features, eventType);
        CollectionListener[] notify = (CollectionListener[]) listeners
                .toArray(new CollectionListener[listeners.size()]);
        for (CollectionListener listener : notify) {
            try {
                listener.collectionChanged(event);
            } catch (Throwable t) {
                LOGGER.log(Level.WARNING, "Problem encountered during notification of " + event, t);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public SimpleFeatureIterator features() {
        Envelope everything = new Envelope(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
                Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
       
        final List<SimpleFeature> list = (List<SimpleFeature>) index.query(everything);
        final Iterator<SimpleFeature> iterator = list.iterator();
        return new SimpleFeatureIterator() {
            public SimpleFeature next() throws NoSuchElementException {
                return iterator.next();
            }

            public boolean hasNext() {
                return iterator.hasNext();
            }

            public void close() {
            }
        };
    }

    public SimpleFeatureCollection sort(SortBy order) {
        throw new UnsupportedOperationException();
    }

    public SimpleFeatureCollection subCollection(Filter filter) {
        throw new UnsupportedOperationException();
    }

    public void accepts(final FeatureVisitor visitor, ProgressListener listener) throws IOException {
        Envelope everything = new Envelope(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
                Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
        final ProgressListener progress = listener != null ? listener : new NullProgressListener();
        progress.started();
        final float size = (float) size();
        final IOException problem[] = new IOException[1];
        index.query(everything, new ItemVisitor() {
            float count = 0f;

            public void visitItem(Object item) {
                SimpleFeature feature = null;
                try {
                    feature = (SimpleFeature) item;
                    visitor.visit(feature);
                } catch (Throwable t) {
                    progress.exceptionOccurred(t);
                    String fid = feature == null ? "feature" : feature.getIdentifier().toString();
                    problem[0] = new IOException("Problem visiting " + fid + ":" + t, t);
                } finally {
                    progress.progress(count / size);
                }
            }
        });
        if( problem[0] != null ){
            throw problem[0];
        }
        progress.complete();
    }

    public boolean add(SimpleFeature feature) {
        ReferencedEnvelope bounds = ReferencedEnvelope.reference(feature.getBounds());
        index.insert(bounds, feature);

        return false;
    }

    public boolean addAll(Collection<? extends SimpleFeature> collection) {
        for (SimpleFeature feature : collection) {
            try {
                ReferencedEnvelope bounds = ReferencedEnvelope.reference(feature.getBounds());
                index.insert(bounds, feature);
            } catch (Throwable t) {
            }
        }
        return false;
    }

    public boolean addAll(
            FeatureCollection<? extends SimpleFeatureType, ? extends SimpleFeature> collection) {
        FeatureIterator<? extends SimpleFeature> iter = collection.features();
        try {
            while (iter.hasNext()) {
                try {
                    SimpleFeature feature = iter.next();
                    ReferencedEnvelope bounds = ReferencedEnvelope.reference(feature.getBounds());
                    index.insert(bounds, feature);
                } catch (Throwable t) {
                }
            }
        } finally {
            iter.close();
        }
        return false;
    }

    public synchronized void clear() {
        index = null;
        index = new STRtree();
        listeners.clear();
        listeners = null;
    }

    public void close(FeatureIterator<SimpleFeature> close) {
    }

    public void close(Iterator<SimpleFeature> close) {
    }

    @SuppressWarnings("unchecked")
    public boolean contains(Object obj) {
        if (obj instanceof SimpleFeature) {
            SimpleFeature feature = (SimpleFeature) obj;
            ReferencedEnvelope bounds = ReferencedEnvelope.reference(feature.getBounds());
            for (Iterator<SimpleFeature> iter = (Iterator<SimpleFeature>) index.query(bounds); iter
                    .hasNext();) {
                SimpleFeature sample = iter.next();
                if (sample == feature) {
                    return true;
                }
            }

        }
        return false;
    }

    public boolean containsAll(Collection<?> collection) {
        boolean containsAll = true;
        for (Object obj : collection) {
            boolean contains = contains(obj);
            if (!contains) {
                containsAll = false;
                break;
            }
        }
        return containsAll;
    }

    public ReferencedEnvelope getBounds() {
        CoordinateReferenceSystem crs = schema.getCoordinateReferenceSystem();
        Envelope bounds = (Envelope) index.getRoot().getBounds();
        return new ReferencedEnvelope(bounds, crs);
    }

    public String getID() {
        return null;
    }

    public SimpleFeatureType getSchema() {
        return schema;
    }

    public boolean isEmpty() {
        return index.itemsTree().isEmpty();
    }

    @SuppressWarnings("unchecked")
    public Iterator<SimpleFeature> iterator() {
        Envelope everything = new Envelope(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
                Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
        final List<SimpleFeature> list = (List<SimpleFeature>) index.query(everything);
        return (Iterator<SimpleFeature> ) list.iterator();
    }

    public void purge() {
    }

    public boolean remove(Object o) {
        throw new UnsupportedOperationException("Cannot remove items from STRtree");
    }

    public boolean removeAll(Collection<?> c) {
        throw new UnsupportedOperationException("Cannot remove items from STRtree");
    }

    @SuppressWarnings("unchecked")
    public boolean retainAll(Collection<?> c) {
        throw new UnsupportedOperationException("Cannot remove items from STRtree");
    }

    /**
     * Will build the STRtree index if required.
     */
    public int size() {
        return index.size();
    }

    public Object[] toArray() {
        return toArray(new Object[size()]);
    }

    @SuppressWarnings("unchecked")
    public <O> O[] toArray(O[] array) {
        int size = size();
        if (array.length < size) {
            array = (O[]) java.lang.reflect.Array.newInstance(array.getClass().getComponentType(),
                    size);
        }
        Iterator<SimpleFeature> it = iterator();
        try {
            Object[] result = array;
            for (int i = 0; i < size; i++) {
                result[i] = it.next();
            }
            if (array.length > size) {
                array[size] = null;
            }
            return array;
        } finally {
            close(it);
        }
    }

}
TOP

Related Classes of org.geotools.data.collection.SpatialIndexFeatureCollection

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.