Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 * Author: Matthew Perry 
7
 * '$Date: 2011-01-21 15:08:31 -0800 (Fri, 21 Jan 2011) $'
8
 * '$Revision: 5829 $'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24

    
25
package edu.ucsb.nceas.metacat.spatial;
26

    
27
import org.geotools.data.shapefile.ShapefileDataStore;
28
import org.geotools.data.FeatureStore;
29
import org.geotools.data.FeatureSource;
30
import org.geotools.data.DefaultTransaction;
31
import org.geotools.data.Transaction;
32
import org.geotools.filter.Filter;
33
import org.geotools.filter.AbstractFilter;
34
import org.geotools.filter.Expression;
35
import org.geotools.filter.CompareFilter;
36
import org.geotools.filter.GeometryFilter;
37
import org.geotools.filter.FilterFactory;
38
import org.geotools.filter.FilterFactoryFinder;
39
import org.geotools.filter.IllegalFilterException;
40
import org.geotools.feature.FeatureCollection;
41
import org.geotools.feature.FeatureCollections;
42
import org.opengis.feature.simple.SimpleFeature;
43
import org.opengis.feature.simple.SimpleFeatureType;
44

    
45
import com.vividsolutions.jts.geom.Envelope;
46
import com.vividsolutions.jts.geom.Geometry;
47
import com.vividsolutions.jts.geom.GeometryFactory;
48
import com.vividsolutions.jts.geom.Polygon;
49
import com.vividsolutions.jts.geom.Coordinate;
50

    
51
import java.io.File;
52
import java.net.URI;
53
import java.net.URL;
54
import java.net.MalformedURLException;
55
import java.sql.ResultSet;
56
import java.sql.PreparedStatement;
57
import java.util.Vector;
58
import java.util.Iterator; 
59
import java.io.IOException;
60

    
61
import org.apache.log4j.Logger;
62

    
63
import edu.ucsb.nceas.metacat.util.MetacatUtil;
64

    
65
/** 
66
 * Class to query the persistent spatial cache
67
 * and returns docids matching spatial constraints
68
 */
69
public class SpatialQuery {
70
 
71
  private static Logger log = Logger.getLogger(SpatialQuery.class.getName());
72
 
73
  /** 
74
   * empty constructor to initialize spatial query
75
   */
76
  public SpatialQuery() { }
77
 
78
  /**
79
   * Querys all features in the spatial cache 
80
   * and filters based on bouding coordinates.
81
   * Returns Vector of docids.
82
   *
83
   * @param w West bounding coordinate 
84
   * @param s South bounding coordinate 
85
   * @param e East bounding coordinate 
86
   * @param n North bounding coordinate 
87
   *
88
   */
89
  public Vector<String> filterByBbox( float w, float s, float e, float n ) {
90
      Vector<String> docids = new Vector<String>();
91
      SpatialFeatureSchema featureSchema = new SpatialFeatureSchema();
92
      
93
      ShapefileDataStore store = null;
94
      FeatureSource features = null;
95
      FeatureCollection collection = null;
96
      FilterFactory filterFactory = FilterFactoryFinder.createFilterFactory();
97

    
98
      try {
99
          // read the spatial cache (polygons)
100
          store = new ShapefileDataStore( (new File( featureSchema.polygonShpUri )).toURL() );
101
          features = store.getFeatureSource(store.getTypeNames()[0]);
102

    
103
          // Construct bounding box
104
          Envelope envelope = new Envelope( w, e, s, n ); 
105
          Expression bbox = filterFactory.createBBoxExpression( envelope );
106

    
107
          // Construct the bbox as an actual geometry
108
          Coordinate[] linestringCoordinates = new Coordinate[5];
109
          linestringCoordinates[0] = new Coordinate( w, s );
110
          linestringCoordinates[1] = new Coordinate( w, n );
111
          linestringCoordinates[2] = new Coordinate( e, n );
112
          linestringCoordinates[3] = new Coordinate( e, s );
113
          linestringCoordinates[4] = new Coordinate( w, s );
114

    
115
          GeometryFactory geomFac = new GeometryFactory();
116
          Polygon bboxGeom = geomFac.createPolygon( geomFac.createLinearRing(linestringCoordinates), null);
117

    
118
          // Set up geometry filter based on bbox
119
          SimpleFeatureType featureType = store.getSchema( store.getTypeNames()[0] );
120
          Expression geometry = filterFactory.createAttributeExpression( featureType.getGeometryDescriptor().getName().toString());
121
          GeometryFilter bboxFilter = filterFactory.createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
122
          bboxFilter.addLeftGeometry( geometry );
123
          bboxFilter.addRightGeometry( bbox );
124

    
125
          // Iterate through the filtered feature collection
126
          // and add matches to the docid Vector
127
          collection = features.getFeatures(bboxFilter);
128
          Iterator iterator = collection.iterator();
129
          try {
130
              for( Iterator i=collection.iterator(); i.hasNext(); ) {
131
                  SimpleFeature feature = (SimpleFeature) i.next();
132

    
133
                  Geometry geom = (Geometry)feature.getAttribute(0);
134
                  if ( geom.within( bboxGeom ) ) {
135
                      // assumes docid is attribute number 1 
136
                      // in a zero-based index of dbf columns
137
                      docids.add( (String) feature.getAttribute(1) );
138
                  }
139
              }
140
          } finally {
141
              collection.close( iterator );
142
          }
143
         
144
          /*
145
           * Also query the point cache since there may be point-only documents
146
           * Filter by the bbox AND check against docids Vector so that
147
           * docids already in the Vector don't get duplicated.
148
           */ 
149
          // read the spatial cache (points)
150
          store = new ShapefileDataStore( (new File( featureSchema.pointShpUri )).toURL() );
151
          features = store.getFeatureSource(store.getTypeNames()[0]);
152

    
153
          // Set up geometry filter based on bbox
154
          featureType = store.getSchema( store.getTypeNames()[0] );
155
          geometry = filterFactory.createAttributeExpression( featureType.getGeometryDescriptor().getName().toString()  );
156
          bboxFilter = filterFactory.createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
157
          bboxFilter.addLeftGeometry( geometry );
158
          bboxFilter.addRightGeometry( bbox );
159

    
160
          // Iterate through the filtered feature collection
161
          // and add matches to the docid Vector IF
162
          // they aren't already present
163
          collection = features.getFeatures(bboxFilter);
164
          iterator = collection.iterator();
165
          String docid = null;
166
          try {
167
              for( Iterator i=collection.iterator(); i.hasNext(); ) {
168
                  SimpleFeature feature = (SimpleFeature) i.next();
169
                  Geometry geom = (Geometry)feature.getAttribute(0);
170
                  if ( geom.intersects( bboxGeom ) ) { 
171
                      // assumes docid is attribute number 1 
172
                      // in a zero-based index of dbf columns
173
                      docid = (String) feature.getAttribute(1);
174
                      if( !docids.contains( docid ) ) {
175
                          docids.add( docid );
176
                      }
177
                  }
178
              }
179
          } finally {
180
              collection.close( iterator );
181
          }
182

    
183
      } catch (MalformedURLException ex) {
184
          ex.printStackTrace();
185
      } catch (IOException ex) {
186
          ex.printStackTrace();
187
      } catch (IllegalFilterException ex) {
188
          ex.printStackTrace();
189
      }
190

    
191
      return docids;
192

    
193
  }
194

    
195
}
(6-6/8)