All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotools.data.collection.CollectionFeatureSource Maven / Gradle / Ivy

Go to download

The main module contains the GeoTools public interfaces that are used by other GeoTools modules (and GeoTools applications). Where possible we make use industry standard terms as provided by OGC and ISO standards. The formal GeoTools public api consists of gt-metadata, jts and the gt-main module. The main module contains the default implementations that are available provided to other GeoTools modules using our factory system. Factories are obtained from an appropriate FactoryFinder, giving applications a chance configure the factory used using the Factory Hints facilities. FilterFactory ff = CommonFactoryFinder.getFilterFactory(); Expression expr = ff.add( expression1, expression2 ); If you find yourself using implementation specific classes chances are you doing it wrong: Expression expr = new AddImpl( expression1, expressiom2 );

There is a newer version: 24.2-oss84-1
Show newest version
/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2019, 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.data.collection;

import java.awt.RenderingHints.Key;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.geotools.data.DataAccess;
import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureListener;
import org.geotools.data.Query;
import org.geotools.data.QueryCapabilities;
import org.geotools.data.ResourceInfo;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.store.EmptyFeatureCollection;
import org.geotools.data.store.ReTypingFeatureCollection;
import org.geotools.data.store.ReprojectingFeatureCollection;
import org.geotools.feature.collection.DecoratingSimpleFeatureCollection;
import org.geotools.feature.collection.FilteringSimpleFeatureCollection;
import org.geotools.feature.collection.MaxSimpleFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;

/**
 * This is a "port" of ContentFeatureSource to work with an iterator.
 *
 * 

To use this class please "wrap" CollectionFeatureSource around your choice of * FeatureCollection. * *

 * SimpleFeatureCollection collection = new ListFeatureCollection(schema);
 * collection.add(feature1);
 * collection.add(feature2);
 * FeatureSource source = new CollectionFeatureSource(collection);
 * 
* *

Note to implementors: If you are performing "real I/O" please use ContentFeatureSource as it * provides support for IOException. * * @author Jody */ public class CollectionFeatureSource implements SimpleFeatureSource { protected SimpleFeatureCollection collection; /** observers */ protected List listeners = null; private QueryCapabilities capabilities; private Set hints; public CollectionFeatureSource(SimpleFeatureCollection collection) { this.collection = collection; } public SimpleFeatureType getSchema() { return collection.getSchema(); } public synchronized void addFeatureListener(FeatureListener listener) { if (listeners == null) { listeners = Collections.synchronizedList(new ArrayList()); } listeners.add(listener); } public synchronized void removeFeatureListener(FeatureListener listener) { if (listeners == null) { return; } listeners.remove(listener); } public ReferencedEnvelope getBounds() throws IOException { return collection.getBounds(); } public ReferencedEnvelope getBounds(Query query) throws IOException { return getFeatures(query).getBounds(); } public int getCount(Query query) throws IOException { return getFeatures(query).size(); } public DataAccess getDataStore() { throw new UnsupportedOperationException("CollectionFeatureSource is an inmemory wrapper"); } public ResourceInfo getInfo() { throw new UnsupportedOperationException("CollectionFeatureSource is an inmemory wrapper"); } public Name getName() { return collection.getSchema().getName(); } public synchronized QueryCapabilities getQueryCapabilities() { if (capabilities == null) { capabilities = new QueryCapabilities() { public boolean isOffsetSupported() { return true; } public boolean isReliableFIDSupported() { return true; } public boolean supportsSorting( org.opengis.filter.sort.SortBy[] sortAttributes) { return true; } }; } return capabilities; } public synchronized Set getSupportedHints() { if (hints == null) { Set supports = new HashSet(); // supports.add( Hints.FEATURE_DETACHED ); hints = Collections.unmodifiableSet(supports); } return hints; } @Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append("CollectionFeatureSource:"); buf.append(collection); return buf.toString(); } // // GET FEATURES // This forms the heart of the CollectionFeatureSource implementation // Use: DataUtilities.mixQueries(this.query, query, "subCollection" ) as needed // public SimpleFeatureCollection getFeatures() throws IOException { return getFeatures(Query.ALL); } public SimpleFeatureCollection getFeatures(Filter filter) { Query query = new Query(getSchema().getTypeName(), filter); return getFeatures(query); } public SimpleFeatureCollection getFeatures(Query query) { query = DataUtilities.resolvePropertyNames(query, getSchema()); final int offset = query.getStartIndex() != null ? query.getStartIndex() : 0; if (offset > 0 && query.getSortBy() == null) { if (!getQueryCapabilities().supportsSorting(query.getSortBy())) { throw new IllegalStateException( "Feature source does not support this sorting " + "so there is no way a stable paging (offset/limit) can be performed"); } Query copy = new Query(query); copy.setSortBy(new SortBy[] {SortBy.NATURAL_ORDER}); query = copy; } SimpleFeatureCollection features = collection; // step one: filter if (query.getFilter() != null && query.getFilter().equals(Filter.EXCLUDE)) { return new EmptyFeatureCollection(getSchema()); } if (query.getFilter() != null && query.getFilter() != Filter.INCLUDE) { features = new FilteringSimpleFeatureCollection(features, query.getFilter()); } // step two: reproject if (query.getCoordinateSystemReproject() != null) { features = new ReprojectingFeatureCollection( features, query.getCoordinateSystemReproject()); } // step two sort! (note this makes a sorted copy) if (query.getSortBy() != null && query.getSortBy().length != 0) { SimpleFeature array[] = features.toArray(new SimpleFeature[features.size()]); // Arrays sort is stable (not resorting equal elements) for (SortBy sortBy : query.getSortBy()) { Comparator comparator = DataUtilities.sortComparator(sortBy); Arrays.sort(array, comparator); } ArrayList list = new ArrayList(Arrays.asList(array)); features = new ListFeatureCollection(getSchema(), list); } // step three skip to start and return max number of fetaures if (offset > 0 || !query.isMaxFeaturesUnlimited()) { long max = Long.MAX_VALUE; if (!query.isMaxFeaturesUnlimited()) { max = query.getMaxFeatures(); } features = new MaxSimpleFeatureCollection(features, offset, max); } // step four - retyping // (It would be nice to do this earlier so as to not have all the baggage // of unneeded attributes) if (query.getPropertyNames() != Query.ALL_NAMES) { // rebuild the type and wrap the reader SimpleFeatureType schema = features.getSchema(); SimpleFeatureType target = SimpleFeatureTypeBuilder.retype(schema, query.getPropertyNames()); // do an equals check because we may have needlessly retyped (that is, // the subclass might be able to only partially retype) if (!target.equals(schema)) { features = new ReTypingFeatureCollection(features, target); } } // Wrap up the results in a method that allows subCollection return new SubCollection(query, features); } /** * SubCollection for CollectionFeatureSource. * *

Will route any calls refining the feature collection back to CollectionFeatureSource. This * is based on the success of ContentFeatureCollection. * * @author Jody */ protected class SubCollection extends DecoratingSimpleFeatureCollection { private Query query; protected SubCollection(Query query, SimpleFeatureCollection features) { super(features); this.query = query; } public SimpleFeatureCollection subCollection(Filter filter) { Query q = new Query(getSchema().getTypeName(), filter); Query subQuery = DataUtilities.mixQueries(query, q, q.getHandle()); return CollectionFeatureSource.this.getFeatures(subQuery); } @Override public SimpleFeatureCollection sort(SortBy order) { Query q = new Query(getSchema().getTypeName()); q.setSortBy(new SortBy[] {order}); Query subQuery = DataUtilities.mixQueries(query, q, q.getHandle()); return CollectionFeatureSource.this.getFeatures(subQuery); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy