}
void buildIndex(Connection conn) throws Exception {
Statement st = null;
PreparedStatement ps = null;
FeatureIterator fi = null;
try {
st = conn.createStatement();
st.execute("CREATE TABLE FEATUREIDX(" //
+ "X NUMBER, " //
+ "Y NUMBER, " //
+ "FID VARCHAR(64), " //
+ "ORDER_FIELD " + h2Type + ")");
st.execute("CREATE INDEX FEATUREIDX_COORDS ON FEATUREIDX(X, Y)");
st.execute("CREATE INDEX FEATUREIDX_ORDER_FIELD ON FEATUREIDX(ORDER_FIELD)");
// prepare this statement so that the sql parser has to deal
// with it just once
ps = conn.prepareStatement("INSERT INTO "
+ "FEATUREIDX(X, Y, FID, ORDER_FIELD) VALUES (?, ?, ?, ?)");
// build an optimized query, loading only the necessary attributes
GeometryDescriptor geom = fs.getSchema()
.getGeometryDescriptor();
CoordinateReferenceSystem nativeCrs = geom
.getCoordinateReferenceSystem();
Query q = new Query();
if (geom.getLocalName().equals(attribute)) {
q.setPropertyNames(new String[] { geom.getLocalName() });
} else {
q.setPropertyNames(new String[] { attribute, geom.getLocalName() });
}
// setup the eventual transform
MathTransform tx = null;
double[] coords = new double[2];
if (!CRS.equalsIgnoreMetadata(nativeCrs, WGS84))
tx = CRS.findMathTransform(nativeCrs, WGS84, true);
// read all the features and fill the index table
// make it so the insertion is a single big transaction, should
// be faster,
// provided it does not kill H2...
conn.setAutoCommit(false);
fi = fs.getFeatures(q).features();
while (fi.hasNext()) {
// grab the centroid and transform it in 4326 if necessary
SimpleFeature f = (SimpleFeature) fi.next();
Geometry g = (Geometry) f.getDefaultGeometry();
Point centroid = g.getCentroid();
//robustness check for bad geometries
if ( Double.isNaN( centroid.getX() ) || Double.isNaN( centroid.getY() ) ) {
LOGGER.warning( "Could not calculate centroid for feature " + f.getID() + "; g = " + g.toText() );
continue;
}
coords[0] = centroid.getX();
coords[1] = centroid.getY();
if (tx != null)
tx.transform(coords, 0, coords, 0, 1);
// insert
ps.setDouble(1, coords[0]);
ps.setDouble(2, coords[1]);
ps.setString(3, f.getID());
ps.setObject(4, getSortAttributeValue(f));
ps.execute();
}
// todo: commit every 1000 features or so. No transaction is
// slower, but too big transaction imposes a big overhead on the db
conn.commit();
// hum, shall we kick H2 so that it updates the statistics?
} finally {
conn.setAutoCommit(true);
JDBCUtils.close(st);
JDBCUtils.close(ps);
if (fi != null)
fi.close();
}
}