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: 2008-12-26 13:09:47 -0800 (Fri, 26 Dec 2008) $'
8
 * '$Revision: 4699 $'
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
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

    
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
import edu.ucsb.nceas.metacat.util.MetacatUtil;
63

    
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
  public Vector<String> filterByBbox( float w, float s, float e, float n ) {
89
      Vector<String> docids = new Vector<String>();
90
      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
          // read the spatial cache (polygons)
99
          store = new ShapefileDataStore( (new File( featureSchema.polygonShpUri )).toURL() );
100
          features = store.getFeatureSource(store.getTypeNames()[0]);
101

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

    
106
          // 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
          // Set up geometry filter based on bbox
118
          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
          // Iterate through the filtered feature collection
125
          // and add matches to the docid Vector
126
          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

    
132
                  Geometry geom = (Geometry)feature.getAttribute(0);
133
                  if ( geom.within( bboxGeom ) ) {
134
                      // assumes docid is attribute number 1 
135
                      // in a zero-based index of dbf columns
136
                      docids.add( (String) feature.getAttribute(1) );
137
                  }
138
              }
139
          } finally {
140
              collection.close( iterator );
141
          }
142
         
143
          /*
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

    
152
          // 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

    
159
          // 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
                  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
                  }
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
      return docids;
191

    
192
  }
193

    
194
}
(6-6/8)