Project

General

Profile

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

    
25
import java.io.File;
26

    
27
import edu.ucsb.nceas.metacat.DBConnection;
28
import edu.ucsb.nceas.metacat.MetaCatUtil;
29

    
30
import com.vividsolutions.jts.geom.Coordinate;
31
import com.vividsolutions.jts.geom.Point;
32
import com.vividsolutions.jts.geom.Polygon;
33
import com.vividsolutions.jts.geom.MultiPolygon;
34
import com.vividsolutions.jts.geom.MultiPoint;
35
import com.vividsolutions.jts.geom.GeometryFactory;
36
import com.vividsolutions.jts.geom.PrecisionModel;
37

    
38
import org.geotools.feature.AttributeType;
39
import org.geotools.feature.AttributeTypeFactory;
40
import org.geotools.feature.Feature;
41
import org.geotools.feature.FeatureType;
42
import org.geotools.feature.FeatureTypeFactory;
43
import org.geotools.feature.SchemaException;
44

    
45
import java.sql.ResultSet;
46
import java.sql.PreparedStatement;
47
import java.util.Vector;
48

    
49
import org.apache.log4j.Logger;
50

    
51
public class SpatialDocument {
52

    
53
  private DBConnection dbconn;
54

    
55
  private static Logger log =
56
      Logger.getLogger(SpatialDocument.class.getName());
57

    
58
  private SpatialFeatureSchema featureSchema = new SpatialFeatureSchema();
59

    
60
  Vector west = new Vector();
61
  Vector south = new Vector();
62
  Vector east = new Vector();
63
  Vector north = new Vector();
64

    
65
  String title = null;
66
  String docid = null;
67

    
68
  /** constructor that queries the db **/
69
  public SpatialDocument( String docid , DBConnection dbconn ) {
70

    
71
    this.docid = docid;
72
    PreparedStatement pstmt = null;
73
    ResultSet rs = null;
74
    this.dbconn = dbconn;
75

    
76
    /*
77
     * Get the bounding coordinates
78
     */
79
    String query = "SELECT path, nodedatanumerical, parentnodeid FROM xml_path_index"
80
    + " WHERE docid = '" + docid.trim() + "'"
81
    + " AND (path = '" + MetaCatUtil.getOption("westBoundingCoordinatePath") + "'"
82
    + "  OR path = '" + MetaCatUtil.getOption("southBoundingCoordinatePath") + "'"
83
    + "  OR path = '" + MetaCatUtil.getOption("eastBoundingCoordinatePath") + "'"
84
    + "  OR path = '" + MetaCatUtil.getOption("northBoundingCoordinatePath") + "'"
85
    + " ) ORDER BY parentnodeid;";
86

    
87
    try {
88
      pstmt = dbconn.prepareStatement(query);
89
      pstmt.execute();
90
      rs = pstmt.getResultSet();
91
      while (rs.next()) {
92
        if ( rs.getString(1).equals( MetaCatUtil.getOption("westBoundingCoordinatePath") ) )
93
            this.west.add( rs.getFloat(2) );
94
        else if ( rs.getString(1).equals( MetaCatUtil.getOption("southBoundingCoordinatePath") ) )
95
            this.south.add( rs.getFloat(2) );
96
        else if ( rs.getString(1).equals( MetaCatUtil.getOption("eastBoundingCoordinatePath") ) )
97
            this.east.add( rs.getFloat(2) );
98
        else if ( rs.getString(1).equals( MetaCatUtil.getOption("northBoundingCoordinatePath") ) )
99
            this.north.add( rs.getFloat(2) );
100
        else
101
            log.error("** An xml path not related to your bounding coordinates was returned by this query \n" + query + "\n");
102
      }
103
      rs.close();
104
      pstmt.close();
105
    }
106
    catch(Exception e) {
107
      log.error(" ---- Error getting bounding coordinates for " + docid);
108
      e.printStackTrace();
109
    }      
110

    
111
    // Get the Title
112
    query = "select docid, nodedata, nodeid "
113
          + "from xml_nodes "
114
          + "where parentnodeid = "
115
          + "  ( select  nodeid "
116
          + "    from  xml_nodes "
117
          + "    where docid like '" + docid.trim() +"' "
118
          + "    and nodename like 'title%' "
119
          + "    and parentnodeid = "
120
          + "      ( select nodeid "
121
          + "        from xml_nodes "
122
          + "        where docid like '" + docid.trim() + "' "
123
          + "        and nodename = 'dataset' "
124
          + "        limit 1) "
125
          + "    limit 1)" ;
126

    
127
    try {
128
      pstmt = dbconn.prepareStatement(query);
129
      pstmt.execute();
130
      rs = pstmt.getResultSet();
131
      if (rs.next())
132
        this.title = rs.getString(2);
133
      rs.close();
134
      pstmt.close();
135
    }
136
    catch(Exception e) {
137
      log.error(" **** Error getting docids from getTitle for docid = "+docid);
138
      e.printStackTrace();
139
      log.error(" query ============== \n " + query);
140
      this.title = docid;
141
    }
142

    
143
    /* try {
144
        dbconn.close();
145
    } catch( java.sql.SQLException e ) {
146
        log.error("java.sql.SQLException");
147
    }
148
    */
149

    
150
  }
151

    
152
  /* 
153
   * Returns a jts (multi)polygon feature with geometry plus attributes
154
   * ready to be inserted into our spatial dataset cache
155
   */
156
  public Feature getPolygonFeature() {
157
      // Get polygon feature type
158
      FeatureType polyType = featureSchema.getPolygonFeatureType();
159

    
160
      MultiPolygon theGeom = getPolygonGeometry();
161
      if (theGeom == null)
162
          return null;
163

    
164
      // Populate the feature schema
165
      try {
166
          Feature polyFeature = polyType.create(new Object[]{ 
167
              theGeom,
168
              this.docid,
169
              getUrl(this.docid), 
170
              this.title });
171
          return polyFeature; 
172
      } catch (org.geotools.feature.IllegalAttributeException e) {
173
          log.error("!!!!!!! org.geotools.feature.IllegalAttributeException");
174
          return null;
175
      }
176
  }
177

    
178
  /* 
179
   * Returns a jts (multi)point feature with geometry plus attributes
180
   * ready to be inserted into our spatial dataset cache
181
   */
182
  public Feature getPointFeature() {
183
      // Get polygon feature type
184
      FeatureType pointType = featureSchema.getPointFeatureType();
185

    
186
      MultiPoint theGeom = getPointGeometry();
187
      if (theGeom == null)
188
          return null;
189

    
190
      // Populate the feature schema
191
      try {
192
          Feature pointFeature = pointType.create(new Object[]{ 
193
              theGeom,
194
              this.docid,
195
              getUrl(this.docid), 
196
              this.title });
197
          return pointFeature;
198
      } catch (org.geotools.feature.IllegalAttributeException e) {
199
          log.error("!!!!!!! org.geotools.feature.IllegalAttributeException");
200
          return null;
201
      }
202
  }
203

    
204
  /*
205
   * Given a valid docid, return an appropriate URL
206
   * for viewing the metadata document
207
   */
208
  private String getUrl( String docid ) {
209
     String docUrl = MetaCatUtil.getOption("metacatUrl")  
210
                    + "?action=read"
211
                    + "&docid=" + docid 
212
                    + "&qformat=" + MetaCatUtil.getOption("default-style");
213

    
214
     return docUrl;
215
  }
216

    
217
  /**
218
   * returns the title of the docid
219
   */
220
  private String getTitle(String docid) {
221
    String title = null;
222
    PreparedStatement pstmt = null;
223
    ResultSet rs = null;
224
    String query = "select docid, nodedata, nodeid "
225
                 + "from xml_nodes "
226
                 + "where parentnodeid = "
227
                 + "  ( select  nodeid "
228
                 + "    from  xml_nodes "
229
                 + "    where docid like '" + docid.trim() +"' "
230
                 + "    and nodename like 'title%' "
231
                 + "    and parentnodeid = "
232
                 + "      ( select nodeid "
233
                 + "        from xml_nodes "
234
                 + "        where docid like '" + docid.trim() + "' "
235
                 + "        and nodename = 'dataset' "
236
                 + "        limit 1) "
237
                 + "    limit 1)" ;
238

    
239
    /*
240
     * String query = "select docid, nodedata, nodeid from xml_nodes where "
241
     *   + "nodeid =(select  nodeid from  xml_nodes where docid  like '"
242
     *   + docid.trim() + "' and nodename like 'title%');";
243
     */
244

    
245
    try {
246
      dbconn = new DBConnection();
247
      pstmt = dbconn.prepareStatement(query);
248
      pstmt.execute();
249
      rs = pstmt.getResultSet();
250
      if (rs.next())
251
        title = rs.getString(2);
252
      rs.close();
253
      pstmt.close();
254
      dbconn.close();
255
    }
256
    catch(Exception e) {
257
      log.error(" **** Error getting docids from getTitle for docid = "+docid);
258
      e.printStackTrace();
259
      log.error(" query ============== \n " + query);
260
      title = docid;
261
    }
262
    
263
    return title;
264
  }
265

    
266

    
267
  /*
268
   * Returns polygon geometry
269
   */
270
  private MultiPolygon getPolygonGeometry() {
271

    
272
    PrecisionModel precModel = new PrecisionModel(); // default: Floating point
273
    GeometryFactory geomFac = new GeometryFactory( precModel, featureSchema.srid );
274

    
275
    Vector polygons = new Vector();
276

    
277
    if ( west.size() == south.size() && south.size() == east.size() && east.size() == north.size() ) {
278
        for (int i = 0; i < west.size(); i++) {
279

    
280
            Coordinate[] linestringCoordinates = new Coordinate[5];
281

    
282
            // Check if it's actually a valid polygon
283
            if ( (Float)west.elementAt(i) == 0.0 &&
284
                 (Float)east.elementAt(i) == 0.0 && 
285
                 (Float)north.elementAt(i) == 0.0 &&
286
                 (Float)south.elementAt(i) == 0.0) {
287

    
288
                log.warn("        Invalid or empty coodinates ... skipping");
289
                continue;
290
            } else if( ((Float)west.elementAt(i)).compareTo( (Float)east.elementAt(i) ) == 0 && 
291
                       ((Float)north.elementAt(i)).compareTo( (Float)south.elementAt(i) ) == 0 ) {
292

    
293
                log.warn("        Point coordinates only.. skipping polygon generation");
294
                continue;
295
            }
296

    
297
            linestringCoordinates[0] = new Coordinate( (Float)west.elementAt(i), (Float)south.elementAt(i) );
298
            linestringCoordinates[1] = new Coordinate( (Float)west.elementAt(i), (Float)north.elementAt(i));
299
            linestringCoordinates[2] = new Coordinate( (Float)east.elementAt(i), (Float)north.elementAt(i));
300
            linestringCoordinates[3] = new Coordinate( (Float)east.elementAt(i), (Float)south.elementAt(i));
301
            linestringCoordinates[4] = new Coordinate( (Float)west.elementAt(i), (Float)south.elementAt(i));
302
            polygons.add( geomFac.createPolygon( geomFac.createLinearRing(linestringCoordinates), null) );
303
        }
304
    } else {
305
       log.error(" *** Something went wrong.. your east,west,north and south bounding arrays are different sizes!");
306
    }
307
    
308
    if( polygons.size() > 0 ) {
309
       Polygon[] polyArray = geomFac.toPolygonArray( polygons );
310
       MultiPolygon multiPolyGeom= geomFac.createMultiPolygon( polyArray );
311
       return multiPolyGeom; 
312
    } else {
313
       return null;
314
    } 
315

    
316
  }
317
   
318
  /*
319
   * returns a point geometry
320
   */
321
  private MultiPoint getPointGeometry() {
322

    
323
    PrecisionModel precModel = new PrecisionModel(); // default: Floating point
324
    GeometryFactory geomFac = new GeometryFactory( precModel, featureSchema.srid );
325

    
326
    PreparedStatement pstmt = null;
327
    ResultSet rs = null;
328

    
329
    Vector points = new Vector();
330

    
331
    if ( west.size() == south.size() && south.size() == east.size() && east.size() == north.size() ) {
332
        for (int i = 0; i < west.size(); i++) {
333

    
334
            // Check if it's actually a valid point
335
            if ( (Float)west.elementAt(i) == (float)0.0 &&
336
                 (Float)east.elementAt(i) == (float)0.0 && 
337
                 (Float)north.elementAt(i) == (float)0.0 &&
338
                 (Float)south.elementAt(i) == (float)0.0 ) {
339

    
340
                log.warn("        Invalid or empty coodinates ... skipping");
341
                continue;
342
            }
343

    
344
            Double xCenter = ( (Float)west.elementAt(i) + (Float)east.elementAt(i) ) / (Double) 2.0;
345
            Double yCenter = ( (Float)south.elementAt(i) + (Float)north.elementAt(i) ) / (Double) 2.0;
346
            points.add( geomFac.createPoint( new Coordinate( xCenter, yCenter)) );
347
        }
348
    } else {
349
       log.error(" *** Something went wrong.. your east,west,north and south bounding vectors are different sizes!");
350
    }
351
    
352
    if( points.size() > 0 ) {
353
       Point[] pointArray = geomFac.toPointArray( points );
354
       MultiPoint multiPointGeom= geomFac.createMultiPoint( pointArray );
355
       return multiPointGeom; 
356
    } else {
357
       return null;
358
    } 
359

    
360

    
361
  }
362
}
(10-10/16)