Project

General

Profile

1 3044 perry
/**
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$'
8
 * '$Revision$'
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.feature.FeatureType;
28
import org.geotools.data.shapefile.ShapefileDataStore;
29
import org.geotools.data.FeatureStore;
30
import org.geotools.data.FeatureSource;
31
import org.geotools.data.DefaultTransaction;
32
import org.geotools.data.Transaction;
33
import org.geotools.feature.Feature;
34
import org.geotools.filter.Filter;
35
import org.geotools.filter.AbstractFilter;
36
import org.geotools.filter.Expression;
37
import org.geotools.filter.CompareFilter;
38
import org.geotools.filter.GeometryFilter;
39
import org.geotools.filter.FilterFactory;
40
import org.geotools.filter.FilterFactoryFinder;
41
import org.geotools.filter.IllegalFilterException;
42
import org.geotools.feature.FeatureCollection;
43
import org.geotools.feature.FeatureCollections;
44
import com.vividsolutions.jts.geom.Envelope;
45 3048 perry
import com.vividsolutions.jts.geom.Geometry;
46
import com.vividsolutions.jts.geom.GeometryFactory;
47
import com.vividsolutions.jts.geom.Polygon;
48
import com.vividsolutions.jts.geom.Coordinate;
49 3044 perry
50
import java.io.File;
51
import java.net.URI;
52
import java.net.URL;
53
import java.net.MalformedURLException;
54
import java.sql.ResultSet;
55
import java.sql.PreparedStatement;
56
import java.util.Vector;
57
import java.util.Iterator;
58
import java.io.IOException;
59
60
import org.apache.log4j.Logger;
61
62 4699 daigle
import edu.ucsb.nceas.metacat.util.MetacatUtil;
63 3044 perry
64
/**
65
 * Class to query the persistent spatial cache
66
 * and returns docids matching spatial constraints
67
 */
68
public class SpatialQuery {
69
70
  private static Logger log = Logger.getLogger(SpatialQuery.class.getName());
71
72
  /**
73
   * empty constructor to initialize spatial query
74
   */
75
  public SpatialQuery() { }
76
77
  /**
78
   * Querys all features in the spatial cache
79
   * and filters based on bouding coordinates.
80
   * Returns Vector of docids.
81
   *
82
   * @param w West bounding coordinate
83
   * @param s South bounding coordinate
84
   * @param e East bounding coordinate
85
   * @param n North bounding coordinate
86
   *
87
   */
88 4080 daigle
  public Vector<String> filterByBbox( float w, float s, float e, float n ) {
89
      Vector<String> docids = new Vector<String>();
90 3044 perry
      SpatialFeatureSchema featureSchema = new SpatialFeatureSchema();
91
92
      ShapefileDataStore store = null;
93
      FeatureSource features = null;
94
      FeatureCollection collection = null;
95
      FilterFactory filterFactory = FilterFactoryFinder.createFilterFactory();
96
97
      try {
98 3045 perry
          // read the spatial cache (polygons)
99 3044 perry
          store = new ShapefileDataStore( (new File( featureSchema.polygonShpUri )).toURL() );
100
          features = store.getFeatureSource(store.getTypeNames()[0]);
101
102 3045 perry
          // Construct bounding box
103 3044 perry
          Envelope envelope = new Envelope( w, e, s, n );
104
          Expression bbox = filterFactory.createBBoxExpression( envelope );
105
106 3048 perry
          // Construct the bbox as an actual geometry
107
          Coordinate[] linestringCoordinates = new Coordinate[5];
108
          linestringCoordinates[0] = new Coordinate( w, s );
109
          linestringCoordinates[1] = new Coordinate( w, n );
110
          linestringCoordinates[2] = new Coordinate( e, n );
111
          linestringCoordinates[3] = new Coordinate( e, s );
112
          linestringCoordinates[4] = new Coordinate( w, s );
113
114
          GeometryFactory geomFac = new GeometryFactory();
115
          Polygon bboxGeom = geomFac.createPolygon( geomFac.createLinearRing(linestringCoordinates), null);
116
117 3045 perry
          // Set up geometry filter based on bbox
118 3044 perry
          FeatureType featureType = store.getSchema( store.getTypeNames()[0] );
119
          Expression geometry = filterFactory.createAttributeExpression( featureType.getDefaultGeometry().getName()  );
120
          GeometryFilter bboxFilter = filterFactory.createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
121
          bboxFilter.addLeftGeometry( geometry );
122
          bboxFilter.addRightGeometry( bbox );
123
124 3045 perry
          // Iterate through the filtered feature collection
125
          // and add matches to the docid Vector
126 3044 perry
          collection = features.getFeatures(bboxFilter);
127
          Iterator iterator = collection.iterator();
128
          try {
129
              for( Iterator i=collection.iterator(); i.hasNext(); ) {
130
                  Feature feature = (Feature) i.next();
131 3048 perry
132
                  Geometry geom = (Geometry)feature.getAttribute(0);
133 3492 leinfelder
                  if ( geom.within( bboxGeom ) ) {
134 3048 perry
                      // assumes docid is attribute number 1
135
                      // in a zero-based index of dbf columns
136
                      docids.add( (String) feature.getAttribute(1) );
137
                  }
138 3044 perry
              }
139
          } finally {
140
              collection.close( iterator );
141
          }
142
143 3045 perry
          /*
144
           * Also query the point cache since there may be point-only documents
145
           * Filter by the bbox AND check against docids Vector so that
146
           * docids already in the Vector don't get duplicated.
147
           */
148
          // read the spatial cache (points)
149
          store = new ShapefileDataStore( (new File( featureSchema.pointShpUri )).toURL() );
150
          features = store.getFeatureSource(store.getTypeNames()[0]);
151 3044 perry
152 3045 perry
          // Set up geometry filter based on bbox
153
          featureType = store.getSchema( store.getTypeNames()[0] );
154
          geometry = filterFactory.createAttributeExpression( featureType.getDefaultGeometry().getName()  );
155
          bboxFilter = filterFactory.createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
156
          bboxFilter.addLeftGeometry( geometry );
157
          bboxFilter.addRightGeometry( bbox );
158 3044 perry
159 3045 perry
          // Iterate through the filtered feature collection
160
          // and add matches to the docid Vector IF
161
          // they aren't already present
162
          collection = features.getFeatures(bboxFilter);
163
          iterator = collection.iterator();
164
          String docid = null;
165
          try {
166
              for( Iterator i=collection.iterator(); i.hasNext(); ) {
167
                  Feature feature = (Feature) i.next();
168 3048 perry
                  Geometry geom = (Geometry)feature.getAttribute(0);
169
                  if ( geom.intersects( bboxGeom ) ) {
170
                      // assumes docid is attribute number 1
171
                      // in a zero-based index of dbf columns
172
                      docid = (String) feature.getAttribute(1);
173
                      if( !docids.contains( docid ) ) {
174
                          docids.add( docid );
175
                      }
176 3045 perry
                  }
177
              }
178
          } finally {
179
              collection.close( iterator );
180
          }
181
182
      } catch (MalformedURLException ex) {
183
          ex.printStackTrace();
184
      } catch (IOException ex) {
185
          ex.printStackTrace();
186
      } catch (IllegalFilterException ex) {
187
          ex.printStackTrace();
188
      }
189
190 3044 perry
      return docids;
191
192
  }
193
194
}