Package org.geotools.caching.grid.featurecache

Source Code of org.geotools.caching.grid.featurecache.StreamingGridFeatureCache

package org.geotools.caching.grid.featurecache;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;

import org.geotools.caching.CacheOversizedException;
import org.geotools.caching.featurecache.FeatureCacheException;
import org.geotools.caching.grid.featurecache.readers.GridCachingFeatureCollection;
import org.geotools.caching.grid.spatialindex.NodeLockInvalidatingVisitor;
import org.geotools.caching.spatialindex.NodeIdentifier;
import org.geotools.caching.spatialindex.Storage;
import org.geotools.caching.util.BBoxFilterSplitter;
import org.geotools.caching.util.CacheUtil;
import org.geotools.data.DefaultQuery;
import org.geotools.data.Query;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.store.EmptyFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.filter.Filter;
import org.opengis.filter.spatial.BBOX;

import com.vividsolutions.jts.geom.Envelope;

/**
* Implementation of a GridFeatureCache that uses
* streaming feature collections.  Feature are streamed out of the cache
* and the feature source only when requested.  Features streams out of the
* feature source are cached as they are read.
*
* <p>This is a read only implementation; you cannot add
* features to this cache.</p>
* <p>This implementation of a feature cache locks the cache at the node level
* not the entire cache.  So as long as you are accessing different nodes you should
* be able to write to and read from the cache at the same time.
* </p>
* <p>Only supports SimpleFeatureType & SimpleFeature</p>
*
* @author Emily
* @since 1.2.0
*
*
*
*
* @source $URL$
*/
public class StreamingGridFeatureCache extends GridFeatureCache {

   
    public StreamingGridFeatureCache(SimpleFeatureSource fs, int indexcapacity, int capacity, Storage storethrows FeatureCacheException {
    super(fs, indexcapacity, capacity, store);
  }
   
  public StreamingGridFeatureCache(SimpleFeatureSource fs, ReferencedEnvelope env, int indexcapacity, int capacity, Storage store){
    super(fs, env, indexcapacity, capacity, store);
  }

 
  /**
   * Gets all feature within a given envelope.
   */
  @Override
    public SimpleFeatureCollection get(Envelope e) throws IOException{
    Filter f = ff.bbox(getSchema().getGeometryDescriptor().getLocalName(), e.getMinX(), e.getMinY(), e.getMaxX(), e.getMaxY(), getSchema().getCoordinateReferenceSystem().toString());   
    return getFeatures(f);
  }
 
  /**
   * Gets all features that match a query.
   *
   * <p>Currently the query handle is not supported.</p>
   */
  @Override
    public SimpleFeatureCollection getFeatures(Query query) throws IOException{
    //setup types
    if (query.getTypeName() == null){
      query = new DefaultQuery(query);
      ((DefaultQuery)query).setTypeName(this.getSchema().getTypeName());
    }else if (!query.getTypeName().equals(this.getSchema().getTypeName())){
      //types do not match
      return new EmptyFeatureCollection(this.getSchema());
    }

    Filter[] filters = splitFilter(query.getFilter());
    Filter envFilter = filters[0];
    //Filter postFilter = filters[1];
       
    if (envFilter.equals(Filter.EXCLUDE)){
      //nothing to get
      return new EmptyFeatureCollection(this.getSchema());
    }else if (envFilter.equals(Filter.INCLUDE)){
      //lets create a new bbox filter out of the bounds
      envFilter = createFilterFromBounds();
      return new GridCachingFeatureCollection((BBOX)envFilter, query, this, this.fs, true);
    }else if (envFilter instanceof BBOX){
      return new GridCachingFeatureCollection((BBOX)envFilter, query, this, this.fs, true);
    }else{
      throw new UnsupportedOperationException("Invalid filter created.");
    }
  }
 
  /**
   * Get all features that match given filter.
   */
  @Override
    public SimpleFeatureCollection getFeatures(Filter filter) throws IOException{
     
    Filter[] filters = splitFilter(filter);
    Filter envFilter = filters[0];
       
    if (envFilter.equals(Filter.EXCLUDE)){
            //nothing to get
            return new EmptyFeatureCollection(this.getSchema());
        }else if (envFilter.equals(Filter.INCLUDE)) {
          //get bounds of data
          envFilter = createFilterFromBounds();
      return generateFeatureCollection((BBOX)envFilter, filter);
        } else if (envFilter instanceof BBOX){  
          SimpleFeatureCollection fc = generateFeatureCollection((BBOX)envFilter, filter);
          return fc;
        }else{
          throw new UnsupportedOperationException("Invalid filter created.");
        }
  }
 
  /**
   * Creates a bbox filter from the data bounds
   * @return
   * @throws IOException
   */
  private BBOX createFilterFromBounds() throws IOException{
    Envelope env = this.getBounds();
    BBOX myfilter = ff.bbox(getSchema().getGeometryDescriptor().getLocalName(), env.getMinX(), env.getMinY(), env.getMaxX(), env.getMaxY(), getSchema().getCoordinateReferenceSystem().toString());
        return myfilter;
  }
 
  /**
   * Creates a streaming feature collection
   *
   * @param envFilter
   * @param postFilter
   * @return
   */
  private SimpleFeatureCollection generateFeatureCollection(BBOX envFilter, Filter postFilter){
    GridCachingFeatureCollection collection = new GridCachingFeatureCollection(envFilter, postFilter, this, this.fs, true);
    return collection;
  }
 
  /**
   * Creates a streaming feature collection
   *
   * @param envFilter
   * @param postFilter
   * @return
   */
  private SimpleFeatureCollection generateFeatureCollection(Envelope env){
    GridCachingFeatureCollection collection = new GridCachingFeatureCollection(env, this);
    return collection;
  }
   
  /**
   * Splits the filter into two parts; the "bounds" part which
   * will be used to get features from the cache; the filter part which
   * will be applied after to ensure the feature meets the entire
   * filter needs.
   *
   *
   * @param filter
   */
  private Filter[] splitFilter(Filter filter){
    BBoxFilterSplitter splitter = new BBoxFilterSplitter();
        filter.accept(splitter, null);

        Filter spatial_restrictions = splitter.getFilterPre();
        Filter other_restrictions = splitter.getFilterPost();

        return new Filter[]{spatial_restrictions, other_restrictions};
       
  }
 
  /**
   * Returns all features in the cache that match the given envelope.
   */
  public SimpleFeatureCollection peek(Envelope e) {
         return generateFeatureCollection(e);
  }
 

  /**
   * Unsupported.
   */
  public void put(FeatureCollection fc, Envelope e) throws CacheOversizedException {
    throw new UnsupportedOperationException("Streaming feature cache does not put entire feature collections.");
  }

  /**
   * Unsupported.
   */
  public void put(FeatureCollection fc) throws CacheOversizedException {
    throw new UnsupportedOperationException("Streaming feature cache does not put entire feature collections.");
  }
 
  /**
   * Removes all nodes from the cache that match the given envelope.
   */
  public void remove(Envelope e) {
    NodeLockInvalidatingVisitor v = new NodeLockInvalidatingVisitor(this.tracker);
    try {
      if (e == null) {
        e = getBounds();// no envelope specified so assume everything
      }
      this.tracker.intersectionQuery(CacheUtil.convert(e), v);      // invalidates nodes
      this.tracker.getStatistics().addToDataCounter(-v.getDataCount());    //update stats to remove all data
    } catch (IOException ex) {
      logger.log(Level.SEVERE, "Error removing elements from cache.", ex);
    }
    this.tracker.flush();
  }
 
   /**
     * Registers a collection of nodes as valid.
     * This function assumes that the necessary nodes are locked
     * so that synchronization problems don't occur.
     * @param nodes
     */
    public void register( Collection<NodeIdentifier> nodes ) {
        // we don't want to track access while we register; this will ensure that just because a
        // node touches another node it
        // isn't considered an access; it might be better to improve the way containment query is
        // done.
        boolean recordaccess = this.tracker.getDoRecordAccess();
        try {
            this.tracker.setDoRecordAccess(false);
            for( Iterator<NodeIdentifier> iterator = nodes.iterator(); iterator.hasNext(); ) {
                NodeIdentifier nodeIdentifier = (NodeIdentifier) iterator.next();
                nodeIdentifier.setValid(true);
            }
        } finally {
            this.tracker.setDoRecordAccess(recordaccess);
        }
    }
   
    /**
     * Un-registers a collection of nodes.
     * This function assumes that the necessary nodes are locked
     * so that synchronization problems don't occur.
     *
     * @param nodes
     */
    @Override
    public void unregister( Collection<NodeIdentifier> nodes ) {
        // we don't want to track access while we register; this will ensure that just because a
        // node touches another node it
        // isn't considered an access; it might be better to improve the way containment query is
        // done.
        boolean recordaccess = this.tracker.getDoRecordAccess();
        try {
            this.tracker.setDoRecordAccess(false);
            for( Iterator<NodeIdentifier> iterator = nodes.iterator(); iterator.hasNext(); ) {
                NodeIdentifier nodeIdentifier = (NodeIdentifier) iterator.next();
                nodeIdentifier.setValid(false);
            }
        } finally {
            this.tracker.setDoRecordAccess(recordaccess);
        }
    }
}
TOP

Related Classes of org.geotools.caching.grid.featurecache.StreamingGridFeatureCache

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.