Subversion Repositories hibernate-spatial

Compare Revisions

Ignore whitespace Rev 303 → Rev 304

/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/cfg/HSConfigurationTest.java
New file
0,0 → 1,30
package org.hibernatespatial.cfg;
 
import org.junit.Test;
 
import static org.junit.Assert.assertEquals;
 
public class HSConfigurationTest {
 
@Test
public void testConfigureFailure() {
HSConfiguration config = new HSConfiguration();
config.configure("non-existing-file");
}
 
@Test
public void testConfigureFile() {
HSConfiguration config = new HSConfiguration();
config.configure("test.cfg.xml");
testResults(config);
}
 
 
private void testResults(HSConfiguration config) {
assertEquals("org.hibernatespatial.postgis.PostgisDialect", config
.getDefaultDialect());
assertEquals("FIXED", config.getPrecisionModel());
assertEquals("5", config.getPrecisionModelScale());
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestCircle.java
New file
0,0 → 1,196
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.test;
 
import com.vividsolutions.jts.geom.Coordinate;
import org.hibernatespatial.Circle;
import org.junit.Test;
 
import static org.junit.Assert.*;
 
/**
* Test functionality of Circle class Date: Oct 15, 2007
*
* @author Tom Acree
*/
public class TestCircle {
 
@Test
public void testCreateCircle() {
 
Coordinate center = (new Coordinate(0, 0));
double radius = 5;
 
Coordinate p1 = new Coordinate(3, 4);
Coordinate p2 = new Coordinate(0, 5);
Coordinate p3 = new Coordinate(-3, 4);
 
Circle c0 = new Circle(center, radius);
Circle c1 = new Circle(p1, p2, p3);
assertEquals(c0, c1);
 
assertTrue(Double.compare(c1.getRadius(), radius) == 0);
assertTrue(c1.getCenter().equals2D(center));
 
double distance = c1.distanceFromCenter(p3);
assertTrue(Double.compare(c1.getRadius(), distance) == 0);
}
 
@Test
public void testNormalize() {
double actual, expected = 0;
 
double angleIncr = Math.PI / 4; // increment by 45 degrees
double twoPi = Math.PI * 2;
int factor = 8;
for (int i = 0; i <= factor; i++) {
expected = i * angleIncr;
actual = (Circle.normalizeAngle(expected));
assertEquals(actual, expected, Math.ulp(expected));
double degrees = Math.toDegrees(actual);
assertTrue(actual <= twoPi);
assertTrue(degrees <= 360);
}
 
factor = -8;
double testAngle;
for (int i = -1; i >= factor; i--) {
testAngle = i * angleIncr;
expected = twoPi + (i * angleIncr);
actual = (Circle.normalizeAngle(testAngle));
assertEquals(actual, expected, Math.ulp(expected));
double degrees = Math.toDegrees(actual);
assertTrue(actual <= Math.PI * 2);
assertTrue(degrees <= 360);
}
 
// couple extra boundary cases
expected = 0;
actual = Circle.normalizeAngle(twoPi * 8);
assertEquals(expected, actual, Math.ulp(expected));
 
testAngle = angleIncr + twoPi;
expected = angleIncr;
actual = Circle.normalizeAngle(testAngle);
assertEquals(expected, actual, Math.ulp(expected));
 
testAngle = angleIncr - twoPi;
expected = angleIncr;
actual = Circle.normalizeAngle(testAngle);
assertEquals(expected, actual, Math.ulp(expected));
}
 
@Test
public void testAngleDifference() {
double a1 = Math.PI / 8;
double a2 = Math.PI / 4;
 
double diff = Circle.subtractAngles(a1, a2);
assertTrue(diff < Math.PI);
 
diff = Circle.subtractAngles(a2, a1);
assertTrue(diff > Math.PI);
}
 
@Test
public void testMajorArc() {
Coordinate expectedCenter = new Coordinate(3, 0);
double expectedRadius = 5;
Coordinate p1 = new Coordinate(0, 4);
Coordinate p2 = new Coordinate(8, 0);
Coordinate p3 = new Coordinate(0, -4);
Circle c = new Circle(p1, p2, p3);
 
assertTrue(c.getCenter().equals2D(expectedCenter));
assertTrue(Double.compare(c.getRadius(), expectedRadius) == 0);
}
 
@Test
public void testArcDirection() {
Coordinate[] coords = new Coordinate[]{new Coordinate(0, 5),
new Coordinate(3, 4), new Coordinate(5, 0),
new Coordinate(3, -4), new Coordinate(0, -5),
new Coordinate(-3, -4), new Coordinate(-5, 0),
new Coordinate(-3, 4)};
for (int i = 0; i < coords.length; i++) {
Coordinate p1 = coords[i];
Coordinate p2 = coords[(i + 1) % coords.length];
Coordinate p3 = coords[(i + 2) % coords.length];
Circle c = new Circle(p1, p2, p3);
Circle.Arc a = c.createArc(p1, p2, p3);
assertTrue("Failed Points:" + p1 + ", " + p2 + ", " + p3, a
.isClockwise());
}
 
for (int i = 0; i < coords.length; i++) {
Coordinate p3 = coords[i];
Coordinate p2 = coords[(i + 1) % coords.length];
Coordinate p1 = coords[(i + 2) % coords.length];
Circle c = new Circle(p1, p2, p3);
Circle.Arc a = c.createArc(p1, p2, p3);
assertFalse("Failed Points:" + p1 + ", " + p2 + ", " + p3, a
.isClockwise());
}
}
 
@Test
public void testLinearize() {
Coordinate p1 = new Coordinate(5, 0);
Coordinate p2 = new Coordinate(4, 3);
Coordinate p3 = new Coordinate(4, -3);
 
Circle c = new Circle(p1, p2, p3);
 
Coordinate[] results = c.linearizeArc(p3, p2, p1, c.getRadius() * 0.01);
 
assertNotNull(results);
assertTrue(results.length > 0);
for (Coordinate coord : results) {
double error = c.getRadius() - c.distanceFromCenter(coord);
assertTrue(Double.compare(error, 0.0001) < 0);
}
}
 
@Test
public void testLinearizeCircle() {
Coordinate p1 = new Coordinate(5, 0);
Coordinate p2 = new Coordinate(4, 3);
Coordinate p3 = new Coordinate(4, -3);
 
Circle c = new Circle(p1, p2, p3);
Coordinate[] results = c.linearizeArc(p1, p2, p1,
(c.getRadius() * 0.01));
for (Coordinate coord : results) {
double error = c.getRadius() - c.distanceFromCenter(coord);
assertTrue(Double.compare(error, 0.0001) < 0);
}
 
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/AbstractExpectationsFactory.java
New file
0,0 → 1,803
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
 
/**
* An <code>AbstractExpectationsFactory</code> provides the expected
* values to be used in the unit tests of the spatial functions
* provided by specific providers.
* <p/>
* The expected values are returned as a map of (identifier, expected value) pairs.
*
* @author Karel Maesen, Geovise BVBA
*/
public abstract class AbstractExpectationsFactory {
 
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractExpectationsFactory.class);
 
public final static String TEST_POLYGON_WKT = "POLYGON((0 0, 50 0, 100 100, 0 100, 0 0))";
public final static String TEST_POINT_WKT = "POINT(0 0)";
 
public final static int INTEGER = 1;
public final static int DOUBLE = 2;
public final static int GEOMETRY = 3;
public final static int STRING = 4;
public final static int BOOLEAN = 5;
public final static int OBJECT = -1;
 
private final static int TEST_SRID = 4326;
 
private final DataSourceUtils dataSourceUtils;
private static final int MAX_BYTE_LEN = 1024;
 
public AbstractExpectationsFactory(DataSourceUtils dataSourceUtils) {
this.dataSourceUtils = dataSourceUtils;
}
 
protected DataSourceUtils getDataSourceUtils() {
return this.dataSourceUtils;
}
 
/**
* Returns the SRID in which all tests are conducted. This is for now 4326;
*
* @return
*/
public int getTestSrid() {
return TEST_SRID;
}
 
 
/**
* Returns the expected dimensions of all testsuite-suite geometries.
*
* @return map of identifier, dimension
* @throws SQLException
*/
public Map<Integer, Integer> getDimension() throws SQLException {
return retrieveExpected(createNativeDimensionSQL(), INTEGER);
}
 
/**
* Returns the expected WKT of all testsuite-suite geometries.
*
* @return map of identifier, WKT-string
* @throws SQLException
*/
public Map<Integer, String> getAsText() throws SQLException {
return retrieveExpected(createNativeAsTextStatement(), STRING);
 
}
 
 
/**
* Returns the expected WKB representations of all testsuite-suite geometries
*
* @return map of identifier, WKB representation
* @throws SQLException
*/
public Map<Integer, byte[]> getAsBinary() throws SQLException {
return retrieveExpected(createNativeAsBinaryStatement(), OBJECT);
}
 
/**
* Returns the expected type names of all testsuite-suite geometries
*
* @return map of identifier, type name
* @throws SQLException
*/
public Map<Integer, String> getGeometryType() throws SQLException {
return retrieveExpected(createNativeGeometryTypeStatement(), STRING);
}
 
/**
* Returns the expected SRID codes of all testsuite-suite geometries
*
* @return map of identifier, SRID
* @throws SQLException
*/
public Map<Integer, Integer> getSrid() throws SQLException {
return retrieveExpected(createNativeSridStatement(), INTEGER);
}
 
/**
* Returns whether the testsuite-suite geometries are simple
*
* @return map of identifier and whether testsuite-suite geometry is simple
* @throws SQLException
*/
public Map<Integer, Boolean> getIsSimple() throws SQLException {
return retrieveExpected(createNativeIsSimpleStatement(), BOOLEAN);
}
 
/**
* Returns whether the testsuite-suite geometries are empty
*
* @return map of identifier and whether testsuite-suite geometry is empty
* @throws SQLException
*/
public Map<Integer, Boolean> getIsEmpty() throws SQLException {
return retrieveExpected(createNativeIsEmptyStatement(), BOOLEAN);
}
 
/**
* Returns whether the testsuite-suite geometries are empty
*
* @return map of identifier and whether testsuite-suite geometry is empty
* @throws SQLException
*/
public Map<Integer, Boolean> getIsNotEmpty() throws SQLException {
return retrieveExpected(createNativeIsNotEmptyStatement(), BOOLEAN);
}
 
 
/**
* Returns the expected boundaries of all testsuite-suite geometries
*
* @return map of identifier and boundary geometry
* @throws SQLException
*/
public Map<Integer, Geometry> getBoundary() throws SQLException {
return retrieveExpected(createNativeBoundaryStatement(), GEOMETRY);
}
 
/**
* Returns the expected envelopes of all testsuite-suite geometries
*
* @return map of identifier and envelope
* @throws SQLException
*/
public Map<Integer, Geometry> getEnvelope() throws SQLException {
return retrieveExpected(createNativeEnvelopeStatement(), GEOMETRY);
}
 
/**
* Returns the expected results of the within operator
*
* @param geom testsuite-suite geometry
* @return
* @throws SQLException
*/
public Map<Integer, Boolean> getWithin(Geometry geom) throws SQLException {
return retrieveExpected(createNativeWithinStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the equals operator
*
* @param geom
* @return
* @throws SQLException
*/
public Map<Integer, Boolean> getEquals(Geometry geom) throws SQLException {
return retrieveExpected(createNativeEqualsStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the crosses operator
*
* @param geom
* @return
* @throws SQLException
*/
public Map<Integer, Boolean> getCrosses(Geometry geom) throws SQLException {
return retrieveExpected(createNativeCrossesStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the contains operator
*/
public Map<Integer, Boolean> getContains(Geometry geom) throws SQLException {
return retrieveExpected(createNativeContainsStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the disjoint operator
*
* @param geom
* @return
* @throws SQLException
*/
public Map<Integer, Boolean> getDisjoint(Geometry geom) throws SQLException {
return retrieveExpected(createNativeDisjointStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the intersects operator
*
* @param geom
* @return
* @throws SQLException
*/
public Map<Integer, Boolean> getIntersects(Geometry geom) throws SQLException {
return retrieveExpected(createNativeIntersectsStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the touches operator
*
* @param geom
* @return
* @throws SQLException
*/
public Map<Integer, Boolean> getTouches(Geometry geom) throws SQLException {
return retrieveExpected(createNativeTouchesStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the overlaps operator
*
* @param geom
* @return
* @throws SQLException
*/
public Map<Integer, Boolean> getOverlaps(Geometry geom) throws SQLException {
return retrieveExpected(createNativeOverlapsStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the DWithin operator
*
* @param geom
* @param distance
* @return
*/
public Map<Integer, Boolean> getDwithin(Point geom, double distance) throws SQLException {
return retrieveExpected(createNativeDwithinStatement(geom, distance), BOOLEAN);
}
 
/**
* Returns the expected result of the havingSRID operator
*
* @param srid the SRID (EPSG code)
* @return
*/
public Map<Integer, Boolean> havingSRID(int srid) throws SQLException {
return retrieveExpected(createNativeHavingSRIDStatement(srid), BOOLEAN);
}
 
 
/**
* Returns the expected results of the relate operator
*
* @param geom
* @param matrix
* @return
* @throws SQLException
*/
public Map<Integer, Boolean> getRelate(Geometry geom, String matrix) throws SQLException {
return retrieveExpected(createNativeRelateStatement(geom, matrix), BOOLEAN);
}
 
/**
* Returns the expected results for the geometry filter
*
* @param geom filter Geometry
* @return
*/
public Map<Integer, Boolean> getFilter(Geometry geom) throws SQLException {
return retrieveExpected(createNativeFilterStatement(geom), BOOLEAN);
}
 
/**
* Returns the expected results of the distance function
*
* @param geom geometry parameter to distance function
* @return
* @throws SQLException
*/
public Map<Integer, Double> getDistance(Geometry geom) throws SQLException {
return retrieveExpected(createNativeDistanceStatement(geom), DOUBLE);
}
 
/**
* Returns the expected results of the buffering function
*
* @param distance distance parameter to the buffer function
* @return
* @throws SQLException
*/
public Map<Integer, Geometry> getBuffer(Double distance) throws SQLException {
return retrieveExpected(createNativeBufferStatement(distance), GEOMETRY);
}
 
/**
* Returns the expected results of the convexhull function
*
* @param geom geometry with which each testsuite-suite geometry is unioned before convexhull calculation
* @return
* @throws SQLException
*/
public Map<Integer, Geometry> getConvexHull(Geometry geom) throws SQLException {
return retrieveExpected(createNativeConvexHullStatement(geom), GEOMETRY);
}
 
/**
* Returns the expected results of the intersection function
*
* @param geom parameter to the intersection function
* @return
* @throws SQLException
*/
public Map<Integer, Geometry> getIntersection(Geometry geom) throws SQLException {
return retrieveExpected(createNativeIntersectionStatement(geom), GEOMETRY);
}
 
/**
* Returns the expected results of the difference function
*
* @param geom parameter to the difference function
* @return
* @throws SQLException
*/
public Map<Integer, Geometry> getDifference(Geometry geom) throws SQLException {
return retrieveExpected(createNativeDifferenceStatement(geom), GEOMETRY);
}
 
/**
* Returns the expected results of the symdifference function
*
* @param geom parameter to the symdifference function
* @return
* @throws SQLException
*/
 
public Map<Integer, Geometry> getSymDifference(Geometry geom) throws SQLException {
return retrieveExpected(createNativeSymDifferenceStatement(geom), GEOMETRY);
}
 
/**
* Returns the expected results of the geomunion function
*
* @param geom parameter to the geomunion function
* @return
* @throws SQLException
*/
public Map<Integer, Geometry> getGeomUnion(Geometry geom) throws SQLException {
return retrieveExpected(createNativeGeomUnionStatement(geom), GEOMETRY);
}
 
/**
* Returns the expected result of the transform function
*
* @param epsg
* @return
* @throws SQLException
*/
public Map<Integer, Geometry> getTransform(int epsg) throws SQLException {
return retrieveExpected(createNativeTransformStatement(epsg), GEOMETRY);
}
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, touches(geom, :filter) from GeomEntity where touches(geom, :filter) = true and srid(geom) = 4326"
*
* @param geom the geometry corresponding to the ':filter' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeTouchesStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, overlaps(geom, :filter) from GeomEntity where overlaps(geom, :filter) = true and srid(geom) = 4326"
*
* @param geom the geometry corresponding to the ':filter' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeOverlapsStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, relate(geom, :filter, :matrix) from GeomEntity where relate(geom, :filter, :matrix) = true and srid(geom) = 4326"
*
* @param geom the geometry corresponding to the ':filter' query parameter
* @param matrix the string corresponding to the ':matrix' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeRelateStatement(Geometry geom, String matrix);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, dwithin(geom, :filter, :distance) from GeomEntity where dwithin(geom, :filter, :distance) = true and srid(geom) = 4326"
*
* @param geom the geometry corresponding to the ':filter' query parameter
* @param distance the string corresponding to the ':distance' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeDwithinStatement(Point geom, double distance);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, intersects(geom, :filter) from GeomEntity where intersects(geom, :filter) = true and srid(geom) = 4326"
*
* @param geom the geometry corresponding to the ':filter' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeIntersectsStatement(Geometry geom);
 
/**
* Returns the statement corresponding to the SpatialRestrictions.filter() method.
*
* @param geom filter geometry
* @return
*/
protected abstract NativeSQLStatement createNativeFilterStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, distance(geom, :filter) from GeomEntity where srid(geom) = 4326"
*
* @param geom
* @return
*/
protected abstract NativeSQLStatement createNativeDistanceStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, dimension(geom) from GeomEntity".
*
* @return the SQL String
*/
protected abstract NativeSQLStatement createNativeDimensionSQL();
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, buffer(geom, :distance) from GeomEntity where srid(geom) = 4326"
*
* @param distance parameter corresponding to the ':distance' query parameter
* @return the native SQL Statement
*/
protected abstract NativeSQLStatement createNativeBufferStatement(Double distance);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, convexhull(geomunion(geom, :polygon)) from GeomEntity where srid(geom) = 4326"
*
* @param geom parameter corresponding to the ':polygon' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeConvexHullStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, intersection(geom, :polygon) from GeomEntity where srid(geom) = 4326"
*
* @param geom parameter corresponding to the ':polygon' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeIntersectionStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, difference(geom, :polygon) from GeomEntity where srid(geom) = 4326"26"
*
* @param geom parameter corresponding to the ':polygon' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeDifferenceStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, symdifference(geom, :polygon) from GeomEntity where srid(geom) = 4326"26"
*
* @param geom parameter corresponding to the ':polygon' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeSymDifferenceStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, geomunion(geom, :polygon) from GeomEntity where srid(geom) = 4326"26"
*
* @param geom parameter corresponding to the ':polygon' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeGeomUnionStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, astext(geom) from GeomEntity".
*
* @return the native SQL Statement
*/
protected abstract NativeSQLStatement createNativeAsTextStatement();
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, srid(geom) from GeomEntity".
*
* @return the native SQL Statement
*/
protected abstract NativeSQLStatement createNativeSridStatement();
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, issimple(geom) from GeomEntity".
*
* @return the native SQL Statement
*/
protected abstract NativeSQLStatement createNativeIsSimpleStatement();
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, isempty(geom) from GeomEntity".
*
* @return the native SQL Statement
*/
protected abstract NativeSQLStatement createNativeIsEmptyStatement();
 
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id,not isempty(geom) from GeomEntity".
*
* @return
*/
protected abstract NativeSQLStatement createNativeIsNotEmptyStatement();
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, boundary(geom) from GeomEntity".
*
* @return the native SQL Statement
*/
protected abstract NativeSQLStatement createNativeBoundaryStatement();
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, envelope(geom) from GeomEntity".
*
* @return the native SQL Statement
*/
protected abstract NativeSQLStatement createNativeEnvelopeStatement();
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, asbinary(geom) from GeomEntity".
*
* @return the native SQL Statement
*/
protected abstract NativeSQLStatement createNativeAsBinaryStatement();
 
/**
* Returns a statement corresponding to the HQL statement:
* "select id, geometrytype(geom) from GeomEntity".
*
* @return the SQL String
*/
protected abstract NativeSQLStatement createNativeGeometryTypeStatement();
 
/**
* Returns a statement corresponding to the HQL statement
* "SELECT id, within(geom, :filter) from GeomEntity where within(geom, :filter) = true and srid(geom) = 4326"
*
* @param testPolygon the geometry corresponding to the ':filter' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeWithinStatement(Geometry testPolygon);
 
/**
* Returns a statement corresponding to the HQL statement
* "SELECT id, equals(geom, :filter) from GeomEntity where equals(geom, :filter) = true and srid(geom) = 4326"
*
* @param geom the geometry corresponding to the ':filter' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeEqualsStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement
* "SELECT id, crosses(geom, :filter) from GeomEntity where crosses(geom, :filter) = true and srid(geom) = 4326"
*
* @param geom the geometry corresponding to the ':filter' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeCrossesStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement:
* "SELECT id, contains(geom, :filter) from GeomEntity where contains(geom, :geom) = true and srid(geom) = 4326";
*
* @param geom
* @return
*/
protected abstract NativeSQLStatement createNativeContainsStatement(Geometry geom);
 
/**
* Returns a statement corresponding to the HQL statement
* "SELECT id, disjoint(geom, :filter) from GeomEntity where disjoint(geom, :filter) = true and srid(geom) = 4326"
*
* @param geom the geometry corresponding to the ':filter' query parameter
* @return
*/
protected abstract NativeSQLStatement createNativeDisjointStatement(Geometry geom);
 
 
/**
* Returns a statement corresponding to the HQL statement
* "SELECT id, transform(geom, :epsg) from GeomEntity where srid(geom) = 4326"
*
* @param epsg - the EPSG code of the target projection system.
* @return
*/
protected abstract NativeSQLStatement createNativeTransformStatement(int epsg);
 
/**
* Returns the statement corresponding to the HQL statement
* "select id, (srid(geom) = :epsg) from GeomEntity where srid(geom) = :epsg ";
*
* @param srid
* @return
*/
protected abstract NativeSQLStatement createNativeHavingSRIDStatement(int srid);
 
/**
* Creates a connection to the database
*
* @return a Connection
* @throws SQLException
*/
protected Connection createConnection() throws SQLException {
return this.dataSourceUtils.getConnection();
}
 
/**
* Decodes a native database object to a JTS <code>Geometry</code> instance
*
* @param o native database object
* @return decoded geometry
*/
protected abstract Geometry decode(Object o);
 
/**
* Return a testsuite-suite polygon (filter, ...)
*
* @return a testsuite-suite polygon
*/
public Polygon getTestPolygon() {
WKTReader reader = new WKTReader();
try {
Polygon polygon = (Polygon) reader.read(TEST_POLYGON_WKT);
polygon.setSRID(getTestSrid());
return polygon;
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
 
/**
* Return a testsuite-suite point (filter, ...)
*
* @return a testsuite-suite point
*/
public Point getTestPoint() {
WKTReader reader = new WKTReader();
try {
Point point = (Point) reader.read(TEST_POINT_WKT);
point.setSRID(getTestSrid());
return point;
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
 
protected <T> Map<Integer, T> retrieveExpected(NativeSQLStatement nativeSQLStatement, int type) throws SQLException {
PreparedStatement preparedStatement = null;
Connection cn = null;
Map<Integer, T> expected = new HashMap<Integer, T>();
try {
cn = createConnection();
preparedStatement = nativeSQLStatement.prepare(cn);
LOGGER.info("Native SQL is: " + preparedStatement.toString());
ResultSet results = preparedStatement.executeQuery();
while (results.next()) {
int id = results.getInt(1);
switch (type) {
case GEOMETRY:
expected.put(id, (T) decode(results.getObject(2)));
break;
case STRING:
expected.put(id, (T) results.getString(2));
break;
case INTEGER:
expected.put(id, (T) Long.valueOf(results.getLong(2)));
break;
case DOUBLE:
Double value = Double.valueOf(results.getDouble(2));
if (results.wasNull())
value = null; //this is required because SQL Server converts automatically null to 0.0
expected.put(id, (T) value);
break;
case BOOLEAN:
expected.put(id, (T) Boolean.valueOf(results.getBoolean(2)));
break;
default:
T val = (T) results.getObject(2);
//this code is a hack to deal with Oracle Spatial that returns Blob's for asWKB() function
//TODO -- clean up
if (val instanceof Blob) {
val = (T) ((Blob) val).getBytes(1, MAX_BYTE_LEN);
}
expected.put(id, val);
}
}
return expected;
} finally {
if (preparedStatement != null) preparedStatement.close();
if (cn != null) cn.close();
}
}
 
protected NativeSQLStatement createNativeSQLStatement(final String sql) {
return new NativeSQLStatement() {
public PreparedStatement prepare(Connection connection) throws SQLException {
return connection.prepareStatement(sql);
}
};
}
 
protected NativeSQLStatement createNativeSQLStatementAllWKTParams(final String sql, final String wkt) {
return new NativeSQLStatement() {
public PreparedStatement prepare(Connection connection) throws SQLException {
PreparedStatement pstmt = connection.prepareStatement(sql);
for (int i = 1; i <= numPlaceHoldersInSQL(sql); i++) {
pstmt.setString(i, wkt);
}
return pstmt;
}
};
}
 
protected NativeSQLStatement createNativeSQLStatement(final String sql, final Object[] params) {
return new NativeSQLStatement() {
public PreparedStatement prepare(Connection connection) throws SQLException {
PreparedStatement pstmt = connection.prepareStatement(sql);
int i = 1;
for (Object param : params) {
pstmt.setObject(i++, param);
}
return pstmt;
}
};
}
 
 
protected int numPlaceHoldersInSQL(String sql) {
return sql.replaceAll("[^?]", "").length();
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestDataElement.java
New file
0,0 → 1,49
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
/**
* A <code>TestDataElement</code> captures the information necessary to build a testsuite-suite geometry.
*
* @author Karel Maesen, Geovise BVBA
*/
public class TestDataElement {
 
 
final public String wkt;
final public int id;
final public int srid;
final public String type;
 
protected TestDataElement(int id, String type, String wkt, int srid) {
this.wkt = wkt;
this.id = id;
this.type = type;
this.srid = srid;
}
 
}
 
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/GeomEntity.java
New file
0,0 → 1,93
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
 
/**
* Test class used in unit testing.
*/
public class GeomEntity implements TestFeature {
 
private Integer id;
 
private String type;
 
private Geometry geom;
 
public Integer getId() {
return id;
}
 
public void setId(Integer id) {
this.id = id;
}
 
public String getType() {
return type;
}
 
public void setType(String type) {
this.type = type;
}
 
public Geometry getGeom() {
return geom;
}
 
public void setGeom(Geometry geom) {
this.geom = geom;
}
 
public static GeomEntity createFrom(TestDataElement element) throws ParseException {
EWKTReader reader = new EWKTReader();
GeomEntity result = new GeomEntity();
result.setId(element.id);
Geometry geom = reader.read(element.wkt);
geom.setSRID(element.srid);
result.setGeom(geom);
result.setType(element.type);
return result;
}
 
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
 
GeomEntity geomEntity = (GeomEntity) o;
 
if (id != geomEntity.id) return false;
 
return true;
}
 
@Override
public int hashCode() {
return id;
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/TestMLineStringGetCoordinatesBetween.java
New file
0,0 → 1,512
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.PrecisionModel;
import org.hibernatespatial.mgeom.*;
import org.junit.Before;
import org.junit.Test;
 
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;
 
public class TestMLineStringGetCoordinatesBetween {
MLineString incrLine;
MLineString decLine;
MLineString emptyLine;
MLineString nonMonotoneLine;
MLineString partiallyConstantIncreasing;
MLineString partiallyConstantDecreasing;
 
 
private PrecisionModel prec = new PrecisionModel(PrecisionModel.FIXED);
 
private MGeometryFactory mgeomFactory = new MGeometryFactory(
MCoordinateSequenceFactory.instance());
 
@Before
public void setUp() {
 
MCoordinate[] coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0)
};
incrLine = mgeomFactory.createMLineString(coordinates);
 
coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0)
};
decLine = mgeomFactory.createMLineString(coordinates);
 
coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(0.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 5.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 1.5)
};
nonMonotoneLine = mgeomFactory.createMLineString(coordinates);
 
coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0)
};
partiallyConstantIncreasing = mgeomFactory.createMLineString(coordinates);
 
coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0)
};
partiallyConstantDecreasing = mgeomFactory.createMLineString(coordinates);
 
 
}
 
@Test
public void test_measure_inside_monotone_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = incrLine.getCoordinatesBetween(0.5, 3.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(1.0, 3.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0), crds[2]);
 
result = incrLine.getCoordinatesBetween(0.0, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[4]);
 
result = incrLine.getCoordinatesBetween(0.5, 1.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(3.5, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.5), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(3.5, 3.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.7, 0.0, 3.7), crds[1]);
 
result = incrLine.getCoordinatesBetween(0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[1]);
 
result = incrLine.getCoordinatesBetween(-0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[1]);
 
result = incrLine.getCoordinatesBetween(3.5, 4.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[1]);
}
 
 
@Test
public void test_measure_inside_partially_constant_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = partiallyConstantIncreasing.getCoordinatesBetween(0.5, 2.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 2.5), crds[crds.length - 1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(1.0, 3.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0), crds[3]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(0.0, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(6, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[5]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(0.5, 1.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[crds.length - 1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(1.5, 2.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 2.5), crds[crds.length - 1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(3.5, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[crds.length - 1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(3.5, 3.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.7, 0.0, 3.7), crds[1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(-0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(3.5, 4.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[1]);
}
 
@Test
public void test_measures_monotone_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = decLine.getCoordinatesBetween(0.5, 3.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(1.0, 3.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[2]);
 
result = decLine.getCoordinatesBetween(0.0, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[4]);
 
result = decLine.getCoordinatesBetween(0.5, 1.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(3.5, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(3.5, 3.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.7, 0.0, 3.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[1]);
 
result = decLine.getCoordinatesBetween(0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[1]);
 
result = decLine.getCoordinatesBetween(-0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[1]);
 
result = decLine.getCoordinatesBetween(3.5, 4.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
}
 
 
@Test
public void test_measures_partially_constant_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = partiallyConstantDecreasing.getCoordinatesBetween(0.5, 3.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(6, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(1.0, 3.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[2]);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[3]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(0.0, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(6, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[5]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(0.5, 1.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(1.5, 2.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 2.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[2]);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[3]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(3.5, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[crds.length - 1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(3.5, 3.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.7, 0.0, 3.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(-0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(3.5, 4.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[0]);
}
 
@Test
public void test_measure_outside_monotone_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = incrLine.getCoordinatesBetween(-1.5, -0.5);
assertEquals(1, result.length);
assertEquals(0, result[0].size());
 
result = incrLine.getCoordinatesBetween(10.0, 20.0);
assertEquals(1, result.length);
assertEquals(0, result[0].size());
}
 
@Test
public void test_measure_outside_monotone_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = decLine.getCoordinatesBetween(-1.5, -0.5);
assertEquals(1, result.length);
assertEquals(0, result[0].size());
 
result = decLine.getCoordinatesBetween(10.0, 20.0);
assertEquals(1, result.length);
assertEquals(0, result[0].size());
}
 
@Test
public void test_measure_overlap_monotone_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = incrLine.getCoordinatesBetween(-0.5, 5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(0.5, 5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(-1.0, 2.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(2.5, 0.0, 2.5), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(4.0, 5.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(1, crds.length);
 
}
 
@Test
public void test_measure_overlap_monotone_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = decLine.getCoordinatesBetween(-0.5, 5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(0.5, 5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(-1.0, 2.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(2.5, 0.0, 2.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[crds.length - 1]);
}
 
@Test
public void test_measure_inverse_monotone_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = incrLine.getCoordinatesBetween(3.5, 0.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[crds.length - 1]);
}
 
@Test
public void test_measure_inverse_monotone_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = decLine.getCoordinatesBetween(3.5, 0.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
}
 
@Test
public void test_fail_on_non_monotone() throws MGeometryException {
try {
nonMonotoneLine.getCoordinatesBetween(0.5, 10.0);
fail("Needs to throw an IllegalArgumentException on non-monotone linestrings.");
} catch (MGeometryException e) {
assertEquals(e.getType(), MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/TestEventLocator.java
New file
0,0 → 1,120
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.PrecisionModel;
import org.hibernatespatial.mgeom.*;
import org.junit.Before;
import org.junit.Test;
 
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
 
public class TestEventLocator {
 
private PrecisionModel prec = new PrecisionModel(PrecisionModel.FIXED);
 
private MGeometryFactory mgeomFactory = new MGeometryFactory(
MCoordinateSequenceFactory.instance());
 
private MultiMLineString incrML;
 
@Before
public void setUp() {
 
MCoordinate[] coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0)
};
MLineString line1 = mgeomFactory.createMLineString(coordinates);
 
MCoordinate[] coordinates2 = new MCoordinate[]{
MCoordinate.create2dWithMeasure(5.0, 0.0, 5.0),
MCoordinate.create2dWithMeasure(6.0, 0.0, 6.0),
MCoordinate.create2dWithMeasure(7.0, 0.0, 7.0),
};
MLineString line2 = mgeomFactory.createMLineString(coordinates2);
 
MCoordinate[] coordinates3 = new MCoordinate[]{
MCoordinate.create2dWithMeasure(9.0, 0.0, 9.0),
MCoordinate.create2dWithMeasure(10.0, 0.0, 10.0),
MCoordinate.create2dWithMeasure(11.0, 0.0, 11.0),
};
MLineString line3 = mgeomFactory.createMLineString(coordinates2);
 
incrML = mgeomFactory.createMultiMLineString(new MLineString[]{line1, line2});
 
}
 
@Test
public void test_event_starts_at_end_of_component() throws MGeometryException {
MultiMLineString result = EventLocator.getLinearGeometry(incrML, 4.0, 5.5);
assertNotNull(result);
assertEquals(1, result.getNumGeometries());
assertEquals(2, result.getCoordinates().length);
Coordinate[] coordinates = result.getCoordinates();
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 5.0), (MCoordinate) coordinates[0]);
assertEquals(MCoordinate.create2dWithMeasure(5.5, 0.0, 5.5), (MCoordinate) coordinates[1]);
 
}
 
@Test
public void test_event_ends_at_begin_of_component() throws MGeometryException {
MultiMLineString result = EventLocator.getLinearGeometry(incrML, 3.0, 5.0);
assertNotNull(result);
assertEquals(1, result.getNumGeometries());
assertEquals(2, result.getCoordinates().length);
Coordinate[] coordinates = result.getCoordinates();
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0), (MCoordinate) coordinates[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), (MCoordinate) coordinates[1]);
}
 
 
@Test
public void test_event_ends_at_end_of_component() throws MGeometryException {
MultiMLineString result = EventLocator.getLinearGeometry(incrML, 4.5, 7.0);
assertNotNull(result);
assertEquals(1, result.getNumGeometries());
assertEquals(3, result.getCoordinates().length);
Coordinate[] coordinates = result.getCoordinates();
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 5.0), (MCoordinate) coordinates[0]);
assertEquals(MCoordinate.create2dWithMeasure(6.0, 0.0, 6.0), (MCoordinate) coordinates[1]);
assertEquals(MCoordinate.create2dWithMeasure(7.0, 0.0, 7.0), (MCoordinate) coordinates[2]);
}
 
@Test
public void test_locator_result_has_same_srid_as_input_mgeometry() throws MGeometryException {
incrML.setSRID(123);
MultiMLineString result = EventLocator.getLinearGeometry(incrML, 4.5, 7.0);
assertEquals(123, result.getSRID());
}
 
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/MultiMLineStringTest.java
New file
0,0 → 1,185
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.test.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.GeometryFactory;
import junit.framework.TestCase;
import org.hibernatespatial.mgeom.MCoordinate;
import org.hibernatespatial.mgeom.MCoordinateSequenceFactory;
import org.hibernatespatial.mgeom.MLineString;
import org.hibernatespatial.mgeom.MultiMLineString;
 
/**
* @author Karel Maesen
*/
public class MultiMLineStringTest extends TestCase {
 
private final MCoordinateSequenceFactory mcfactory = MCoordinateSequenceFactory
.instance();
 
private final GeometryFactory geomfactory = new GeometryFactory(mcfactory);
 
protected MLineString ml1;
 
protected MLineString ml2;
 
protected MultiMLineString mm1;
 
protected MultiMLineString mmsimple;
 
protected MCoordinate lastco;
 
public static void main(String[] args) {
junit.textui.TestRunner.run(MultiMLineStringTest.class);
}
 
/*
* @see TestCase#setUp()
*/
 
protected void setUp() throws Exception {
super.setUp();
 
MCoordinate mc0 = new MCoordinate(0.0, 0.0, 0.0, 0.0);
MCoordinate mc1 = new MCoordinate(1.0, 0.0, 0.0, 0.1);
MCoordinate mc2 = new MCoordinate(1.0, 1.0, 0.0, 0.2);
MCoordinate mc3 = new MCoordinate(5.0, 1.0, 0.0, 0.3);
MCoordinate mc4 = new MCoordinate(5.0, 3.0, 0.0, 0.4);
lastco = mc4;
 
MCoordinate[] m1 = {mc0, mc1, mc2};
MCoordinate[] m2 = {mc3, mc4};
 
CoordinateSequence mseq1 = mcfactory.create(m1);
ml1 = new MLineString(mseq1, geomfactory);
 
CoordinateSequence mseq2 = mcfactory.create(m2);
ml2 = new MLineString(mseq2, geomfactory);
 
mmsimple = new MultiMLineString(new MLineString[]{ml1}, 0.1,
geomfactory);
mm1 = new MultiMLineString(new MLineString[]{ml1, ml2}, 0.1,
geomfactory);
 
}
 
/*
* @see TestCase#tearDown()
*/
 
protected void tearDown() throws Exception {
super.tearDown();
}
 
public void testMaxM() {
assertEquals(0.4, mm1.getMaxM(), 0.000001);
}
 
/*
* Class under testsuite-suite for java.lang.String getGeometryType()
*/
 
public void testGetGeometryType() {
assertTrue("wrong type reported", mm1.getGeometryType()
.equalsIgnoreCase("multimlinestring"));
}
 
public void testGetDimension() {
// TODO Implement getDimension().
}
 
public void testGetBoundary() {
// TODO Implement getBoundary().
}
 
public void testGetBoundaryDimension() {
// TODO Implement getBoundaryDimension().
}
 
/*
* Class under testsuite-suite for boolean
* equalsExact(com.vividsolutions.jts.geom.Geometry, double)
*/
 
public void testEqualsExactGeometrydouble() {
// TODO Implement equalsExact().
}
 
/*
* Class under testsuite-suite for void
* MultiLineString(com.vividsolutions.jts.geom.LineString[],
* com.vividsolutions.jts.geom.PrecisionModel, int)
*/
 
public void testMultiLineStringLineStringArrayPrecisionModelint() {
// TODO Implement MultiLineString().
}
 
/*
* Class under testsuite-suite for void
* MultiLineString(com.vividsolutions.jts.geom.LineString[],
* com.vividsolutions.jts.geom.GeometryFactory)
*/
 
public void testMultiLineStringLineStringArrayGeometryFactory() {
// TODO Implement MultiLineString().
}
 
public void testIsClosed() {
// TODO Implement isClosed().
}
 
public void testClone() {
// TODO implement
 
}
 
public void testInterpolate() {
mm1.measureOnLength(false);
Coordinate[] ca = mm1.getCoordinates();
assertTrue("co 0 not OK", ((MCoordinate) ca[0]).m == 0.0);
assertTrue("co 1 not OK",
Math.abs(((MCoordinate) ca[1]).m - 1.0) < 0.00001);
assertTrue("co 2 not OK",
Math.abs(((MCoordinate) ca[2]).m - 2.0) < 0.00001);
assertTrue("co 3 not OK", Math.abs(((MCoordinate) ca[3]).m
- (2.0 + mm1.getMGap())) < 0.00001);
assertTrue("co 4 not OK", Math.abs(((MCoordinate) ca[4]).m
- (4.0 + mm1.getMGap())) < 0.00001);
 
double dist = mm1.getLength();
dist += (mm1.getNumGeometries() - 1) * mm1.getMGap();
assertTrue("interpolation not consistent with distance", Math
.abs(((MCoordinate) ca[4]).m - dist) < 0.00001);
 
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/MLineStringTest.java
New file
0,0 → 1,714
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.test.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.CoordinateSequenceComparator;
import com.vividsolutions.jts.geom.PrecisionModel;
import junit.framework.TestCase;
import org.hibernatespatial.mgeom.*;
 
/**
* @author Karel Maesen
*/
public class MLineStringTest extends TestCase {
 
private PrecisionModel prec = new PrecisionModel(PrecisionModel.FIXED);
 
private MGeometryFactory mgeomFactory = new MGeometryFactory(
MCoordinateSequenceFactory.instance());
 
private MLineString controlledLine;
 
private MLineString arbitraryLine;
 
private MLineString nullLine;
 
private MLineString ringLine;
 
public static void main(String[] args) {
junit.textui.TestRunner.run(MLineStringTest.class);
}
 
/*
* @see TestCase#setUp()
*/
 
protected void setUp() throws Exception {
super.setUp();
MCoordinate mc0 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
MCoordinate mc1 = MCoordinate.create2dWithMeasure(1.0, 0.0, 0.0);
MCoordinate mc2 = MCoordinate.create2dWithMeasure(1.0, 1.0, 0.0);
MCoordinate mc3 = MCoordinate.create2dWithMeasure(2.0, 1.0, 0.0);
 
MCoordinate[] mcoar = new MCoordinate[]{mc0, mc1, mc2, mc3};
controlledLine = mgeomFactory.createMLineString(mcoar);
 
mc0 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
mc1 = MCoordinate.create2dWithMeasure(1.0, 0.0, 0.0);
mc2 = MCoordinate.create2dWithMeasure(1.0, 1.0, 0.0);
mc3 = MCoordinate.create2dWithMeasure(0.0, 1.0, 0.0);
MCoordinate mc4 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
 
mcoar = new MCoordinate[]{mc0, mc1, mc2, mc3, mc4};
ringLine = mgeomFactory.createMLineString(mcoar);
 
int l = (int) Math.round(Math.random() * 250.0);
l = Math.max(2, l);
System.out.println("Size of arbitraryline ==" + l);
mcoar = new MCoordinate[l];
for (int i = 0; i < mcoar.length; i++) {
double x = Math.random() * 100000.0;
double y = Math.random() * 100000.0;
double z = Double.NaN; // JTS doesn't support operations on the
// z-coordinate value
double m = Math.random() * 100000.0;
mcoar[i] = new MCoordinate(x, y, z, m);
}
arbitraryLine = mgeomFactory.createMLineString(mcoar);
 
mcoar = new MCoordinate[0];
nullLine = mgeomFactory.createMLineString(mcoar);
}
 
/*
* @see TestCase#tearDown()
*/
 
protected void tearDown() throws Exception {
super.tearDown();
}
 
/**
* Constructor for MLineStringTest.
*
* @param name
*/
public MLineStringTest(String name) {
super(name);
}
 
//
// public void testMLineString() {
 
// }
 
/*
* Class under testsuite-suite for Object clone()
*/
 
public void testClone() {
MLineString mltest = (MLineString) arbitraryLine.clone();
 
Coordinate[] testco = mltest.getCoordinates();
Coordinate[] arco = arbitraryLine.getCoordinates();
assertEquals(testco.length, arco.length);
for (int i = 0; i < arco.length; i++) {
// clones must have equal, but not identical coordinates
assertEquals(arco[i], testco[i]);
assertNotSame(arco[i], testco[i]);
}
 
mltest = (MLineString) nullLine.clone();
assertEquals(mltest.isEmpty(), nullLine.isEmpty());
assertTrue(mltest.isEmpty());
 
}
 
public void testGetClosestPoint() {
 
try {
if (!arbitraryLine.isMonotone(false)) {
Coordinate mc = arbitraryLine.getClosestPoint(new Coordinate(
1.0, 2.0), 0.1);
assertTrue(false); // should never evaluate this
}
} catch (Exception e) {
assertTrue(((MGeometryException) e).getType() == MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
 
try {
// check reaction on null string
MCoordinate mc = nullLine.getClosestPoint(new Coordinate(0.0, 1.0),
1.0);
assertNull(mc);
 
// must return the very same coordinate if the coordinate is a
// coordinate of the line
arbitraryLine.measureOnLength(false);
int selp = (int) (arbitraryLine.getNumPoints() / 2);
MCoordinate mcexp = (MCoordinate) arbitraryLine
.getCoordinateN(selp);
MCoordinate mctest = arbitraryLine.getClosestPoint(mcexp, 1);
assertEquals(mcexp, mctest);
 
// must not return a point that is beyond the tolerance
mctest = controlledLine.getClosestPoint(
new Coordinate(20.0, 20, 0), 1.0);
assertNull(mctest);
 
// check for cases of circular MGeometry: lowest measure should be
// return.
ringLine.measureOnLength(false);
assertTrue(ringLine.isRing());
assertTrue(ringLine.isMonotone(false));
assertTrue(ringLine.getMeasureDirection() == MGeometry.INCREASING);
MCoordinate expCo = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
MCoordinate testCo = ringLine.getClosestPoint(expCo, 0.1);
assertTrue(DoubleComparator.equals(testCo.m, expCo.m));
ringLine.reverseMeasures();
testCo = ringLine.getClosestPoint(expCo, 0.1);
assertTrue(DoubleComparator.equals(testCo.m, expCo.m));
ringLine.measureOnLength(false);
int n = ringLine.getNumPoints() - 1;
ringLine.setMeasureAtIndex(n, 100.0);
ringLine.setMeasureAtIndex(0, 0.0);
testCo = ringLine.getClosestPoint(expCo, 0.001);
assertTrue(DoubleComparator.equals(testCo.m, 0.0));
 
// get two neighbouring points along the arbitraryline
arbitraryLine.measureOnLength(false);
int elem1Indx = (int) (Math.random() * (arbitraryLine
.getNumPoints() - 1));
int elem2Indx = 0;
if (elem1Indx == arbitraryLine.getNumPoints() - 1) {
elem2Indx = elem1Indx - 1;
} else {
elem2Indx = elem1Indx + 1;
}
// testsuite-suite whether a coordinate between these two returns exactly
MCoordinate mco1 = (MCoordinate) arbitraryLine
.getCoordinateN(elem1Indx);
MCoordinate mco2 = (MCoordinate) arbitraryLine
.getCoordinateN(elem2Indx);
double d = mco1.distance(mco2);
double offset = Math.random();
mcexp = MCoordinate.create2dWithMeasure(mco1.x + offset
* (mco2.x - mco1.x), mco1.y + offset * (mco2.y - mco1.y),
0.0);
mctest = arbitraryLine.getClosestPoint(mcexp, d);
mcexp.m = mco1.m + offset * (mco2.m - mco1.m);
assertEquals(mcexp.x, mctest.x, 0.001);
assertEquals(mcexp.y, mctest.y, 0.001);
assertEquals(mcexp.z, mctest.z, 0.001);
double delta = Math.random();
 
MCoordinate mcin = MCoordinate.create2dWithMeasure(mco1.x + offset
* (mco2.x - mco1.x) + delta, mco1.y + offset
* (mco2.y - mco1.y) + delta, 0.0);
 
// returned point is on the line
mctest = arbitraryLine.getClosestPoint(mcin, d);
assertEquals(mcin.x, mctest.x, delta * Math.sqrt(2));
assertEquals(mcin.y, mctest.y, delta * Math.sqrt(2));
} catch (Exception e) {
e.printStackTrace();
assertTrue(false); // should never reach this point
}
 
}
 
public void testGetCoordinateAtM() {
// what if null string
try {
Coordinate mc = nullLine.getCoordinateAtM(2);
assertNull(mc);
 
// get two neighbouring points along the arbitraryline
arbitraryLine.measureOnLength(false);
int elem1Indx = (int) (Math.random() * (arbitraryLine
.getNumPoints() - 1));
int elem2Indx = 0;
if (elem1Indx == arbitraryLine.getNumPoints() - 1) {
elem2Indx = elem1Indx - 1;
} else {
elem2Indx = elem1Indx + 1;
}
 
// if m is value of a coordinate, the returned coordinate should
// equal that coordinate
 
MCoordinate mco1 = (MCoordinate) arbitraryLine
.getCoordinateN(elem1Indx);
MCoordinate mcotest = (MCoordinate) arbitraryLine
.getCoordinateAtM(mco1.m);
assertNotSame(mco1, mcotest);
assertEquals(mco1.x, mcotest.x, Math.ulp(100 * mco1.x));
assertEquals(mco1.y, mcotest.y, Math.ulp(100 * mco1.y));
assertEquals(mco1.m, mcotest.m, Math.ulp(100 * mco1.m));
 
MCoordinate mco2 = (MCoordinate) arbitraryLine
.getCoordinateN(elem2Indx);
double offset = Math.random();
double newM = mco1.m + offset * (mco2.m - mco1.m);
MCoordinate mcexp = new MCoordinate(mco1.x + offset
* (mco2.x - mco1.x), mco1.y + offset * (mco2.y - mco1.y),
Double.NaN, mco1.m + offset * (mco2.m - mco1.m));
MCoordinate mctest = (MCoordinate) arbitraryLine
.getCoordinateAtM(newM);
assertEquals(mcexp.x, mctest.x, 0.0001);
assertEquals(mcexp.y, mctest.y, 0.0001);
assertEquals(mcexp.m, mctest.m, 0.0001);
 
} catch (Exception e) {
System.err.println(e);
}
}
 
/*
* Class under testsuite-suite for String getGeometryType()
*/
 
public void testGetGeometryType() {
assertEquals("MLineString", arbitraryLine.getGeometryType());
}
 
public void testGetMatCoordinate() {
try {
// what in case of the null string
assertTrue(Double.isNaN(nullLine.getMatCoordinate(new Coordinate(
1.0, 1.0), 1.0)));
 
// get two neighbouring points along the arbitraryline
arbitraryLine.measureOnLength(false);
int elem1Indx = (int) (Math.random() * (arbitraryLine
.getNumPoints() - 1));
int elem2Indx = 0;
if (elem1Indx == arbitraryLine.getNumPoints() - 1) {
elem2Indx = elem1Indx - 1;
} else {
elem2Indx = elem1Indx + 1;
}
 
// if a coordinate of the geometry is passed, it should return
// exactly that m-value
MCoordinate mco1 = (MCoordinate) arbitraryLine
.getCoordinateN(elem1Indx);
double m = arbitraryLine.getMatCoordinate(mco1, 0.00001);
assertEquals(mco1.m, m, DoubleComparator
.defaultNumericalPrecision());
 
// check for a coordinate between mco1 and mco2 (neighbouring
// coordinates)
MCoordinate mco2 = (MCoordinate) arbitraryLine
.getCoordinateN(elem2Indx);
double offset = Math.random();
double expectedM = mco1.m + offset * (mco2.m - mco1.m);
Coordinate mctest = new Coordinate(mco1.x + offset
* (mco2.x - mco1.x), mco1.y + offset * (mco2.y - mco1.y));
 
double testM = arbitraryLine.getMatCoordinate(mctest, offset);
assertEquals(expectedM, testM, DoubleComparator
.defaultNumericalPrecision());
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);// should never reach here
}
}
 
public void testGetMatN() {
// Implement getMatN().
}
 
public void testGetMaxM() {
// Implement getMaxM().
}
 
public void testGetCoordinatesBetween() {
 
try {
// what if the null value is passed
CoordinateSequence[] cs = nullLine.getCoordinatesBetween(0.0, 5.0);
assertTrue("cs.length = " + cs.length + ". Should be 1", cs.length == 1);
assertEquals(cs[0].size(), 0);
 
arbitraryLine.measureOnLength(false);
// what if from/to is outside of the range of values
double maxM = arbitraryLine.getMaxM();
cs = arbitraryLine.getCoordinatesBetween(maxM + 1.0, maxM + 10.0);
 
// check for several ascending M-values
int minIdx = (int) (Math.random() * (arbitraryLine.getNumPoints() - 1));
int maxIdx = Math.min((arbitraryLine.getNumPoints() - 1),
minIdx + 10);
double minM = ((MCoordinate) arbitraryLine.getCoordinateN(minIdx)).m;
maxM = ((MCoordinate) arbitraryLine.getCoordinateN(maxIdx)).m;
cs = arbitraryLine.getCoordinatesBetween(minM, maxM);
assertNotNull(cs);
assertTrue(cs.length > 0);
Coordinate[] coar = cs[0].toCoordinateArray();
int j = 0;
for (int i = minIdx; i <= maxIdx; i++) {
assertEquals((MCoordinate) arbitraryLine.getCoordinateN(i),
coar[j]);
j++;
}
 
minM = Math.max(0.0, minM - Math.random() * 10);
cs = arbitraryLine.getCoordinatesBetween(minM, maxM);
coar = cs[0].toCoordinateArray();
MCoordinate mctest = (MCoordinate) coar[0];
MCoordinate mcexp = (MCoordinate) arbitraryLine
.getCoordinateAtM(minM);
assertEquals(mcexp, mctest);
assertEquals(mctest.m, minM, DoubleComparator
.defaultNumericalPrecision());
 
maxM = Math.min(arbitraryLine.getLength(), maxM + Math.random()
* 10);
cs = arbitraryLine.getCoordinatesBetween(minM, maxM);
coar = cs[0].toCoordinateArray();
mctest = (MCoordinate) coar[coar.length - 1];
mcexp = (MCoordinate) arbitraryLine.getCoordinateAtM(maxM);
assertEquals(mcexp.x, mctest.x, Math.ulp(mcexp.x) * 100);
assertEquals(mcexp.y, mctest.y, Math.ulp(mcexp.y) * 100);
assertEquals(mctest.m, maxM, DoubleComparator
.defaultNumericalPrecision());
 
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);// should never reach here
 
}
}
 
public void testGetMeasureDirection() {
assertTrue(nullLine.isMonotone(false));
 
assertTrue(arbitraryLine.isMonotone(false)
|| (!arbitraryLine.isMonotone(false) && arbitraryLine
.getMeasureDirection() == MGeometry.NON_MONOTONE));
arbitraryLine.measureOnLength(false);
assertEquals(MGeometry.INCREASING, arbitraryLine.getMeasureDirection());
 
arbitraryLine.reverseMeasures();
assertEquals(MGeometry.DECREASING, arbitraryLine.getMeasureDirection());
 
for (int i = 0; i < arbitraryLine.getNumPoints(); i++) {
arbitraryLine.setMeasureAtIndex(i, 0.0);
}
assertEquals(MGeometry.CONSTANT, arbitraryLine.getMeasureDirection());
}
 
public void testGetMeasures() {
 
}
 
public void testGetMinM() {
 
}
 
public void testInterpolate() {
MCoordinate mc0NaN = MCoordinate.create2d(0.0, 0.0);
MCoordinate mc0 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
MCoordinate mc2NaN = MCoordinate.create2d(2.0, 0.0);
MCoordinate mc5NaN = MCoordinate.create2d(5.0, 0.0);
MCoordinate mc10NaN = MCoordinate.create2d(10.0, 0.0);
MCoordinate mc10 = MCoordinate.create2dWithMeasure(10.0, 0.0, 10.0);
 
// Internal coordinate measures are not defined, outer measures are
// 0-10, total 2d length is 10
MLineString line = mgeomFactory.createMLineString(new MCoordinate[]{
mc0, mc2NaN, mc5NaN, mc10});
MLineString lineBeginNaN = mgeomFactory
.createMLineString(new MCoordinate[]{mc0NaN, mc2NaN, mc5NaN,
mc10});
MLineString lineEndNaN = mgeomFactory
.createMLineString(new MCoordinate[]{mc0, mc2NaN, mc5NaN,
mc10NaN});
 
assertTrue(DoubleComparator.equals(line.getLength(), 10));
assertTrue(DoubleComparator.equals(lineBeginNaN.getLength(), 10));
assertTrue(DoubleComparator.equals(lineEndNaN.getLength(), 10));
 
line.interpolate(mc0.m, mc10.m);
lineBeginNaN.interpolate(mc0.m, mc10.m);
lineEndNaN.interpolate(mc0.m, mc10.m);
 
assertTrue(line.isMonotone(false));
assertTrue(line.isMonotone(true));
assertTrue(lineBeginNaN.isMonotone(false));
assertTrue(lineBeginNaN.isMonotone(true));
assertTrue(lineEndNaN.isMonotone(false));
assertTrue(lineEndNaN.isMonotone(true));
 
double[] expectedM = new double[]{mc0.m, 2.0, 5.0, mc10.m};
for (int i = 0; i < expectedM.length; i++) {
double actualMLine = line.getCoordinateSequence().getOrdinate(i,
CoordinateSequence.M);
double actualBeginNaN = lineBeginNaN.getCoordinateSequence()
.getOrdinate(i, CoordinateSequence.M);
double actualEndNaN = lineEndNaN.getCoordinateSequence()
.getOrdinate(i, CoordinateSequence.M);
assertTrue(DoubleComparator.equals(expectedM[i], actualMLine));
assertTrue(DoubleComparator.equals(expectedM[i], actualBeginNaN));
assertTrue(DoubleComparator.equals(expectedM[i], actualEndNaN));
}
 
// Test Continuous case by interpolating with begin and end measures
// equal
double continuousMeasure = 0.0D;
line.interpolate(continuousMeasure, continuousMeasure);
double[] measures = line.getMeasures();
for (int i = 0; i < measures.length; i++)
assertTrue(DoubleComparator.equals(measures[i], continuousMeasure));
}
 
public void testIsMonotone() {
MCoordinate mc0NaN = MCoordinate.create2d(1.0, 0.0);
MCoordinate mc0 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
MCoordinate mc1NaN = MCoordinate.create2d(1.0, 0.0);
MCoordinate mc1 = MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0);
MCoordinate mc2NaN = MCoordinate.create2d(2.0, 0.0);
MCoordinate mc2 = MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0);
MCoordinate mc3NaN = MCoordinate.create2d(3.0, 0.0);
MCoordinate mc3 = MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0);
 
MLineString emptyLine = mgeomFactory
.createMLineString(new MCoordinate[]{});
MLineString orderedLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc0, mc1, mc2, mc3});
MLineString unorderedLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc0, mc2, mc1, mc3});
MLineString constantLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc2, mc2, mc2, mc2});
MLineString reverseOrderedLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc3, mc2, mc1, mc0});
MLineString reverseUnOrderedLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc3, mc1, mc2, mc0});
MLineString dupCoordLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc0, mc1, mc1, mc2});
MLineString reverseDupCoordLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc2, mc1, mc1, mc0});
 
assertTrue(emptyLine.isMonotone(false));
assertTrue(emptyLine.isMonotone(true));
 
assertTrue(orderedLine.isMonotone(false));
assertTrue(orderedLine.isMonotone(true));
// testsuite-suite reversing the ordered line
orderedLine.reverseMeasures();
assertTrue(orderedLine.isMonotone(false));
assertTrue(orderedLine.isMonotone(true));
// testsuite-suite shifting
orderedLine.shiftMeasure(1.0);
assertTrue(orderedLine.isMonotone(false));
assertTrue(orderedLine.isMonotone(true));
orderedLine.shiftMeasure(-1.0);
assertTrue(orderedLine.isMonotone(false));
assertTrue(orderedLine.isMonotone(true));
 
assertFalse(unorderedLine.isMonotone(false));
assertFalse(unorderedLine.isMonotone(true));
 
assertTrue(constantLine.isMonotone(false));
assertFalse(constantLine.isMonotone(true));
// testsuite-suite shifting
constantLine.shiftMeasure(1.0);
assertTrue(constantLine.isMonotone(false));
assertFalse(constantLine.isMonotone(true));
constantLine.shiftMeasure(-1.0);
assertTrue(constantLine.isMonotone(false));
assertFalse(constantLine.isMonotone(true));
 
assertTrue(reverseOrderedLine.isMonotone(false));
assertTrue(reverseOrderedLine.isMonotone(true));
// testsuite-suite reversing the line
reverseOrderedLine.reverseMeasures();
assertTrue(reverseOrderedLine.isMonotone(false));
assertTrue(reverseOrderedLine.isMonotone(true));
// testsuite-suite shifting
reverseOrderedLine.shiftMeasure(1.0);
assertTrue(reverseOrderedLine.isMonotone(false));
assertTrue(reverseOrderedLine.isMonotone(true));
reverseOrderedLine.shiftMeasure(-1.0);
assertTrue(reverseOrderedLine.isMonotone(false));
assertTrue(reverseOrderedLine.isMonotone(true));
 
assertFalse(reverseUnOrderedLine.isMonotone(false));
assertFalse(reverseUnOrderedLine.isMonotone(true));
 
assertTrue(dupCoordLine.isMonotone(false));
assertFalse(dupCoordLine.isMonotone(true));
// testsuite-suite shifting
dupCoordLine.shiftMeasure(1.0);
assertTrue(dupCoordLine.isMonotone(false));
assertFalse(dupCoordLine.isMonotone(true));
dupCoordLine.shiftMeasure(-1.0);
assertTrue(dupCoordLine.isMonotone(false));
assertFalse(dupCoordLine.isMonotone(true));
 
assertTrue(reverseDupCoordLine.isMonotone(false));
assertFalse(reverseDupCoordLine.isMonotone(true));
// testsuite-suite shifting
reverseDupCoordLine.shiftMeasure(1.0);
assertTrue(reverseDupCoordLine.isMonotone(false));
assertFalse(reverseDupCoordLine.isMonotone(true));
reverseDupCoordLine.shiftMeasure(-1.0);
assertTrue(reverseDupCoordLine.isMonotone(false));
assertFalse(reverseDupCoordLine.isMonotone(true));
 
assertEquals(orderedLine.getMeasureDirection(), MGeometry.INCREASING);
assertEquals(unorderedLine.getMeasureDirection(),
MGeometry.NON_MONOTONE);
assertEquals(reverseOrderedLine.getMeasureDirection(),
MGeometry.DECREASING);
assertEquals(dupCoordLine.getMeasureDirection(), MGeometry.INCREASING);
assertEquals(reverseDupCoordLine.getMeasureDirection(),
MGeometry.DECREASING);
 
// Test scenario where there are NaN middle measures
MLineString internalNaNLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc0, mc1NaN, mc2NaN, mc3});
MLineString beginNaNLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc0NaN, mc2, mc3});
MLineString endNaNLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc0, mc2, mc3NaN});
MLineString beginEndNaNLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc0NaN, mc2, mc3NaN});
 
assertFalse(internalNaNLine.isMonotone(false));
assertFalse(internalNaNLine.isMonotone(true));
internalNaNLine.measureOnLength(false);
assertTrue(internalNaNLine.isMonotone(false));
assertTrue(internalNaNLine.isMonotone(true));
 
assertFalse(beginNaNLine.isMonotone(false));
assertFalse(beginNaNLine.isMonotone(true));
beginNaNLine.measureOnLength(false);
assertTrue(beginNaNLine.isMonotone(false));
assertTrue(beginNaNLine.isMonotone(true));
 
assertFalse(endNaNLine.isMonotone(false));
assertFalse(endNaNLine.isMonotone(true));
endNaNLine.measureOnLength(false);
assertTrue(endNaNLine.isMonotone(false));
assertTrue(endNaNLine.isMonotone(true));
 
assertFalse(beginEndNaNLine.isMonotone(false));
assertFalse(beginEndNaNLine.isMonotone(true));
beginEndNaNLine.measureOnLength(false);
assertTrue(beginEndNaNLine.isMonotone(false));
assertTrue(beginEndNaNLine.isMonotone(true));
}
 
public void testGetCoordinatesBetweenNonStrict() {
try {
CoordinateSequenceComparator coordCompare = new CoordinateSequenceComparator();
MCoordinate mc0 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0);
MCoordinate mc1 = MCoordinate.create2dWithMeasure(0.0, 1.0, 1);
MCoordinate mc2_1 = MCoordinate.create2dWithMeasure(0.0, 2.0, 1);
MCoordinate mc2 = MCoordinate.create2dWithMeasure(0.0, 2.0, 2);
MCoordinate mc3 = MCoordinate.create2dWithMeasure(0.0, 3.0, 3);
MCoordinate mc4 = MCoordinate.create2dWithMeasure(0.0, 4.0, 4);
 
// Test non-strict sequence where all coordinate x,y positions are
// unique, but contains a
// duplicate measure. The measure sequence in this testsuite-suite s
// [0,1,1,3,4]
MLineString nonStrictPointLine = mgeomFactory
.createMLineString(new MCoordinate[]{mc0, mc1, mc2_1,
mc3, mc4});
CoordinateSequence[] nonStrictSeq = nonStrictPointLine
.getCoordinatesBetween(mc0.m, mc2_1.m);
assertNotNull(nonStrictSeq);
 
nonStrictSeq = nonStrictPointLine.getCoordinatesBetween(mc0.m,
mc4.m);
assertNotNull(nonStrictSeq);
 
nonStrictSeq = nonStrictPointLine.getCoordinatesBetween(mc1.m,
mc4.m);
assertNotNull(nonStrictSeq);
 
nonStrictSeq = nonStrictPointLine
.getCoordinatesBetween(1.1D, mc4.m);
assertNotNull(nonStrictSeq);
 
} catch (MGeometryException e) {
e.printStackTrace();
}
}
 
public void testmeasureOnLength() {
arbitraryLine.measureOnLength(false);
double maxM = arbitraryLine.getMaxM();
double minM = arbitraryLine.getMinM();
assertEquals(maxM, arbitraryLine.getLength(), DoubleComparator
.defaultNumericalPrecision());
assertEquals(minM, 0.0d, DoubleComparator.defaultNumericalPrecision());
MCoordinate mco = (MCoordinate) arbitraryLine
.getCoordinateN(arbitraryLine.getNumPoints() - 1);
assertEquals(mco.m, maxM, DoubleComparator.defaultNumericalPrecision());
mco = (MCoordinate) arbitraryLine.getCoordinateN(0);
assertEquals(mco.m, minM, DoubleComparator.defaultNumericalPrecision());
}
 
public void testReverseMeasures() {
 
nullLine.reverseMeasures();
 
arbitraryLine.measureOnLength(false);
arbitraryLine.reverseMeasures();
assertTrue(arbitraryLine.getMeasureDirection() == MGeometry.DECREASING);
double mlast = arbitraryLine.getMatN(arbitraryLine.getNumPoints() - 1);
arbitraryLine.reverseMeasures();
assertTrue(arbitraryLine.getMeasureDirection() == MGeometry.INCREASING);
double mfirst = arbitraryLine.getMatN(0);
assertEquals(mlast, mfirst, DoubleComparator
.defaultNumericalPrecision());
 
}
 
public void testSetMatN() {
// TODO Implement setMeasureAtIndex().
}
 
public void testShiftMBy() {
// TODO Implement shiftMeasure().
}
 
/*
* Class under testsuite-suite for String toString()
*/
 
public void testToString() {
// TODO Implement toString().
}
 
public void testUnionM() {
// TODO Implement unionM().
}
 
public void testVerifyMonotone() {
// TODO Implement verifyMonotone().
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/GeometryEquality.java
New file
0,0 → 1,96
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import org.hibernatespatial.mgeom.MCoordinate;
 
/**
* This class tests for the equality between geometries.
* <p/>
* The notion of geometric equality can differ slightly between
* spatial databases.
*/
public class GeometryEquality {
 
public boolean test(Geometry geom1, Geometry geom2) {
if (geom1 == null) return geom2 == null;
if (geom1.isEmpty()) return geom2.isEmpty() && geom1.getSRID() == geom2.getSRID();
if (geom1 instanceof GeometryCollection) {
if (!(geom2 instanceof GeometryCollection)) return false;
GeometryCollection expectedCollection = (GeometryCollection) geom1;
GeometryCollection receivedCollection = (GeometryCollection) geom2;
for (int partIndex = 0; partIndex < expectedCollection.getNumGeometries(); partIndex++) {
Geometry partExpected = expectedCollection.getGeometryN(partIndex);
Geometry partReceived = receivedCollection.getGeometryN(partIndex);
if (!test(partExpected, partReceived)) return false;
}
return true;
} else {
return testSimpleGeometryEquality(geom1, geom2);
}
}
 
/**
* Test whether two geometries, not of type GeometryCollection are equal.
*
* @param geom1
* @param geom2
* @return
*/
protected boolean testSimpleGeometryEquality(Geometry geom1, Geometry geom2) {
//return geom1.equals(geom2);
return testTypeAndVertexEquality(geom1, geom2) && geom1.getSRID() == geom2.getSRID();
}
 
protected boolean testTypeAndVertexEquality(Geometry geom1, Geometry geom2) {
if (!geom1.getGeometryType().equals(geom2.getGeometryType())) return false;
if (geom1.getNumGeometries() != geom2.getNumGeometries()) return false;
if (geom1.getNumPoints() != geom2.getNumPoints()) return false;
Coordinate[] coordinates1 = geom1.getCoordinates();
Coordinate[] coordinates2 = geom2.getCoordinates();
for (int i = 0; i < coordinates1.length; i++) {
Coordinate c1 = coordinates1[i];
Coordinate c2 = coordinates2[i];
if (!testCoordinateEquality(c1, c2)) return false;
}
return true;
}
 
private boolean testCoordinateEquality(Coordinate c1, Coordinate c2) {
if (c1 instanceof MCoordinate) {
if (!(c2 instanceof MCoordinate)) return false;
MCoordinate mc1 = (MCoordinate) c1;
MCoordinate mc2 = (MCoordinate) c2;
if (!Double.isNaN(mc1.m) && mc1.m != mc2.m) return false;
}
if (!Double.isNaN(c1.z) && c1.z != c2.z) return false;
return c1.x == c2.x && c1.y == c2.y;
}
}
 
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestData.java
New file
0,0 → 1,163
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
import java.io.InputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
 
/**
* A <code>TestData</code> instance is a list object
* that contains all the <code>TestDataElement</code>s that
* are used in a unit testsuite-suite suite.
*
* @author Karel Maesen, Geovise BVBA
*/
public class TestData implements List<TestDataElement> {
 
private List<TestDataElement> testDataElements;
private InputStream in;
 
protected TestData() {
}
 
;
 
public int size() {
return testDataElements.size();
}
 
public boolean isEmpty() {
return testDataElements.isEmpty();
}
 
public boolean contains(Object o) {
return testDataElements.contains(o);
}
 
public Iterator<TestDataElement> iterator() {
return testDataElements.iterator();
}
 
public Object[] toArray() {
return testDataElements.toArray();
}
 
public <T> T[] toArray(T[] a) {
return testDataElements.toArray(a);
}
 
public boolean add(TestDataElement testDataElement) {
return testDataElements.add(testDataElement);
}
 
public boolean remove(Object o) {
return testDataElements.remove(o);
}
 
public boolean containsAll(Collection<?> c) {
return testDataElements.containsAll(c);
}
 
public boolean addAll(Collection<? extends TestDataElement> c) {
return testDataElements.addAll(c);
}
 
public boolean addAll(int index, Collection<? extends TestDataElement> c) {
return testDataElements.addAll(index, c);
}
 
public boolean removeAll(Collection<?> c) {
return testDataElements.removeAll(c);
}
 
public boolean retainAll(Collection<?> c) {
return testDataElements.retainAll(c);
}
 
public void clear() {
testDataElements.clear();
}
 
public boolean equals(Object o) {
return testDataElements.equals(o);
}
 
public int hashCode() {
return testDataElements.hashCode();
}
 
public TestDataElement get(int index) {
return testDataElements.get(index);
}
 
public TestDataElement set(int index, TestDataElement element) {
return testDataElements.set(index, element);
}
 
public void add(int index, TestDataElement element) {
testDataElements.add(index, element);
}
 
public TestDataElement remove(int index) {
return testDataElements.remove(index);
}
 
public int indexOf(Object o) {
return testDataElements.indexOf(o);
}
 
public int lastIndexOf(Object o) {
return testDataElements.lastIndexOf(o);
}
 
public ListIterator<TestDataElement> listIterator() {
return testDataElements.listIterator();
}
 
public ListIterator<TestDataElement> listIterator(int index) {
return testDataElements.listIterator(index);
}
 
public List<TestDataElement> subList(int fromIndex, int toIndex) {
return testDataElements.subList(fromIndex, toIndex);
}
 
public static TestData fromFile(String fileName) {
TestDataReader reader = new TestDataReader();
return fromFile(fileName, reader);
}
 
public static TestData fromFile(String fileName, TestDataReader reader) {
List<TestDataElement> elements = reader.read(fileName);
TestData testData = new TestData();
testData.testDataElements = elements;
return testData;
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/DataSourceUtils.java
New file
0,0 → 1,343
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import org.apache.commons.dbcp.BasicDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import javax.sql.DataSource;
import java.io.*;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
 
/**
* <p>Unit testsuite-suite support class.</p>
*
* @author Karel Maesen, Geovise BVBA.
*/
public class DataSourceUtils {
 
 
private static Logger LOGGER = LoggerFactory.getLogger(DataSourceUtils.class);
 
 
private final SQLExpressionTemplate sqlExpressionTemplate;
private final String jdbcDriver;
private final String jdbcUrl;
private final String jdbcUser;
private final String jdbcPass;
 
private DataSource dataSource;
 
 
/**
* Constructor for the DataSourceUtils object.
* <p/>
* <p>The following entities are required in the property file:
* <il>
* <li> jdbcUrl: jdbc connection URL</li>
* <li> dbUsername: username for the database</li>
* <li> dbPassword: password for the database</li>
* <li> driver: fully-qualified class name for the JDBC Driver</li>
* </il>
*
* @param jdbcDriver
* @param jdbcUrl
* @param jdbcUser
* @param jdbcPass
* @param sqlExpressionTemplate SQLExpressionTemplate object that generates SQL statements for this database
*/
public DataSourceUtils(String jdbcDriver, String jdbcUrl, String jdbcUser, String jdbcPass, SQLExpressionTemplate sqlExpressionTemplate) {
this.jdbcDriver = jdbcDriver;
this.jdbcUrl = jdbcUrl;
this.jdbcUser = jdbcUser;
this.jdbcPass = jdbcPass;
this.sqlExpressionTemplate = sqlExpressionTemplate;
createBasicDataSource();
}
 
/**
* Constructor using a properties file
*
* @param propertyFile
* @param template
*/
public DataSourceUtils(String propertyFile, SQLExpressionTemplate template) {
Properties properties = readProperties(propertyFile);
this.jdbcUrl = properties.getProperty("jdbcUrl");
this.jdbcDriver = properties.getProperty("jdbcDriver");
this.jdbcUser = properties.getProperty("jdbcUser");
this.jdbcPass = properties.getProperty("jdbcPass");
this.sqlExpressionTemplate = template;
createBasicDataSource();
}
 
private Properties readProperties(String propertyFile) {
InputStream is = null;
try {
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(propertyFile);
if (is == null) throw new RuntimeException(String.format("File %s not found on classpath.", propertyFile));
Properties properties = new Properties();
properties.load(is);
return properties;
} catch (IOException e) {
throw (new RuntimeException(e));
} finally {
if (is != null) try {
is.close();
} catch (IOException e) {
//nothing to do
}
}
}
 
private void createBasicDataSource() {
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName(jdbcDriver);
bds.setUrl(jdbcUrl);
bds.setUsername(jdbcUser);
bds.setPassword(jdbcPass);
dataSource = bds;
}
 
 
/**
* Closes the connections to the database.
*
* @throws SQLException
*/
public void close() throws SQLException {
((BasicDataSource) dataSource).close();
}
 
/**
* Returns a DataSource for the configured database.
*
* @return a DataSource
*/
public DataSource getDataSource() {
return dataSource;
}
 
/**
* Returns a JDBC connection to the database
*
* @return a JDBC Connection object
* @throws SQLException
*/
public Connection getConnection() throws SQLException {
Connection cn = getDataSource().getConnection();
cn.setAutoCommit(false);
return cn;
}
 
/**
* Delete all testsuite-suite data from the database
*
* @throws SQLException
*/
public void deleteTestData() throws SQLException {
Connection cn = null;
try {
cn = getDataSource().getConnection();
cn.setAutoCommit(false);
PreparedStatement pmt = cn.prepareStatement("delete from GEOMTEST");
if (!pmt.execute()) {
int updateCount = pmt.getUpdateCount();
LOGGER.info("Removing " + updateCount + " rows.");
}
cn.commit();
pmt.close();
} finally {
try {
if (cn != null) cn.close();
} catch (SQLException e) {
// nothing to do
}
}
}
 
public void insertTestData(TestData testData) throws SQLException {
Connection cn = null;
try {
cn = getDataSource().getConnection();
cn.setAutoCommit(false);
Statement stmt = cn.createStatement();
for (TestDataElement testDataElement : testData) {
String sql = sqlExpressionTemplate.toInsertSql(testDataElement);
LOGGER.debug("adding stmt: " + sql);
stmt.addBatch(sql);
}
int[] insCounts = stmt.executeBatch();
cn.commit();
stmt.close();
LOGGER.info("Loaded " + sum(insCounts) + " rows.");
} finally {
try {
if (cn != null) cn.close();
} catch (SQLException e) {
// nothing to do
}
}
}
 
 
/**
* Parses the content of a file into an executable SQL statement.
*
* @param fileName name of a file containing SQL-statements
* @return
* @throws IOException
*/
public String parseSqlIn(String fileName) throws IOException {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
if (is == null) {
throw new RuntimeException("File " + fileName + " not found on Classpath.");
}
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
 
StringWriter sw = new StringWriter();
BufferedWriter writer = new BufferedWriter(sw);
 
for (int c = reader.read(); c != -1; c = reader.read()) {
writer.write(c);
}
writer.flush();
return sw.toString();
} finally {
if (is != null) {
is.close();
}
}
}
 
/**
* Executes a SQL statement.
* <p/>
* This is used e.g. to drop/create a spatial index, or update the
* geometry metadata statements.
*
* @param sql the (native) SQL Statement to execute
* @throws SQLException
*/
public void executeStatement(String sql) throws SQLException {
Connection cn = null;
try {
cn = getDataSource().getConnection();
cn.setAutoCommit(false);
PreparedStatement statement = cn.prepareStatement(sql);
LOGGER.info("Executing statement: " + sql);
statement.execute();
cn.commit();
statement.close();
} finally {
try {
if (cn != null) cn.close();
} catch (SQLException e) {
} //do nothing.
}
}
 
/**
* Operations to fully initialize the
*/
public void afterCreateSchema() {
 
}
 
/**
* Return the geometries of the testsuite-suite objects as raw (i.e. undecoded) objects from the database.
*
* @param type type of geometry
* @return map of identifier, undecoded geometry object
*/
public Map<Integer, Object> rawDbObjects(String type) {
Map<Integer, Object> map = new HashMap<Integer, Object>();
Connection cn = null;
try {
cn = getDataSource().getConnection();
PreparedStatement pstmt = cn.prepareStatement("select id, geom from geomtest where type = ? order by id");
pstmt.setString(1, type);
ResultSet results = pstmt.executeQuery();
while (results.next()) {
Integer id = results.getInt(1);
Object obj = results.getObject(2);
map.put(id, obj);
}
 
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (cn != null) cn.close();
} catch (SQLException e) {
// nothing we can do.
}
}
return map;
 
}
 
/**
* Returns the JTS geometries that are expected of a decoding of the testsuite-suite object's geometry.
* <p/>
* <p>This method reads the WKT of the testsuite-suite objects and returns the result.</p>
*
* @param type type of geometry
* @return map of identifier and JTS geometry
*/
public Map<Integer, Geometry> expectedGeoms(String type, TestData testData) {
Map<Integer, Geometry> result = new HashMap<Integer, Geometry>();
EWKTReader parser = new EWKTReader();
for (TestDataElement testDataElement : testData) {
if (testDataElement.type.equalsIgnoreCase(type)) {
try {
result.put(testDataElement.id, parser.read(testDataElement.wkt));
} catch (ParseException e) {
System.out.println(String.format("Parsing WKT fails for case %d : %s", testDataElement.id, testDataElement.wkt));
throw new RuntimeException(e);
}
}
}
return result;
}
 
private static int sum(int[] insCounts) {
int result = 0;
for (int idx = 0; idx < insCounts.length; idx++) {
result += insCounts[idx];
}
return result;
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/NativeSQLStatement.java
New file
0,0 → 1,49
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
 
/**
* <code>NativeSQLStatement</code>s can instantiate a
* database-specific <code>PreparedStatement</code> for
* some database query or operation.
*
* @author Karel Maesen, Geovise BVBA
*/
public interface NativeSQLStatement {
 
/**
* create a PreparedStatement from the specified connection
*
* @param connection Connection to the database.
* @return
* @throws SQLException
*/
public PreparedStatement prepare(Connection connection) throws SQLException;
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/SQLExpressionTemplate.java
New file
0,0 → 1,44
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
/**
* <code>SQLExpressoinTemplate</code>s generate database-specific
* SQL statements for a given <code>TestDataElement</code> instance.
*
* @author Karel Maesen, Geovise BVBA
*/
public interface SQLExpressionTemplate {
 
/**
* Returns an insert SQL statement for the specified <code>TestDataElement</code>
*
* @param testDataElement
* @return an insert SQL for testDataElement
*/
public String toInsertSql(TestDataElement testDataElement);
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestFeature.java
New file
0,0 → 1,22
package org.hibernatespatial.test;
 
import com.vividsolutions.jts.geom.Geometry;
 
/**
* Interface for persistent entities in
* integration tests.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: Oct 2, 2010
*/
public interface TestFeature {
 
public Integer getId();
 
public void setId(Integer id);
 
public Geometry getGeom();
 
public void setGeom(Geometry geom);
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestDataReader.java
New file
0,0 → 1,75
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test;
 
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
 
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
public class TestDataReader {
 
public List<TestDataElement> read(String fileName) {
if (fileName == null) throw new RuntimeException("Null testsuite-suite data file specified.");
List<TestDataElement> testDataElements = new ArrayList<TestDataElement>();
SAXReader reader = new SAXReader();
try {
Document document = reader.read(getInputStream(fileName));
addDataElements(document, testDataElements);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
return testDataElements;
}
 
protected void addDataElements(Document document, List<TestDataElement> testDataElements) {
Element root = document.getRootElement();
for (Iterator it = root.elementIterator(); it.hasNext();) {
Element element = (Element) it.next();
addDataElement(element, testDataElements);
}
}
 
protected void addDataElement(Element element, List<TestDataElement> testDataElements) {
int id = Integer.valueOf(element.selectSingleNode("id").getText());
String type = element.selectSingleNode("type").getText();
String wkt = element.selectSingleNode("wkt").getText();
int srid = Integer.valueOf(element.selectSingleNode("srid").getText());
TestDataElement testDataElement = new TestDataElement(id, type, wkt, srid);
testDataElements.add(testDataElement);
}
 
protected InputStream getInputStream(String fileName) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
if (is == null) throw new RuntimeException(String.format("File %s not found on classpath.", fileName));
return is;
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestSupport.java
New file
0,0 → 1,45
package org.hibernatespatial.test;
 
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
 
 
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Sep 30, 2010
*/
public abstract class TestSupport {
 
protected Configuration configuration;
 
public DataSourceUtils createDataSourceUtil(Configuration configuration) {
this.configuration = configuration;
return new DataSourceUtils(driver(), url(), user(), passwd(), getSQLExpressionTemplate());
}
 
public GeometryEquality createGeometryEquality() {
return new GeometryEquality();
}
 
public abstract TestData createTestData(FunctionalTestCase testcase);
 
public abstract AbstractExpectationsFactory createExpectationsFactory(DataSourceUtils dataSourceUtils);
 
public abstract SQLExpressionTemplate getSQLExpressionTemplate();
 
protected String driver() {
return configuration.getProperty("hibernate.connection.driver_class");
}
 
protected String url() {
return configuration.getProperty("hibernate.connection.url");
}
 
protected String user() {
return configuration.getProperty("hibernate.connection.username");
}
 
protected String passwd() {
return configuration.getProperty("hibernate.connection.password");
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/java/org/hibernatespatial/test/EWKTReader.java
New file
0,0 → 1,834
/*
* $Id$
*
* This file is an adapted version of the JTS WKTReader. It has
* been extended by Martin Steinwender to deal with Measured coordinates.
*
* Original copyright notice:
*
* The JTS Topology Suite is a collection of Java classes that
* implement the fundamental operations required to validate a given
* geo-spatial data set to a known topological specification.
*
* Copyright (C) 2001 Vivid Solutions
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
 
 
package org.hibernatespatial.test;
 
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.util.Assert;
import org.hibernatespatial.mgeom.MCoordinate;
import org.hibernatespatial.mgeom.MGeometryFactory;
import org.hibernatespatial.mgeom.MLineString;
 
import java.io.IOException;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
 
/**
* Converts a geometry in EWKT to a JTS-Geometry.
* <p/>
* <code>EWKTReader</code> supports
* extracting <code>Geometry</code> objects from either {@link java.io.Reader}s or
* {@link String}s. This allows it to function as a parser to read <code>Geometry</code>
* objects from text blocks embedded in other data formats (e.g. XML). <P>
* <p/>
* A <code>WKTReader</code> is parameterized by a <code>GeometryFactory</code>,
* to allow it to create <code>Geometry</code> objects of the appropriate
* implementation. In particular, the <code>GeometryFactory</code>
* determines the <code>PrecisionModel</code> and <code>SRID</code> that is
* used. <P>
* <p/>
* The <code>WKTReader</code> converts all input numbers to the precise
* internal representation.
* <p/>
* <h3>Notes:</h3>
* <ul>
* <li>The reader supports non-standard "LINEARRING" tags.
* <li>The reader uses Double.parseDouble to perform the conversion of ASCII
* numbers to floating point. This means it supports the Java
* syntax for floating point literals (including scientific notation).
* </ul>
* <p/>
* <h3>Syntax</h3>
* The following syntax specification describes the version of Well-Known Text
* supported by JTS.
* (The specification uses a syntax language similar to that used in
* the C and Java language specifications.)
* <p/>
* <p/>
* <blockquote><pre>
* <i>WKTGeometry:</i> one of<i>
* <p/>
* WKTPoint WKTLineString WKTLinearRing WKTPolygon
* WKTMultiPoint WKTMultiLineString WKTMultiPolygon
* WKTGeometryCollection</i>
* <p/>
* <i>WKTPoint:</i> <b>POINT ( </b><i>Coordinate</i> <b>)</b>
* <p/>
* <i>WKTLineString:</i> <b>LINESTRING</b> <i>CoordinateSequence</i>
* <p/>
* <i>WKTLinearRing:</i> <b>LINEARRING</b> <i>CoordinateSequence</i>
* <p/>
* <i>WKTPolygon:</i> <b>POLYGON</b> <i>CoordinateSequenceList</i>
* <p/>
* <i>WKTMultiPoint:</i> <b>MULTIPOINT</b> <i>CoordinateSequence</i>
* <p/>
* <i>WKTMultiLineString:</i> <b>MULTILINESTRING</b> <i>CoordinateSequenceList</i>
* <p/>
* <i>WKTMultiPolygon:</i>
* <b>MULTIPOLYGON (</b> <i>CoordinateSequenceList {</i> , <i>CoordinateSequenceList }</i> <b>)</b>
* <p/>
* <i>WKTGeometryCollection: </i>
* <b>GEOMETRYCOLLECTION (</b> <i>WKTGeometry {</i> , <i>WKTGeometry }</i> <b>)</b>
* <p/>
* <i>CoordinateSequenceList:</i>
* <b>(</b> <i>CoordinateSequence {</i> <b>,</b> <i>CoordinateSequence }</i> <b>)</b>
* <p/>
* <i>CoordinateSequence:</i>
* <b>(</b> <i>Coordinate {</i> , <i>Coordinate }</i> <b>)</b>
* <p/>
* <i>Coordinate:
* Number Number Number<sub>opt</sub></i>
* <p/>
* <i>Number:</i> A Java-style floating-point number
* <p/>
* </pre></blockquote>
*
* @see WKTWriter
*/
public class EWKTReader {
private static final String EMPTY = "EMPTY";
private static final String COMMA = ",";
private static final String L_PAREN = "(";
private static final String R_PAREN = ")";
private static final String EQUALS = "=";
private static final String SEMICOLON = ";";
 
private GeometryFactory geometryFactory;
private PrecisionModel precisionModel;
private StreamTokenizer tokenizer;
 
private int dimension = -1;
private Boolean hasM = null;
 
/**
* Creates a reader that creates objects using the default {@link GeometryFactory}.
*/
public EWKTReader() {
this(new MGeometryFactory());
}
 
/**
* Creates a reader that creates objects using the given
* {@link GeometryFactory}.
*
* @param geometryFactory the factory used to create <code>Geometry</code>s.
*/
public EWKTReader(GeometryFactory geometryFactory) {
this.geometryFactory = geometryFactory;
precisionModel = geometryFactory.getPrecisionModel();
}
 
/**
* Reads a Well-Known Text representation of a {@link com.vividsolutions.jts.geom.Geometry}
* from a {@link String}.
*
* @param wellKnownText one or more <Geometry Tagged Text>strings (see the OpenGIS
* Simple Features Specification) separated by whitespace
* @return a <code>Geometry</code> specified by <code>wellKnownText</code>
* @throws com.vividsolutions.jts.io.ParseException
* if a parsing problem occurs
*/
public Geometry read(String wellKnownText) throws ParseException {
StringReader reader = new StringReader(wellKnownText);
try {
return read(reader);
}
finally {
reader.close();
}
}
 
/**
* Reads a Well-Known Text representation of a {@link Geometry}
* from a {@link java.io.Reader}.
*
* @param reader a Reader which will return a <Geometry Tagged Text>
* string (see the OpenGIS Simple Features Specification)
* @return a <code>Geometry</code> read from <code>reader</code>
* @throws ParseException if a parsing problem occurs
*/
public Geometry read(Reader reader) throws ParseException {
 
try {
 
synchronized (this) {
if (this.tokenizer != null) {
throw new RuntimeException("EWKT-Reader is already in use.");
}
tokenizer = new StreamTokenizer(reader);
}
 
// set tokenizer to NOT parse numbers
tokenizer.resetSyntax();
tokenizer.wordChars('a', 'z');
tokenizer.wordChars('A', 'Z');
tokenizer.wordChars(128 + 32, 255);
tokenizer.wordChars('0', '9');
tokenizer.wordChars('-', '-');
tokenizer.wordChars('+', '+');
tokenizer.wordChars('.', '.');
tokenizer.whitespaceChars(0, ' ');
tokenizer.commentChar('#');
 
this.hasM = null;
this.dimension = -1;
 
return readGeometryTaggedText();
 
} catch (IOException e) {
throw new ParseException(e.toString());
} finally {
this.tokenizer = null;
}
}
 
/**
* Returns the next array of <code>Coordinate</code>s in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next element returned by the stream should be L_PAREN (the
* beginning of "(x1 y1, x2 y2, ..., xn yn)") or EMPTY.
* @return the next array of <code>Coordinate</code>s in the
* stream, or an empty array if EMPTY is the next element returned by
* the stream.
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private MCoordinate[] getCoordinates()
throws IOException, ParseException {
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return new MCoordinate[]{};
}
ArrayList coordinates = new ArrayList();
coordinates.add(getPreciseCoordinate());
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
coordinates.add(getPreciseCoordinate());
nextToken = getNextCloserOrComma();
}
return (MCoordinate[]) coordinates.toArray(new MCoordinate[coordinates.size()]);
}
 
/**
* gets the next Coordinate and checks dimension
*
* @return
* @throws IOException
* @throws ParseException
*/
private Coordinate getPreciseCoordinate()
throws IOException, ParseException {
MCoordinate coord = new MCoordinate();
coord.x = getNextNumber();
coord.y = getNextNumber();
 
Double thirdOrdinateValue = null;
Double fourthOrdinateValue = null;
 
if (this.dimension == 3) {
thirdOrdinateValue = getNextNumber();
} else if (this.dimension == 4) {
thirdOrdinateValue = getNextNumber();
fourthOrdinateValue = getNextNumber();
} else if (this.dimension < 0) {
if (isNumberNext()) thirdOrdinateValue = getNextNumber();
if (isNumberNext()) fourthOrdinateValue = getNextNumber();
 
if (fourthOrdinateValue != null) {
this.dimension = 4;
setHasM(true);
} else if (thirdOrdinateValue != null) {
this.dimension = 3;
setHasM(Boolean.TRUE.equals(this.hasM));
} else {
this.dimension = 2;
setHasM(false);
}
}
 
switch (this.dimension) {
case 2:
break;
case 3:
if (this.hasM) {
coord.m = thirdOrdinateValue;
} else {
coord.z = thirdOrdinateValue;
}
break;
case 4:
if (this.hasM) {
coord.z = thirdOrdinateValue;
coord.m = fourthOrdinateValue;
} else {
throw new ParseException("Unsupported geometry dimension.");
}
break;
default:
throw new ParseException("Unsupported geometry dimension.");
}
 
precisionModel.makePrecise(coord);
return coord;
}
 
 
private boolean isNumberNext() throws IOException {
int type = tokenizer.nextToken();
tokenizer.pushBack();
return type == StreamTokenizer.TT_WORD;
}
 
/**
* Parses the next number in the stream.
* Numbers with exponents are handled.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be a number.
* @return the next number in the stream
* @throws ParseException if the next token is not a valid number
* @throws IOException if an I/O error occurs
*/
private double getNextNumber() throws IOException,
ParseException {
int type = tokenizer.nextToken();
switch (type) {
case StreamTokenizer.TT_WORD: {
try {
return Double.parseDouble(tokenizer.sval);
}
catch (NumberFormatException ex) {
throw new ParseException("Invalid number: " + tokenizer.sval);
}
}
}
parseError("number");
return 0.0;
}
 
/**
* Returns the next EMPTY or L_PAREN in the stream as uppercase text.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be EMPTY or L_PAREN.
* @return the next EMPTY or L_PAREN in the stream as uppercase
* text.
* @throws ParseException if the next token is not EMPTY or L_PAREN
* @throws IOException if an I/O error occurs
*/
private String getNextEmptyOrOpener() throws IOException, ParseException {
String nextWord = getNextWord();
if (nextWord.equals(EMPTY) || nextWord.equals(L_PAREN)) {
return nextWord;
}
parseError(EMPTY + " or " + L_PAREN);
return null;
}
 
/**
* Returns the next R_PAREN or COMMA in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be R_PAREN or COMMA.
* @return the next R_PAREN or COMMA in the stream
* @throws ParseException if the next token is not R_PAREN or COMMA
* @throws IOException if an I/O error occurs
*/
private String getNextCloserOrComma() throws IOException, ParseException {
String nextWord = getNextWord();
if (nextWord.equals(COMMA) || nextWord.equals(R_PAREN)) {
return nextWord;
}
parseError(COMMA + " or " + R_PAREN);
return null;
}
 
/**
* Returns the next R_PAREN in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be R_PAREN.
* @return the next R_PAREN in the stream
* @throws ParseException if the next token is not R_PAREN
* @throws IOException if an I/O error occurs
*/
private String getNextCloser() throws IOException, ParseException {
String nextWord = getNextWord();
if (nextWord.equals(R_PAREN)) {
return nextWord;
}
parseError(R_PAREN);
return null;
}
 
/**
* Returns the next R_PAREN in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be R_PAREN.
* @return the next R_PAREN in the stream
* @throws ParseException if the next token is not R_PAREN
* @throws IOException if an I/O error occurs
*/
private int getSRID() throws IOException, ParseException {
if (!getNextWord().equals(EQUALS)) {
parseError(EQUALS);
return 0;
}
int srid = Integer.parseInt(getNextWord());
if (!getNextWord().equals(SEMICOLON)) {
parseError(SEMICOLON);
return 0;
}
return srid;
}
 
/**
* Returns the next word in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be a word.
* @return the next word in the stream as uppercase text
* @throws ParseException if the next token is not a word
* @throws IOException if an I/O error occurs
*/
private String getNextWord() throws IOException, ParseException {
int type = tokenizer.nextToken();
switch (type) {
case StreamTokenizer.TT_WORD:
 
String word = tokenizer.sval;
if (word.equalsIgnoreCase(EMPTY))
return EMPTY;
return word;
 
case '(':
return L_PAREN;
case ')':
return R_PAREN;
case ',':
return COMMA;
case '=':
return EQUALS;
case ';':
return SEMICOLON;
}
parseError("word");
return null;
}
 
/**
* Throws a formatted ParseException for the current token.
*
* @param expected a description of what was expected
* @throws ParseException
* @throws com.vividsolutions.jts.util.AssertionFailedException
* if an invalid token is encountered
*/
private void parseError(String expected)
throws ParseException {
// throws Asserts for tokens that should never be seen
if (tokenizer.ttype == StreamTokenizer.TT_NUMBER)
Assert.shouldNeverReachHere("Unexpected NUMBER token");
if (tokenizer.ttype == StreamTokenizer.TT_EOL)
Assert.shouldNeverReachHere("Unexpected EOL token");
 
String tokenStr = tokenString();
throw new ParseException("Expected " + expected + " but found " + tokenStr);
}
 
/**
* Gets a description of the current token
*
* @return a description of the current token
*/
private String tokenString() {
switch (tokenizer.ttype) {
case StreamTokenizer.TT_NUMBER:
return "<NUMBER>";
case StreamTokenizer.TT_EOL:
return "End-of-Line";
case StreamTokenizer.TT_EOF:
return "End-of-Stream";
case StreamTokenizer.TT_WORD:
return "'" + tokenizer.sval + "'";
}
return "'" + (char) tokenizer.ttype + "'";
}
 
/**
* Creates a <code>Geometry</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;Geometry Tagged Text&gt;.
* @return a <code>Geometry</code> specified by the next token
* in the stream
* @throws ParseException if the coordinates used to create a <code>Polygon</code>
* shell and holes do not form closed linestrings, or if an unexpected
* token was encountered
* @throws IOException if an I/O error occurs
*/
private Geometry readGeometryTaggedText() throws IOException, ParseException {
 
String type = null;
Geometry geom;
 
int srid = geometryFactory.getSRID();
 
try {
String firstWord = getNextWord();
if ("SRID".equals(firstWord)) {
srid = getSRID();
type = getNextWord();
} else {
type = firstWord;
}
} catch (IOException e) {
return null;
} catch (ParseException e) {
return null;
}
 
if (type.equals("POINT")) {
geom = readPointText();
} else if (type.equals("POINTM")) {
setHasM(true);
geom = readPointText();
} else if (type.equalsIgnoreCase("LINESTRING")) {
geom = readLineStringText();
} else if (type.equalsIgnoreCase("LINESTRINGM")) {
setHasM(true);
geom = readLineStringText();
} else if (type.equalsIgnoreCase("LINEARRING")) {
geom = readLinearRingText();
} else if (type.equalsIgnoreCase("LINEARRINGM")) {
setHasM(true);
geom = readLinearRingText();
} else if (type.equalsIgnoreCase("POLYGON")) {
geom = readPolygonText();
} else if (type.equalsIgnoreCase("POLYGONM")) {
//setHasM(true);
//geom = readPolygonText();
throw new RuntimeException("PolygonM is not supported.");
} else if (type.equalsIgnoreCase("MULTIPOINT")) {
geom = readMultiPointText();
} else if (type.equalsIgnoreCase("MULTIPOINTM")) {
setHasM(true);
geom = readMultiPointText();
} else if (type.equalsIgnoreCase("MULTILINESTRING")) {
geom = readMultiLineStringText();
} else if (type.equalsIgnoreCase("MULTILINESTRINGM")) {
setHasM(true);
geom = readMultiLineStringText();
} else if (type.equalsIgnoreCase("MULTIPOLYGON")) {
geom = readMultiPolygonText();
} else if (type.equalsIgnoreCase("MULTIPOLYGONM")) {
//setHasM(true);
//geom = readMultiPolygonText();
throw new RuntimeException("MultiPolygonM is not supported.");
} else if (type.equalsIgnoreCase("GEOMETRYCOLLECTION")) {
geom = readGeometryCollectionText();
} else if (type.equalsIgnoreCase("GEOMETRYCOLLECTIONM")) {
setHasM(true);
geom = readGeometryCollectionText();
} else {
throw new ParseException("Unknown geometry type: " + type);
}
geom.setSRID(srid);
 
return geom;
}
 
/**
* m-values sicherstellen
*
* @throws ParseException
*/
private void setHasM(boolean hasM) throws ParseException {
if (this.hasM == null) {
this.hasM = hasM;
} else if (this.hasM != hasM) {
throw new ParseException("Inkonsistent use of m-values.");
}
}
 
/**
* Creates a <code>Point</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;Point Text&gt;.
* @return a <code>Point</code> specified by the next token in
* the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private Point readPointText() throws IOException, ParseException {
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return geometryFactory.createPoint((Coordinate) null);
}
Point point = geometryFactory.createPoint(getPreciseCoordinate());
getNextCloser();
return point;
}
 
/**
* Creates a <code>LineString</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;LineString Text&gt;.
* @return a <code>LineString</code> specified by the next
* token in the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private LineString readLineStringText() throws IOException, ParseException {
 
MCoordinate[] coords = getCoordinates();
if (this.hasM != null && this.hasM)
return ((MGeometryFactory) geometryFactory).createMLineString(coords);
else
return geometryFactory.createLineString(coords);
 
}
 
/**
* Creates a <code>LinearRing</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;LineString Text&gt;.
* @return a <code>LinearRing</code> specified by the next
* token in the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if the coordinates used to create the <code>LinearRing</code>
* do not form a closed linestring, or if an unexpected token was
* encountered
*/
private LinearRing readLinearRingText()
throws IOException, ParseException {
MCoordinate[] coords = getCoordinates();
if (this.hasM)
throw new RuntimeException("LinearRingM not supported.");
else
return geometryFactory.createLinearRing(coords);
}
 
/**
* Creates a <code>MultiPoint</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;MultiPoint Text&gt;.
* @return a <code>MultiPoint</code> specified by the next
* token in the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private MultiPoint readMultiPointText() throws IOException, ParseException {
MCoordinate[] coords = getCoordinates();
Point[] pts = toPoints(coords);
return geometryFactory.createMultiPoint(pts);
}
 
/**
* Creates an array of <code>Point</code>s having the given <code>Coordinate</code>
* s.
*
* @param coordinates the <code>Coordinate</code>s with which to create the
* <code>Point</code>s
* @return <code>Point</code>s created using this <code>WKTReader</code>
* s <code>GeometryFactory</code>
*/
private Point[] toPoints(Coordinate[] coordinates) {
ArrayList points = new ArrayList();
for (int i = 0; i < coordinates.length; i++) {
points.add(geometryFactory.createPoint(coordinates[i]));
}
return (Point[]) points.toArray(new Point[]{});
}
 
/**
* Creates a <code>Polygon</code> using the next token in the stream.
*
* @param hasM
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;Polygon Text&gt;.
* @return a <code>Polygon</code> specified by the next token
* in the stream
* @throws ParseException if the coordinates used to create the <code>Polygon</code>
* shell and holes do not form closed linestrings, or if an unexpected
* token was encountered.
* @throws IOException if an I/O error occurs
*/
private Polygon readPolygonText() throws IOException, ParseException {
 
// PolygonM is not supported
setHasM(false);
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return geometryFactory.createPolygon(geometryFactory.createLinearRing(
new Coordinate[]{}), new LinearRing[]{});
}
ArrayList holes = new ArrayList();
LinearRing shell = readLinearRingText();
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
LinearRing hole = readLinearRingText();
holes.add(hole);
nextToken = getNextCloserOrComma();
}
LinearRing[] array = new LinearRing[holes.size()];
return geometryFactory.createPolygon(shell, (LinearRing[]) holes.toArray(array));
}
 
/**
* Creates a <code>MultiLineString</code> using the next token in the stream.
*
* @param hasM
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;MultiLineString Text&gt;.
* @return a <code>MultiLineString</code> specified by the
* next token in the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private com.vividsolutions.jts.geom.MultiLineString readMultiLineStringText() throws IOException, ParseException {
 
ArrayList lineStrings = new ArrayList();
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
// No Coordinates for LineString
} else {
LineString lineString = readLineStringText();
lineStrings.add(lineString);
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
lineString = readLineStringText();
lineStrings.add(lineString);
nextToken = getNextCloserOrComma();
}
}
 
if (this.hasM != null && this.hasM == true) {
MLineString[] mlines = (MLineString[]) lineStrings.toArray(new MLineString[lineStrings.size()]);
return ((MGeometryFactory) geometryFactory).createMultiMLineString(mlines);
} else {
setHasM(false);
LineString[] lines = (LineString[]) lineStrings.toArray(new LineString[lineStrings.size()]);
return geometryFactory.createMultiLineString(lines);
}
}
 
/**
* Creates a <code>MultiPolygon</code> using the next token in the stream.
*
* @param hasM
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;MultiPolygon Text&gt;.
* @return a <code>MultiPolygon</code> specified by the next
* token in the stream, or if if the coordinates used to create the
* <code>Polygon</code> shells and holes do not form closed linestrings.
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private MultiPolygon readMultiPolygonText()
throws IOException, ParseException {
 
// MultiPolygonM is not supported
setHasM(false);
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return geometryFactory.createMultiPolygon(new Polygon[]{});
}
ArrayList polygons = new ArrayList();
Polygon polygon = readPolygonText();
polygons.add(polygon);
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
polygon = readPolygonText();
polygons.add(polygon);
nextToken = getNextCloserOrComma();
}
Polygon[] array = new Polygon[polygons.size()];
return geometryFactory.createMultiPolygon((Polygon[]) polygons.toArray(array));
}
 
/**
* Creates a <code>GeometryCollection</code> using the next token in the
* stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;GeometryCollection Text&gt;.
* @return a <code>GeometryCollection</code> specified by the
* next token in the stream
* @throws ParseException if the coordinates used to create a <code>Polygon</code>
* shell and holes do not form closed linestrings, or if an unexpected
* token was encountered
* @throws IOException if an I/O error occurs
*/
private GeometryCollection readGeometryCollectionText()
throws IOException, ParseException {
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return geometryFactory.createGeometryCollection(new Geometry[]{});
}
ArrayList geometries = new ArrayList();
Geometry geometry = readGeometryTaggedText();
geometries.add(geometry);
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
geometry = readGeometryTaggedText();
geometries.add(geometry);
nextToken = getNextCloserOrComma();
}
Geometry[] array = new Geometry[geometries.size()];
return geometryFactory.createGeometryCollection((Geometry[]) geometries.toArray(array));
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/resources/GeomEntity.hbm.xml
New file
0,0 → 1,42
<?xml version="1.0"?>
<!--
~ $Id: GeomEntity.hbm.xml 242 2010-09-22 20:40:07Z maesenka $
~
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for geographic data.
~
~ Copyright © 2007-2010 Geovise BVBA
~
~ This library is free software; you can redistribute it and/or
~ modify it under the terms of the GNU Lesser General Public
~ License as published by the Free Software Foundation; either
~ version 2.1 of the License, or (at your option) any later version.
~
~ This library is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this library; if not, write to the Free Software
~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
~
~ For more information, visit: http://www.hibernatespatial.org/
-->
 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping>
<class name="org.hibernatespatial.test.GeomEntity" table="GEOMTEST">
<id name="id" type="integer">
<generator class="assigned"/>
</id>
<property name="type" type="string">
<column name="type" length="50"/>
</property>
<property name="geom" type="org.hibernatespatial.GeometryUserType">
<column name="geom"/>
</property>
</class>
</hibernate-mapping>
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/resources/test.cfg.xml
New file
0,0 → 1,6
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-spatial>
<default_dialect>org.hibernatespatial.postgis.PostgisDialect</default_dialect>
<precision_model>FIXED</precision_model>
<precision_model_scale>5</precision_model_scale>
</hibernate-spatial>
/branches/Jts_mgeom_wkb/hibernate-spatial/src/test/resources/test-data-set.xml
New file
0,0 → 1,298
<TestData>
<Element>
<id>1</id>
<type>POINT</type>
<wkt>POINT(10 5)</wkt>
<srid>0</srid>
</Element>
<Element>
<id>2</id>
<type>POINT</type>
<wkt>POINT(52.25 2.53)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>3</id>
<type>POINT</type>
<wkt>POINT(150000 200000)</wkt>
<srid>31370</srid>
</Element>
<Element>
<id>4</id>
<type>POINT</type>
<wkt>POINT(10.0 2.0 1.0 3.0)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>5</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0, 20.0 15.0)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>6</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>7</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0 0.0, 20.0 15.0 3.0)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>8</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0 0.0 0.0, 20.0 15.0 3.0 1.0)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>9</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0 1, 20.0 15.0 2, 30.3 22.4 5, 10 30.0 2)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>10</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0 1 1, 20.0 15.0 2 3, 30.3 22.4 5 10, 10 30.0 2 12)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>11</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0))</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>12</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0), (40.0 20.0, 42.0 18.0, 43.0 16.0, 40 14.0))
</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>13</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0 1.0, 20.0 15.0 2.0, 30.3 22.4 1.0, 10 30.0 1.0),(40.0 20.0 0.0, 42.0 18.0 1.0,
43.0 16.0 2.0, 40 14.0 3.0))
</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>14</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0 1.0 0.0, 20.0 15.0 2.0 0.0, 30.3 22.4 1.0 1.0, 10 30.0 1.0 2.0),(40.0 20.0 0.0
3.0, 42.0 18.0 1.0 4.0, 43.0 16.0 2.0 5.0, 40 14.0 3.0 6.0))
</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>15</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0 1.0 0.0, 20.0 15.0 2.0 0.0, 30.3 22.4 1.0 1.0, 10 30.0 1.0 2.0))</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>16</id>
<type>POLYGON</type>
<wkt>POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0) )</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>17</id>
<type>POLYGON</type>
<wkt>POLYGON( (0 0 0, 0 10 1, 10 10 1, 10 0 1, 0 0 0) )</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>18</id>
<type>POLYGON</type>
<wkt>POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 5, 5 5,5 2, 2 2))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>19</id>
<type>POLYGON</type>
<wkt>POLYGON( (110 110, 110 120, 120 120, 120 110, 110 110) )</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>20</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100, 120 140, 130 134, 105 100)) )</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>21</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON( ((10 20 1, 30 40 2, 44 50 2, 10 20 1)), ((105 100 0, 120 140 10, 130 134 20, 105 100 0)) )
</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>22</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON(( (0 0, 0 50, 50 50, 50 0, 0 0), (10 10, 10 20, 20 20, 20 10, 10 10) ),((105 100, 120 140, 130
134, 105 100)) )
</wkt>
<srid>4326</srid>
</Element>
 
 
<Element>
<id>25</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2, 25 5, 30 3)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>26</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>27</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2 1, 25 5 2, 30 3 5)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>28</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2 1 0, 25 5 2 4, 30 3 5 2)</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>30</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>31</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0)))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>32</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0),(1 1, 2 1, 2 2, 1 2,
1 1)))
</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>33</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION( MULTIPOINT(21 2, 25 5, 30 3), MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100,
120 140, 130 134, 105 100)) ), MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0)))
</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>34</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), POINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>35</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>36</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), GEOMETRYCOLLECTION EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>37</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), POLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>38</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTILINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>39</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTIPOINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>40</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTIPOLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
 
<Element>
<id>50</id>
<type>POINT</type>
<wkt>POINT EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>51</id>
<type>LINESTRING</type>
<wkt>LINESTRING EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>52</id>
<type>POLYGON</type>
<wkt>POLYGON EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>53</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>54</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>55</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>56</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION EMPTY</wkt>
<srid>4326</srid>
</Element>
 
 
</TestData>
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/META-INF/MANIFEST.MF
New file
0,0 → 1,3
Manifest-Version: 1.0
Class-Path:
 
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/helper/FinderException.java
New file
0,0 → 1,42
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.helper;
 
/**
* This exception is thrown when Hibernate Spatial fails to find a required
* resource.
*
* @author maesenka
*
*/
public class FinderException extends Exception {
 
private static final long serialVersionUID = 1L;
 
public FinderException(String msg) {
super(msg);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/helper/PropertyFileReader.java
New file
0,0 → 1,102
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.helper;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
/**
* Helper class to read settings and properties files.
*
* @author Karel Maesen
*
*/
public class PropertyFileReader {
 
private static final Logger log = LoggerFactory.getLogger(PropertyFileReader.class);
 
/**
* pattern for comment lines. If it matches, it is a comment.
*/
private static final Pattern nonCommentPattern = Pattern
.compile("^([^#]+)");
 
private InputStream is = null;
 
public PropertyFileReader(InputStream is) {
this.is = is;
}
 
public Properties getProperties() throws IOException {
if (is == null)
return null;
Properties props = new Properties();
props.load(is);
return props;
}
 
/**
* Returns the non-comment lines in a file.
*
* @return set of non-comment strings.
* @throws IOException
*/
public Set<String> getNonCommentLines() throws IOException {
Set<String> lines = new HashSet<String>();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
while ((line = reader.readLine()) != null) {
line = line.trim();
Matcher m = nonCommentPattern.matcher(line);
if (m.find()) {
lines.add(m.group().trim());
}
}
return lines;
}
 
public void close() {
try {
this.is.close();
} catch (IOException e) {
log.warn("Exception when closing PropertyFileReader: " + e);
}
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/helper/GeometryPropertyFinder.java
New file
0,0 → 1,27
package org.hibernatespatial.helper;
 
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.type.Type;
 
import com.vividsolutions.jts.geom.Geometry;
 
/**
* This <code>FinderStrategy</code> implementation returns the first
* geometry-valued property.
*
*/
public class GeometryPropertyFinder implements FinderStrategy<String, ClassMetadata> {
 
public String find(ClassMetadata metadata) throws FinderException {
for (String prop : metadata.getPropertyNames()) {
Type type = metadata.getPropertyType(prop);
 
if (Geometry.class.isAssignableFrom(type.getReturnedClass())) {
return prop;
}
}
throw new FinderException(
"Could not find a Geometry-valued property in "
+ metadata.getEntityName());
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/helper/FinderStrategy.java
New file
0,0 → 1,52
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.helper;
 
/**
* A <code>FinderStrategy</code> is used to find a specific feature. It is
* useful in cases where reflection is used to determine some property of a
* class.
*
* @author Karel Maesen
*
* @param <T>
* the return type of the <code>find</code> method
* @param <S>
* the type of subject
*/
public interface FinderStrategy<T, S> {
 
/**
* Find a feature or property of a subject
*
* @param subject
* the object that is being searched
* @return the object sought
* @throws FinderException
* thrown when the feature can be found;
*/
public T find(S subject) throws FinderException;
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/helper/EnvelopeAdapter.java
New file
0,0 → 1,60
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.helper;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;
 
public class EnvelopeAdapter {
 
static private GeometryFactory geomFactory = new GeometryFactory();
 
static public Polygon toPolygon(Envelope env, int SRID) {
Coordinate[] coords = new Coordinate[5];
 
coords[0] = new Coordinate(env.getMinX(), env.getMinY());
coords[1] = new Coordinate(env.getMinX(), env.getMaxY());
coords[2] = new Coordinate(env.getMaxX(), env.getMaxY());
coords[3] = new Coordinate(env.getMaxX(), env.getMinY());
coords[4] = new Coordinate(env.getMinX(), env.getMinY());
LinearRing shell = geomFactory.createLinearRing(coords);
 
Polygon pg = geomFactory.createPolygon(shell, null);
pg.setSRID(SRID);
return pg;
}
 
public static void setGeometryFactory(GeometryFactory gf) {
geomFactory = gf;
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/Circle.java
New file
0,0 → 1,578
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.PrecisionModel;
 
import java.util.ArrayList;
import java.util.List;
 
/**
* This class provides operations for handling the usage of Circles and arcs in
* Geometries.
* <p/>
* Date: Oct 15, 2007
*
* @author Tom Acree
*/
public class Circle {
private Coordinate center = new Coordinate(0.0, 0.0);
 
private double radius = 0;
 
private PrecisionModel precisionModel = new PrecisionModel();
 
// Constructors **********************************************************
 
/**
* Creates a circle whose center is at the origin and whose radius is 0.
*/
protected Circle() {
}
 
/**
* Create a circle with a defined center and radius
*
* @param center The coordinate representing the center of the circle
* @param radius The radius of the circle
*/
public Circle(Coordinate center, double radius) {
this.center = center;
this.radius = radius;
}
 
/**
* Create a circle using the x/y coordinates for the center.
*
* @param xCenter The x coordinate of the circle's center
* @param yCenter The y coordinate of the circle's center
* @param radius the radius of the circle
*/
public Circle(double xCenter, double yCenter, double radius) {
this(new Coordinate(xCenter, yCenter), radius);
}
 
/**
* Creates a circle based on bounding box. It is possible for the user of
* this class to pass bounds to this method that do not represent a square.
* If this is the case, we must force the bounding rectangle to be a square.
* To this end, we check the box and set the side of the box to the larger
* dimension of the rectangle
*
* @param xLeft
* @param yUpper
* @param xRight
* @param yLower
*/
public Circle(double xLeft, double yUpper, double xRight, double yLower) {
double side = Math.min(Math.abs(xRight - xLeft), Math.abs(yLower
- yUpper));
this.center.x = Math.min(xRight, xLeft) + side / 2;
this.center.y = Math.min(yUpper, yLower) + side / 2;
this.radius = side / 2;
}
 
/**
* Three point method of circle construction. All three points must be on
* the circumference of the circle.
*
* @param point1
* @param point2
* @param point3
*/
public Circle(Coordinate point1, Coordinate point2, Coordinate point3) {
initThreePointCircle(point1, point2, point3);
}
 
/**
* Three point method of circle construction. All three points must be on
* the circumference of the circle.
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param x3
* @param y3
*/
public Circle(double x1, double y1, double x2, double y2, double x3,
double y3) {
this(new Coordinate(x1, y1), new Coordinate(x2, y2), new Coordinate(x3,
y3));
}
 
/**
* shift the center of the circle by delta X and delta Y
*/
public void shift(double deltaX, double deltaY) {
this.center.x = this.center.x + deltaX;
this.center.y = this.center.y + deltaY;
}
 
/**
* Move the circle to a new center
*/
public void move(double x, double y) {
this.center.x = x;
this.center.y = y;
}
 
/**
* Defines the circle based on three points. All three points must be on on
* the circumference of the circle, and hence, the 3 points cannot be have
* any pair equal, and cannot form a line. Therefore, each point given is
* one radius measure from the circle's center.
*
* @param p1 A point on the desired circle
* @param p2 A point on the desired circle
* @param p3 A point on the desired circle
*/
private void initThreePointCircle(Coordinate p1, Coordinate p2,
Coordinate p3) {
double a13, b13, c13;
double a23, b23, c23;
double x = 0., y = 0., rad = 0.;
 
// begin pre-calculations for linear system reduction
a13 = 2 * (p1.x - p3.x);
b13 = 2 * (p1.y - p3.y);
c13 = (p1.y * p1.y - p3.y * p3.y) + (p1.x * p1.x - p3.x * p3.x);
a23 = 2 * (p2.x - p3.x);
b23 = 2 * (p2.y - p3.y);
c23 = (p2.y * p2.y - p3.y * p3.y) + (p2.x * p2.x - p3.x * p3.x);
// testsuite-suite to be certain we have three distinct points passed
double smallNumber = 0.01;
if ((Math.abs(a13) < smallNumber && Math.abs(b13) < smallNumber)
|| (Math.abs(a13) < smallNumber && Math.abs(b13) < smallNumber)) {
// // points too close so set to default circle
x = 0;
y = 0;
rad = 0;
} else {
// everything is acceptable do the y calculation
y = (a13 * c23 - a23 * c13) / (a13 * b23 - a23 * b13);
// x calculation
// choose best formula for calculation
if (Math.abs(a13) > Math.abs(a23)) {
x = (c13 - b13 * y) / a13;
} else {
x = (c23 - b23 * y) / a23;
}
// radius calculation
rad = Math.sqrt((x - p1.x) * (x - p1.x) + (y - p1.y) * (y - p1.y));
}
this.center.x = x;
this.center.y = y;
this.radius = rad;
}
 
public Coordinate getCenter() {
return this.center;
}
 
public double getRadius() {
return this.radius;
}
 
/**
* Given 2 points defining an arc on the circle, interpolates the circle
* into a collection of points that provide connected chords that
* approximate the arc based on the tolerance value. The tolerance value
* specifies the maximum distance between a chord and the circle.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
* @param tolerence maximum distance between the center of the chord and the outer
* edge of the circle
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeArc(double x1, double y1, double x2,
double y2, double x3, double y3, double tolerence) {
Coordinate p1 = new Coordinate(x1, y1);
Coordinate p2 = new Coordinate(x2, y2);
Coordinate p3 = new Coordinate(x3, y3);
return new Circle(p1, p2, p3).linearizeArc(p1, p2, p3, tolerence);
}
 
/**
* Given 2 points defining an arc on the circle, interpolates the circle
* into a collection of points that provide connected chords that
* approximate the arc based on the tolerance value. This method uses a
* tolerence value of 1/100 of the length of the radius.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeArc(double x1, double y1, double x2,
double y2, double x3, double y3) {
Coordinate p1 = new Coordinate(x1, y1);
Coordinate p2 = new Coordinate(x2, y2);
Coordinate p3 = new Coordinate(x3, y3);
Circle c = new Circle(p1, p2, p3);
double tolerence = 0.01 * c.getRadius();
return c.linearizeArc(p1, p2, p3, tolerence);
}
 
/**
* Given a circle defined by the 3 points, creates a linearized
* interpolation of the circle starting and ending on the first coordinate.
* This method uses a tolerence value of 1/100 of the length of the radius.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeCircle(double x1, double y1, double x2,
double y2, double x3, double y3) {
Coordinate p1 = new Coordinate(x1, y1);
Coordinate p2 = new Coordinate(x2, y2);
Coordinate p3 = new Coordinate(x3, y3);
Circle c = new Circle(p1, p2, p3);
double tolerence = 0.01 * c.getRadius();
return c.linearizeArc(p1, p2, p1, tolerence);
}
 
/**
* Given 2 points defining an arc on the circle, interpolates the circle
* into a collection of points that provide connected chords that
* approximate the arc based on the tolerance value. The tolerance value
* specifies the maximum distance between a chord and the circle.
*
* @param p1 begin coordinate of the arc
* @param p2 any other point on the arc
* @param p3 end coordinate of the arc
* @param tolerence maximum distance between the center of the chord and the outer
* edge of the circle
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public Coordinate[] linearizeArc(Coordinate p1, Coordinate p2,
Coordinate p3, double tolerence) {
Arc arc = createArc(p1, p2, p3);
List<Coordinate> result = linearizeInternal(null, arc, tolerence);
return result.toArray(new Coordinate[result.size()]);
}
 
private List<Coordinate> linearizeInternal(List<Coordinate> coordinates,
Arc arc, double tolerence) {
if (coordinates == null) {
coordinates = new ArrayList<Coordinate>();
}
double arcHt = arc.getArcHeight();
if (Double.compare(arcHt, tolerence) <= 0) {
int lastIndex = coordinates.size() - 1;
Coordinate lastCoord = lastIndex >= 0 ? coordinates.get(lastIndex)
: null;
 
if (lastCoord == null || !arc.getP1().equals2D(lastCoord)) {
coordinates.add(arc.getP1());
coordinates.add(arc.getP2());
} else {
coordinates.add(arc.getP2());
}
 
} else {
// otherwise, split
Arc[] splits = arc.split();
linearizeInternal(coordinates, splits[0], tolerence);
linearizeInternal(coordinates, splits[1], tolerence);
}
return coordinates;
}
 
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Circle circle = (Circle) o;
 
if (Double.compare(circle.radius, this.radius) != 0) {
return false;
}
if (this.center != null ? !this.center.equals2D(circle.center)
: circle.center != null) {
return false;
}
return true;
}
 
public String toString() {
return "Circle with Radius = " + this.radius
+ " and a center at the coordinates (" + this.center.x + ", "
+ this.center.y + ")";
}
 
/**
* Returns the angle of the point from the center and the horizontal line
* from the center.
*
* @param p a point in space
* @return The angle of the point from the center of the circle
*/
public double getAngle(Coordinate p) {
double dx = p.x - this.center.x;
double dy = p.y - this.center.y;
double angle;
 
if (dx == 0.0) {
if (dy == 0.0) {
angle = 0.0;
} else if (dy > 0.0) {
angle = Math.PI / 2.0;
} else {
angle = (Math.PI * 3.0) / 2.0;
}
} else if (dy == 0.0) {
if (dx > 0.0) {
angle = 0.0;
} else {
angle = Math.PI;
}
} else {
if (dx < 0.0) {
angle = Math.atan(dy / dx) + Math.PI;
} else if (dy < 0.0) {
angle = Math.atan(dy / dx) + (2 * Math.PI);
} else {
angle = Math.atan(dy / dx);
}
}
return angle;
}
 
public Coordinate getPoint(final double angle) {
double x = Math.cos(angle) * this.radius;
x = x + this.center.x;
x = this.precisionModel.makePrecise(x);
 
double y = Math.sin(angle) * this.radius;
y = y + this.center.y;
y = this.precisionModel.makePrecise(y);
return new Coordinate(x, y);
}
 
/**
* @param p A point in space
* @return The distance the point is from the center of the circle
*/
public double distanceFromCenter(Coordinate p) {
return Math.abs(this.center.distance(p));
}
 
public Arc createArc(Coordinate p1, Coordinate p2, Coordinate p3) {
return new Arc(p1, p2, p3);
}
 
/**
* Returns an angle between 0 and 2*PI. For example, 4*PI would get returned
* as 2*PI since they are equivalent.
*
* @param angle an angle in radians to normalize
* @return an angle between 0 and 2*PI
*/
public static double normalizeAngle(double angle) {
double maxRadians = 2 * Math.PI;
if (angle >= 0 && angle <= maxRadians) {
return angle;
}
if (angle < 0) {
return maxRadians - Math.abs(angle);
} else {
return angle % maxRadians;
}
}
 
/**
* Returns the angle between the angles a1 and a2 in radians. Angle is
* calculated in the counterclockwise direction.
*
* @param a1 first angle
* @param a2 second angle
* @return the angle between a1 and a2 in the clockwise direction
*/
public static double subtractAngles(double a1, double a2) {
if (a1 < a2) {
return a2 - a1;
} else {
return TWO_PI - Math.abs(a2 - a1);
}
}
 
private static final double TWO_PI = Math.PI * 2;
 
public class Arc {
private Coordinate p1, p2;
 
private double arcAngle; // angle in radians
 
private double p1Angle;
 
private double p2Angle;
 
private boolean clockwise;
 
private Arc(Coordinate p1, Coordinate midPt, Coordinate p2) {
this.p1 = p1;
this.p2 = p2;
this.p1Angle = getAngle(p1);
// See if this arc covers the whole circle
if (p1.equals2D(p2)) {
this.p2Angle = TWO_PI + this.p1Angle;
this.arcAngle = TWO_PI;
} else {
this.p2Angle = getAngle(p2);
double midPtAngle = getAngle(midPt);
 
// determine the direction
double ccDegrees = Circle.subtractAngles(this.p1Angle,
midPtAngle)
+ Circle.subtractAngles(midPtAngle, this.p2Angle);
 
if (ccDegrees < TWO_PI) {
this.clockwise = false;
this.arcAngle = ccDegrees;
} else {
this.clockwise = true;
this.arcAngle = TWO_PI - ccDegrees;
}
}
}
 
private Arc(Coordinate p1, Coordinate p2, boolean isClockwise) {
this.p1 = p1;
this.p2 = p2;
this.clockwise = isClockwise;
this.p1Angle = getAngle(p1);
if (p1.equals2D(p2)) {
this.p2Angle = TWO_PI + this.p1Angle;
} else {
this.p2Angle = getAngle(p2);
}
determineArcAngle();
}
 
private void determineArcAngle() {
double diff;
if (this.p1.equals2D(this.p2)) {
diff = TWO_PI;
} else if (this.clockwise) {
diff = this.p1Angle - this.p2Angle;
} else {
diff = this.p2Angle - this.p1Angle;
}
this.arcAngle = Circle.normalizeAngle(diff);
}
 
/**
* given a an arc defined from p1 to p2 existing on this circle, returns
* the height of the arc. This height is defined as the distance from
* the center of a chord defined by (p1, p2) and the outer edge of the
* circle.
*
* @return the arc height
*/
public double getArcHeight() {
Coordinate chordCenterPt = this.getChordCenterPoint();
double dist = distanceFromCenter(chordCenterPt);
if (this.arcAngle > Math.PI) {
return Circle.this.radius + dist;
} else {
return Circle.this.radius - dist;
}
}
 
public Coordinate getChordCenterPoint() {
double centerX = this.p1.x + (this.p2.x - this.p1.x) / 2;
double centerY = this.p1.y + (this.p2.y - this.p1.y) / 2;
return new Coordinate(centerX, centerY);
}
 
public Arc[] split() {
int directionFactor = isClockwise() ? -1 : 1;
double angleOffset = directionFactor * (this.arcAngle / 2);
 
double midAngle = this.p1Angle + angleOffset;
Coordinate newMidPoint = getPoint(midAngle);
 
Arc arc1 = new Arc(this.p1, newMidPoint, isClockwise());
Arc arc2 = new Arc(newMidPoint, this.p2, isClockwise());
return new Arc[]{arc1, arc2};
}
 
public Coordinate getP1() {
return this.p1;
}
 
public Coordinate getP2() {
return this.p2;
}
 
public double getArcAngle() {
return this.arcAngle;
}
 
public double getArcAngleDegrees() {
return Math.toDegrees(this.arcAngle);
}
 
public double getP1Angle() {
return this.p1Angle;
}
 
public double getP2Angle() {
return this.p2Angle;
}
 
public boolean isClockwise() {
return this.clockwise;
}
 
public String toString() {
return "P1: " + this.p1 + " P2: " + this.p2 + " clockwise: " + this.clockwise;
}
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialAnalysis.java
New file
0,0 → 1,48
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
/**
* The spatial analysis functions defined in the OGC SFS specification.
*
* @author Karel Maesen
*/
public interface SpatialAnalysis {
 
public static int DISTANCE = 1;
 
public static int BUFFER = 2;
 
public static int CONVEXHULL = 3;
 
public static int INTERSECTION = 4;
 
public static int UNION = 5;
 
public static int DIFFERENCE = 6;
 
public static int SYMDIFFERENCE = 7;
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialFunction.java
New file
0,0 → 1,47
package org.hibernatespatial;
 
/**
* Spatial functions that users generally expect in a database.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: Oct 7, 2010
*/
public enum SpatialFunction {
 
dimension("SFS 1.1"),
geometrytype("SFS 1.1"),
srid("SFS 1.1"),
envelope("SFS 1.1"),
astext("SFS 1.1"),
asbinary("SFS 1.1"),
isempty("SFS 1.1"),
issimple("SFS 1.1"),
boundary("SFS 1.1"),
equals("SFS 1.1"),
disjoint("SFS 1.1"),
intersects("SFS 1.1"),
touches("SFS 1.1"),
crosses("SFS 1.1"),
within("SFS 1.1"),
contains("SFS 1.1"),
overlaps("SFS 1.1"),
relate("SFS 1.1"),
distance("SFS 1.1"),
buffer("SFS 1.1"),
convexhull("SFS 1.1"),
intersection("SFS 1.1"),
geomunion("SFS 1.1"), //is actually UNION but this conflicts with SQL UNION construct
difference("SFS 1.1"),
symdifference("SFS 1.1"),
//the distance within function - dwithin(geom, geom, distance) : boolean)
dwithin("common"),
//the transform function - transform(geom, epsg-code): geometry
transform("common");
 
private final String description;
 
SpatialFunction(String specification) {
this.description = specification;
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/HBSpatialExtension.java
New file
0,0 → 1,236
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
import org.hibernatespatial.cfg.GeometryFactoryHelper;
import org.hibernatespatial.cfg.HSConfiguration;
import org.hibernatespatial.helper.PropertyFileReader;
import org.hibernatespatial.mgeom.MGeometryFactory;
import org.hibernatespatial.spi.SpatialDialectProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
 
/**
* This is the bootstrap class that is used to get an
* <code>SpatialDialect</code>.
* <p/>
* It also provides a default <code>SpatialDialect</code>.
* <code>GeometryUserType</code>s that do not have a <code>dialect</code>
* parameter use this default.
* <p/>
* The default <code>SpatialDialect</code> will be the first one that is
* returned by the <code>getDefaultDialect</code> method of the provider at
* least if it is non null.
*
* @author Karel Maesen
*/
public class HBSpatialExtension {
 
protected static List<SpatialDialectProvider> providers = new ArrayList<SpatialDialectProvider>();
 
private static final Logger log = LoggerFactory.getLogger(HBSpatialExtension.class);
 
private static SpatialDialect defaultSpatialDialect = null;
 
private static final String DIALECT_PROP_NAME = "hibernate.spatial.dialect";
 
private static HSConfiguration configuration = null;
 
private static MGeometryFactory defaultGeomFactory = new MGeometryFactory();
 
private static boolean configured = false;
 
static {
 
log.info("Initializing HBSpatialExtension");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Enumeration<URL> resources = null;
try {
resources = loader.getResources("META-INF/services/"
+ SpatialDialectProvider.class.getName());
Set<String> names = new HashSet<String>();
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
InputStream is = url.openStream();
try {
names.addAll(providerNamesFromReader(is));
} finally {
is.close();
}
}
 
for (String s : names) {
try {
log.info("Attempting to load Hibernate Spatial Provider "
+ s);
SpatialDialectProvider provider = (SpatialDialectProvider) loader
.loadClass(s).newInstance();
providers.add(provider);
} catch (Exception e) {
throw new HibernateSpatialException(
"Problem loading provider class", e);
}
 
}
} catch (IOException e) {
throw new HibernateSpatialException("No "
+ SpatialDialectProvider.class.getName()
+ " found in META-INF/services", e);
}
 
// configuration - check if there is a system property
String dialectProp = System.getProperty(DIALECT_PROP_NAME);
if (dialectProp != null) {
HSConfiguration hsConfig = new HSConfiguration();
hsConfig.setDefaultDialect(dialectProp);
setConfiguration(hsConfig);
}
 
// configuration - load the config file
log.info("Checking for default configuration file.");
HSConfiguration hsConfig = new HSConfiguration();
if (hsConfig.configure()) {
configuration = hsConfig;
}
 
}
 
/**
* Make sure nobody can instantiate this class
*/
private HBSpatialExtension() {
}
 
public static void setConfiguration(HSConfiguration c) {
log.info("Setting configuration object:" + c);
configuration = c;
//if the HSExtension has already been initialized,
//then it should be reconfigured.
if (configured == true) {
forceConfigure();
}
}
 
private static synchronized void configure() {
// // do nothing if already configured
if (configured) {
return;
}
configured = true;
forceConfigure();
 
 
}
 
private static void forceConfigure() {
// if no configuration object, take the first dialect that is available.
if (configuration == null) {
setDefaultSpatialDialect(providers.get(0).getDefaultDialect());
return;
} else {
log.info("Configuring HBSpatialExtension from "
+ configuration.getSource());
String dialectName = configuration.getDefaultDialect();
if (dialectName != null) {
SpatialDialect dialect = createSpatialDialect(dialectName);
if (dialect != null) {
log.info("Setting Spatial Dialect to : " + dialectName);
setDefaultSpatialDialect(dialect);
}
}
 
// trying to create a defaultGeometryFactory
log.info("Creating default Geometry Factory");
defaultGeomFactory = GeometryFactoryHelper
.createGeometryFactory(configuration);
 
}
 
if (defaultSpatialDialect == null) {
log.warn("Hibernate Spatial Configured but no spatial dialect");
} else {
log.info("Hibernate Spatial configured. Using dialect: "
+ defaultSpatialDialect.getClass().getCanonicalName());
}
}
 
public static HSConfiguration getConfiguration() {
return configuration;
}
 
/**
* @param dialect
*/
private static void setDefaultSpatialDialect(SpatialDialect dialect) {
defaultSpatialDialect = dialect;
}
 
public static SpatialDialect getDefaultSpatialDialect() {
configure();
return defaultSpatialDialect;
}
 
public static SpatialDialect createSpatialDialect(String dialectName) {
SpatialDialect dialect = null;
for (SpatialDialectProvider provider : providers) {
dialect = provider.createSpatialDialect(dialectName);
if (dialect != null) {
break;
}
}
if (dialect == null) {
throw new HibernateSpatialException(
"No SpatialDialect provider for persistenceUnit "
+ dialectName);
}
return dialect;
}
 
//TODO -- this is not thread-safe!
//find another way to initialize
 
public static MGeometryFactory getDefaultGeomFactory() {
configure();
return defaultGeomFactory;
}
 
// Helper methods
 
private static Set<String> providerNamesFromReader(InputStream is)
throws IOException {
PropertyFileReader reader = new PropertyFileReader(is);
return reader.getNonCommentLines();
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialAggregate.java
New file
0,0 → 1,36
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
/**
* Enumeration of types of Spatial Aggregation
*
* @author Karel Maesen
*/
public interface SpatialAggregate {
 
public static final int EXTENT = 1;
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/readers/BasicFeatureReader.java
New file
0,0 → 1,97
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.readers;
 
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.*;
import org.hibernate.criterion.Restrictions;
import org.hibernate.metadata.ClassMetadata;
import org.hibernatespatial.criterion.SpatialFilter;
import org.hibernatespatial.criterion.SpatialRestrictions;
import org.hibernatespatial.helper.FinderException;
import org.hibernatespatial.helper.GeometryPropertyFinder;
 
/**
* A {@link FeatureReader} that uses the {@link FeatureAdapter}
* to dynamically adapt retrieved objects to the Feature interface.
*
* @author Karel Maesen
*/
public class BasicFeatureReader implements FeatureReader {
 
private StatelessSession session = null;
private ScrollableResults results = null;
private final ClassMetadata metadata;
private final Transaction tx;
private final int fetchSize = 1024;
 
public BasicFeatureReader(Class entityClass, SessionFactory sf, Geometry filterGeom, String attributeFilter) throws FinderException {
this.session = sf.openStatelessSession();
this.metadata = sf.getClassMetadata(entityClass);
String geomProp;
 
Criteria crit = this.session.createCriteria(entityClass);
if (filterGeom != null) {
GeometryPropertyFinder gp = new GeometryPropertyFinder();
geomProp = gp.find(this.metadata);
SpatialFilter filter = SpatialRestrictions.filter(geomProp,
filterGeom);
crit.add(filter);
}
if (attributeFilter != null) {
crit.add(Restrictions.sqlRestriction(attributeFilter));
}
// set explicit fetch size (necessary for postgresql)
crit.setFetchSize(fetchSize);
// ensure that there is no autocommit;
tx = this.session.beginTransaction();
this.results = crit.scroll(ScrollMode.FORWARD_ONLY);
}
 
 
public void close() {
this.tx.commit();
this.results.close();
this.results = null;
this.session.close();
 
}
 
public boolean hasNext() {
return this.results.next();
}
 
public Feature next() {
Object[] currentRow = this.results.get();
if (currentRow == null) {
this.close();
throw new RuntimeException("Reading beyond the Scrollable Results.");
}
Object f = currentRow[0];
return FeatureAdapter.adapt(f, this.metadata);
}
 
 
}
Property changes:
Added: svn:keywords
+ Id
Added: svn:mergeinfo
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/readers/Reader.java
New file
0,0 → 1,11
package org.hibernatespatial.readers;
 
public interface Reader<T> {
public boolean hasNext();
public T next();
 
public void close();
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/readers/Feature.java
New file
0,0 → 1,44
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.readers;
 
import com.vividsolutions.jts.geom.Geometry;
 
/**
* A minimal interface for features, understood as being objects having minimally
* geometry and identifier properties.
*
* @author Karel Maesen
*
*/
public interface Feature {
 
public Object getId();
public Geometry getGeometry();
public Object getAttribute(String name);
}
Property changes:
Added: svn:keywords
+ Id
Added: svn:mergeinfo
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/readers/FeatureAdapter.java
New file
0,0 → 1,148
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.readers;
 
import org.hibernate.EntityMode;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.property.Getter;
import org.hibernate.util.ReflectHelper;
import org.hibernatespatial.helper.FinderException;
import org.hibernatespatial.helper.GeometryPropertyFinder;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
/**
* Adapts arbitrary objects to the {@link Feature} interface using dynamic proxying.
*
* @author Karel Maesen
*/
public class FeatureAdapter {
 
public static Feature adapt(Object o, ClassMetadata cf) {
 
return (Feature) Proxy.newProxyInstance(o.getClass().getClassLoader(),
new Class[]{Feature.class},
new FeatureInvocationHandler(o, cf));
}
 
static private class FeatureInvocationHandler implements InvocationHandler {
private final Object target;
private final ClassMetadata metadata;
private Method targetGeomGetter;
private Method targetIdGetter;
 
 
private static final Method geomGetter;
private static final Method idGetter;
private static final Method attrGetter;
 
private static GeometryPropertyFinder geomPropertyFinder = new GeometryPropertyFinder();
 
static {
Class featureIntf = Feature.class;
try {
geomGetter = featureIntf.getDeclaredMethod("getGeometry", new Class[]{});
idGetter = featureIntf.getDeclaredMethod("getId", new Class[]{});
attrGetter = featureIntf.getDeclaredMethod("getAttribute", new Class[]{String.class});
} catch (Exception e) {
throw new RuntimeException("Probable programming Error", e);
}
}
 
private FeatureInvocationHandler(Object o, ClassMetadata meta) {
//TODO check if this is sufficiently general. What if not a POJO?
if (meta.getMappedClass(EntityMode.POJO) != o.getClass()) {
throw new RuntimeException("Metadata and POJO class do not cohere");
}
this.target = o;
this.metadata = meta;
}
 
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Method m = getTargetGetter(method, args);
 
if (m == null) {
return method.invoke(this.target, args);
} else {
return m.invoke(this.target);
}
}
 
private Method getTargetGetter(Method invokedMethod, Object[] args) {
try {
if (invokedMethod.equals(geomGetter)) {
if (this.targetGeomGetter == null) {
this.targetGeomGetter = getGeomGetter();
}
return this.targetGeomGetter;
} else if (invokedMethod.equals(idGetter)) {
if (this.targetIdGetter == null) {
this.targetIdGetter = getIdGetter();
}
return this.targetIdGetter;
} else if (invokedMethod.equals(attrGetter)) {
String property = (String) args[0];
return getGetterFor(property);
} else {
return null;
}
} catch (Exception e) {
throw new RuntimeException("Problem getting suitable target method for method: " + invokedMethod.getName(), e);
}
 
}
 
private Method getGetterFor(String property) {
Class cl = this.metadata.getMappedClass(EntityMode.POJO);
Getter getter = ReflectHelper.getGetter(cl, property);
return getter.getMethod();
}
 
private Method getGeomGetter() {
try {
String prop = getGeometryPropertyName();
return getGetterFor(prop);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
 
public String getGeometryPropertyName() throws FinderException {
return this.geomPropertyFinder.find(this.metadata);
}
 
public Method getIdGetter() {
String prop = this.metadata.getIdentifierPropertyName();
return getGetterFor(prop);
}
 
}
 
 
}
 
Property changes:
Added: svn:keywords
+ Id
Added: svn:mergeinfo
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/readers/FeatureReader.java
New file
0,0 → 1,44
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.readers;
 
 
 
/**
* Interface to iterate over <code>Feature</code>s
* in a database through Hibernate Spatial.
*
* @author Karel Maesen
*
*/
public interface FeatureReader {
public boolean hasNext();
public Feature next();
 
public void close();
 
}
Property changes:
Added: svn:keywords
+ Id
Added: svn:mergeinfo
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/spi/SpatialDialectProvider.java
New file
0,0 → 1,70
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.spi;
 
import org.hibernatespatial.SpatialDialect;
 
/**
* Interface that is implemented by a SpatialDialect Provider.
* <p/>
* A <class>SpatialDialectProvider</class> creates a SpatialDialect for one or
* more database systems. These databases are identified by a dialect string.
* Usually this is the fully qualified class name of a
* <code>org.hibernate.dialect.Dialect</code> or <code>SpatialDialect</code>
* implementation
*
* @author Karel Maesen, Geovise BVBA
*/
 
public interface SpatialDialectProvider {
 
/**
* create Spatial Dialect with the provided name.
*
* @param dialect Name of the dialect to create.
* @return a SpatialDialect
*/
public SpatialDialect createSpatialDialect(String dialect);
 
/**
* Returns the default dialect for this provider.
*
* @return The Default Dialect provided by the implementation.
* <p/>
* Implementations should never return null for this method.
*/
public SpatialDialect getDefaultDialect();
 
/**
* Returns the Dialect names
* <p/>
* This method must return the canonical class names of the Spatialdialect
* implementations that this provider provides.
*
* @return array of dialect names.
*/
public String[] getSupportedDialects();
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/SpatialFilter.java
New file
0,0 → 1,91
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.criterion;
 
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.TypedValue;
import org.hibernatespatial.SpatialDialect;
import org.hibernatespatial.helper.EnvelopeAdapter;
 
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
 
/**
* An implementation for a simple spatial filter. This <code>Criterion</code>
* restricts the resultset to those features whose bounding box overlaps the
* filter geometry. It is intended for quick, but inexact spatial queries.
*
* @author Karel Maesen
*/
public class SpatialFilter implements Criterion {
 
private static final long serialVersionUID = 1L;
 
private String propertyName = null;
 
private Geometry filter = null;
 
public SpatialFilter(String propertyName, Geometry filter) {
this.propertyName = propertyName;
this.filter = filter;
}
 
public SpatialFilter(String propertyName, Envelope envelope, int SRID) {
this.propertyName = propertyName;
this.filter = EnvelopeAdapter.toPolygon(envelope, SRID);
 
}
 
public TypedValue[] getTypedValues(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] { criteriaQuery.getTypedValue(criteria,
propertyName, filter) };
}
 
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
SessionFactoryImplementor factory = criteriaQuery.getFactory();
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria,
this.propertyName);
Dialect dialect = factory.getDialect();
if (dialect instanceof SpatialDialect) {
SpatialDialect seDialect = (SpatialDialect) dialect;
return seDialect.getSpatialFilterExpression(columns[0]);
} else
throw new IllegalStateException(
"Dialect must be spatially enabled dialect");
 
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/DWithinExpression.java
New file
0,0 → 1,45
package org.hibernatespatial.criterion;
 
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.engine.TypedValue;
import org.hibernate.type.StandardBasicTypes;
import org.hibernatespatial.SpatialDialect;
import org.hibernatespatial.SpatialFunction;
 
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/1/11
*/
public class DWithinExpression implements Criterion {
 
 
private final String propertyName;
private final Geometry geometry;
private final double distance;
 
public DWithinExpression(String propertyName, Geometry geometry, double distance) {
this.propertyName = propertyName;
this.geometry = geometry;
this.distance = distance;
}
 
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String column = ExpressionUtil.findColumn(propertyName, criteria, criteriaQuery);
SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect(criteriaQuery, SpatialFunction.dwithin);
return spatialDialect.getDWithinSQL(column);
 
}
 
 
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[]{
criteriaQuery.getTypedValue(criteria, propertyName, geometry),
new TypedValue(StandardBasicTypes.DOUBLE, Double.valueOf(distance), EntityMode.POJO)
};
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/SpatialRestrictions.java
New file
0,0 → 1,149
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.criterion;
 
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.criterion.Criterion;
import org.hibernatespatial.SpatialRelation;
 
/**
* Static Factory Class for creating spatial criterion types.
* <p/>
* <p>
* The criterion types created by this class implement the spatial query
* expressions of the OpenGIS Simple Features Specification for SQL, Revision
* 1.1.
* <p/>
* In addition, it provides for a simple spatial <code>filter</code> that
* works mostly using the spatial index. This corresponds to the Oracle
* Spatial's "SDO_FILTER" function, or the "&&" operator of PostGIS.
* </p>
*
* @author Karel Maesen
*/
public class SpatialRestrictions {
 
SpatialRestrictions() {
}
 
public static SpatialRelateExpression eq(String propertyName, Geometry value) {
return new SpatialRelateExpression(propertyName, value,
SpatialRelation.EQUALS);
}
 
 
public static SpatialRelateExpression within(String propertyName, Geometry value) {
return new SpatialRelateExpression(propertyName, value,
SpatialRelation.WITHIN);
}
 
public static SpatialRelateExpression contains(String propertyName, Geometry value) {
return new SpatialRelateExpression(propertyName, value,
SpatialRelation.CONTAINS);
}
 
public static SpatialRelateExpression crosses(String propertyName, Geometry value) {
return new SpatialRelateExpression(propertyName, value,
SpatialRelation.CROSSES);
}
 
public static SpatialRelateExpression disjoint(String propertyName, Geometry value) {
return new SpatialRelateExpression(propertyName, value,
SpatialRelation.DISJOINT);
}
 
public static SpatialRelateExpression intersects(String propertyName, Geometry value) {
return new SpatialRelateExpression(propertyName, value,
SpatialRelation.INTERSECTS);
}
 
public static SpatialRelateExpression overlaps(String propertyName, Geometry value) {
return new SpatialRelateExpression(propertyName, value,
SpatialRelation.OVERLAPS);
}
 
public static SpatialRelateExpression touches(String propertyName, Geometry value) {
return new SpatialRelateExpression(propertyName, value,
SpatialRelation.TOUCHES);
}
 
public static SpatialFilter filter(String propertyName, Geometry filter) {
return new SpatialFilter(propertyName, filter);
}
 
public static SpatialFilter filter(String propertyName, Envelope envelope,
int SRID) {
return new SpatialFilter(propertyName, envelope, SRID);
}
 
public static Criterion distanceWithin(String propertyName, Geometry geometry, double distance) {
return new DWithinExpression(propertyName, geometry, distance);
}
 
 
public static Criterion havingSRID(String propertyName, int srid) {
return new HavingSridExpression(propertyName, srid);
}
 
public static Criterion isEmpty(String propertyName) {
return new IsEmptyExpression(propertyName, true);
}
 
public static Criterion isNotEmpty(String propertyName) {
return new IsEmptyExpression(propertyName, false);
}
 
public static Criterion spatialRestriction(int relation,
String propertyName, Geometry value) {
switch (relation) {
case SpatialRelation.CONTAINS:
return contains(propertyName, value);
case SpatialRelation.CROSSES:
return crosses(propertyName, value);
case SpatialRelation.DISJOINT:
return disjoint(propertyName, value);
case SpatialRelation.INTERSECTS:
return intersects(propertyName, value);
case SpatialRelation.EQUALS:
return eq(propertyName, value);
case SpatialRelation.FILTER:
return filter(propertyName, value);
case SpatialRelation.OVERLAPS:
return overlaps(propertyName, value);
case SpatialRelation.TOUCHES:
return touches(propertyName, value);
case SpatialRelation.WITHIN:
return within(propertyName, value);
default:
throw new IllegalArgumentException(
"Non-existant spatial relation passed.");
}
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/IsEmptyExpression.java
New file
0,0 → 1,37
package org.hibernatespatial.criterion;
 
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.engine.TypedValue;
import org.hibernatespatial.SpatialDialect;
import org.hibernatespatial.SpatialFunction;
 
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/15/11
*/
public class IsEmptyExpression implements Criterion {
 
private final static TypedValue[] NO_VALUES = new TypedValue[0];
 
private final String propertyName;
private final boolean isEmpty;
 
public IsEmptyExpression(String propertyName, boolean isEmpty) {
this.propertyName = propertyName;
this.isEmpty = isEmpty;
}
 
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String column = ExpressionUtil.findColumn(propertyName, criteria, criteriaQuery);
SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect(criteriaQuery, SpatialFunction.isempty);
return spatialDialect.getIsEmptySQL(column, isEmpty);
}
 
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return NO_VALUES;
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/SpatialRelateExpression.java
New file
0,0 → 1,111
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.criterion;
 
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.TypedValue;
import org.hibernatespatial.SpatialDialect;
 
/**
* An implementation of the <code>Criterion</code> interface that implements
* spatial queries: queries to the effect that a geometry property has a
* specific spatial relation to a test geometry
*
* @author Karel Maesen
*/
public class SpatialRelateExpression implements Criterion {
 
/**
* The geometry property
*/
private String propertyName = null;
 
/**
* The test geometry
*/
private Geometry value = null;
 
/**
* The spatial relation that is queried for.
*/
private int spatialRelation = -1;
 
private static final long serialVersionUID = 1L;
 
public SpatialRelateExpression(String propertyName,
Geometry value, int spatialRelation) {
this.propertyName = propertyName;
this.spatialRelation = spatialRelation;
this.value = value;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.criterion.Criterion#getTypedValues(org.hibernate.Criteria,
* org.hibernate.criterion.CriteriaQuery)
*/
 
public TypedValue[] getTypedValues(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[]{criteriaQuery.getTypedValue(criteria,
propertyName, value)};
 
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.criterion.Criterion#toSqlString(org.hibernate.Criteria,
* org.hibernate.criterion.CriteriaQuery)
*/
 
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
SessionFactoryImplementor factory = criteriaQuery.getFactory();
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria,
this.propertyName);
Dialect dialect = factory.getDialect();
if (dialect instanceof SpatialDialect) {
SpatialDialect seDialect = (SpatialDialect) dialect;
return seDialect.getSpatialRelateSQL(columns[0],
spatialRelation);
} else {
throw new IllegalStateException(
"Dialect must be spatially enabled dialect");
}
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/ExpressionUtil.java
New file
0,0 → 1,36
package org.hibernatespatial.criterion;
 
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.dialect.Dialect;
import org.hibernatespatial.SpatialDialect;
import org.hibernatespatial.SpatialFunction;
 
/**
* This class assists in the formation of a SQL-fragment in the various spatial query expressions.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/15/11
*/
public class ExpressionUtil {
 
public static SpatialDialect getSpatialDialect(CriteriaQuery criteriaQuery, SpatialFunction function) {
Dialect dialect = criteriaQuery.getFactory().getDialect();
if (!(dialect instanceof SpatialDialect)) {
throw new HibernateException("A spatial expression requires a spatial dialect.");
}
SpatialDialect spatialDialect = (SpatialDialect) dialect;
if (!spatialDialect.supports(function)) {
throw new HibernateException(function + " function not supported by this dialect");
}
return spatialDialect;
}
 
public static String findColumn(String propertyName, Criteria criteria, CriteriaQuery criteriaQuery) {
String[] columns = criteriaQuery.findColumns(propertyName, criteria);
if (columns.length != 1)
throw new HibernateException("Spatial Expression may only be used with single-column properties");
return columns[0];
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/SpatialProjections.java
New file
0,0 → 1,79
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.criterion;
 
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.SimpleProjection;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;
import org.hibernatespatial.SpatialAggregate;
import org.hibernatespatial.SpatialDialect;
 
/**
* @author Karel Maesen
*
*/
public class SpatialProjections {
 
public static Projection extent(final String propertyName) {
return new SimpleProjection() {
 
public Type[] getTypes(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
return new Type[] { criteriaQuery.getType(criteria,
propertyName) };
}
 
public String toSqlString(Criteria criteria, int position,
CriteriaQuery criteriaQuery) throws HibernateException {
StringBuilder stbuf = new StringBuilder();
 
SessionFactoryImplementor factory = criteriaQuery.getFactory();
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, propertyName);
Dialect dialect = factory.getDialect();
if (dialect instanceof SpatialDialect) {
SpatialDialect seDialect = (SpatialDialect) dialect;
 
stbuf.append(seDialect.getSpatialAggregateSQL(columns[0],
SpatialAggregate.EXTENT));
stbuf.append(" as y").append(position).append('_');
return stbuf.toString();
}
return null;
}
 
};
 
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/HavingSridExpression.java
New file
0,0 → 1,39
package org.hibernatespatial.criterion;
 
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.engine.TypedValue;
import org.hibernate.type.StandardBasicTypes;
import org.hibernatespatial.SpatialDialect;
import org.hibernatespatial.SpatialFunction;
 
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/9/11
*/
public class HavingSridExpression implements Criterion {
 
private final String propertyName;
private final int srid;
 
public HavingSridExpression(String propertyName, int srid) {
this.propertyName = propertyName;
this.srid = srid;
}
 
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String column = ExpressionUtil.findColumn(propertyName, criteria, criteriaQuery);
SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect(criteriaQuery, SpatialFunction.srid);
return spatialDialect.getHavingSridSQL(column);
}
 
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[]{
new TypedValue(StandardBasicTypes.INTEGER, Integer.valueOf(srid), EntityMode.POJO)
};
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/cfg/HSProperty.java
New file
0,0 → 1,41
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.cfg;
 
/**
* This enum contains the configurable properties of the Hibernate Spatial
* Extension.
*
* @author Karel Maesen
*
*/
public enum HSProperty {
 
DEFAULT_DIALECT, PRECISION_MODEL, PRECISION_MODEL_SCALE
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/cfg/HSConfiguration.java
New file
0,0 → 1,206
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.cfg;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.hibernate.cfg.Configuration;
 
/**
* Configuration information for the Hibernate Spatial Extension.
*
* @author Karel Maesen
*
*
*/
public class HSConfiguration extends Properties {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static Logger logger = LoggerFactory.getLogger(HSConfiguration.class);
 
private String source = "runtime configuration object";
 
private HSProperty[] HSProperties;
 
public HSConfiguration() {
HSProperties = HSProperty.values();
}
 
public String getDefaultDialect() {
return getProperty(HSProperty.DEFAULT_DIALECT.toString());
}
 
public void setDefaultDialect(String dialect) {
setProperty(HSProperty.DEFAULT_DIALECT, dialect);
}
 
public String getPrecisionModel() {
return getProperty(HSProperty.PRECISION_MODEL.toString());
}
 
public void setPrecisionModel(String precisionModel) {
setProperty(HSProperty.PRECISION_MODEL, precisionModel);
}
 
public String getPrecisionModelScale() {
return getProperty(HSProperty.PRECISION_MODEL_SCALE.toString());
}
 
public void setPrecisionModelScale(String scale) {
setProperty(HSProperty.PRECISION_MODEL_SCALE, scale);
}
 
protected String getProperty(HSProperty property) {
return getProperty(property.toString());
}
 
protected void setProperty(HSProperty property, String value) {
setProperty(property.toString(), value);
}
 
/**
* Derives the configuration from the Hibernate Configuration object.
*
* @param hibernateConfig
* Hibernate Configuration object
* @return true, if the configuration is successfull.
*/
public boolean configure(Configuration hibernateConfig) {
String dialect = hibernateConfig.getProperty("hibernate.dialect");
setProperty(HSProperty.DEFAULT_DIALECT, dialect);
return true;
}
 
/**
* Gets the configuriation from the hibernate-spatail.cfg.xml file on the
* classpath.
*
* @return true if the configuration is successfull;
*/
public boolean configure() {
return configure("hibernate-spatial.cfg.xml");
}
 
/**
* Gets the configuriation from the specified file.
*
* @param resource
* the configuration file
* @return true if the configuration is successfull;
*/
public boolean configure(File resource) {
logger.info("Attempting to configuring from file: "
+ resource.getName());
try {
this.source = resource.getAbsolutePath();
return doConfigure(new FileInputStream(resource));
} catch (FileNotFoundException e) {
logger.warn("could not find file: " + resource + ".");
} catch (DocumentException e) {
logger.warn("Failed to load configuration file: " + resource
+ ".\nCause:" + e.getMessage());
}
return false;
}
 
/**
* The source file or URL for this configuration.
*
* @return The source name (file or URL).
*/
public String getSource() {
return this.source;
}
 
/**
* Gets the configuriation from the specified file on the class path.
*
* @param resource
* the configuration file
* @return true if the configuration is successfull;
*/
public boolean configure(String resource) {
logger.debug("Attempting to load configuration from file: " + resource);
ClassLoader classLoader = Thread.currentThread()
.getContextClassLoader();
try {
URL url = classLoader.getResource(resource);
if (url == null) {
logger.info("No configuration file " + resource
+ " on the classpath.");
return false;
}
this.source = url.getFile();
return doConfigure(url.openStream());
} catch (Exception e) {
logger.warn("Failed to load configuration file: " + resource
+ ".\nCause:" + e.getMessage());
}
return false;
}
 
private boolean doConfigure(InputStream stream) throws DocumentException {
try {
SAXReader reader = new SAXReader();
Document configDoc = reader.read(stream);
Element root = configDoc.getRootElement();
for (HSProperty hsprop : HSProperties) {
Element propEl = root.element(hsprop.toString().toLowerCase());
if (propEl != null) {
setProperty(hsprop, propEl.getText());
}
}
return true;
} finally {
try {
stream.close();
} catch (Exception e) {
} // Can't do anything about this.
}
}
public String toString(){
return this.source;
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/cfg/GeometryFactoryHelper.java
New file
0,0 → 1,84
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.cfg;
 
import com.vividsolutions.jts.geom.PrecisionModel;
import org.hibernatespatial.mgeom.MGeometryFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.Map;
 
/**
* Factory for creating a <code>GeometryFactory</code> given a map of
* configuration parameters.
*
* @author Karel Maesen, Geovise BVBA
*/
public class GeometryFactoryHelper {
 
private static Logger logger = LoggerFactory.getLogger(GeometryFactoryHelper.class);
 
public static MGeometryFactory createGeometryFactory(Map map) {
 
if (map == null) {
return new MGeometryFactory();
}
String precisionModelName = null;
Double scale = null;
if (map.containsKey(HSProperty.PRECISION_MODEL.toString())) {
precisionModelName = (String) map.get(HSProperty.PRECISION_MODEL
.toString());
}
if (map.containsKey(HSProperty.PRECISION_MODEL_SCALE.toString())) {
scale = Double.parseDouble(((String) map
.get(HSProperty.PRECISION_MODEL_SCALE.toString())));
}
if (scale != null && !scale.isNaN() && precisionModelName != null
&& precisionModelName.equalsIgnoreCase("FIXED")) {
return new MGeometryFactory(new PrecisionModel(scale));
}
if (precisionModelName == null) {
return new MGeometryFactory();
}
if (precisionModelName.equalsIgnoreCase("FIXED")) {
return new MGeometryFactory(
new PrecisionModel(PrecisionModel.FIXED));
}
if (precisionModelName.equalsIgnoreCase("FLOATING")) {
return new MGeometryFactory(new PrecisionModel(
PrecisionModel.FLOATING));
}
if (precisionModelName.equalsIgnoreCase("FLOATING_SINGLE")) {
return new MGeometryFactory(new PrecisionModel(
PrecisionModel.FLOATING_SINGLE));
}
logger.warn("Configured for PrecisionModel: " + precisionModelName
+ " but don't know how to instantiate.");
logger.warn("Reverting to default GeometryModel");
return new MGeometryFactory();
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialDialect.java
New file
0,0 → 1,138
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
import org.hibernate.usertype.UserType;
 
import java.io.Serializable;
 
/**
* Describes the features of a spatially enabled dialect.
*
* @author Karel Maesen
*/
public interface SpatialDialect extends Serializable {
 
/**
* Returns the SQL fragment for the SQL WHERE-clause when parsing
* <code>org.hibernatespatial.criterion.SpatialRelateExpression</code>s
* into prepared statements.
* <p/>
*
* @param columnName The name of the geometry-typed column to which the relation is
* applied
* @param spatialRelation The type of spatial relation (as defined in
* <code>SpatialRelation</code>).
* @return SQL fragment for use in the SQL WHERE-clause.
*/
public String getSpatialRelateSQL(String columnName, int spatialRelation);
 
/**
* Returns the SQL fragment for the SQL WHERE-expression when parsing
* <code>org.hibernatespatial.criterion.SpatialFilterExpression</code>s
* into prepared statements.
*
* @param columnName- the name of the geometry-typed column to which the filter is
* be applied.
* @return
*/
public String getSpatialFilterExpression(String columnName);
 
/**
* @return an instance of the Geometry Usertype that this dialect provides
*/
public UserType getGeometryUserType();
 
/**
* @param columnName the name of the Geometry property
* @param aggregation the type of <code>SpatialAggregate</code>
* @return the SQL fragment for the projection
*/
public String getSpatialAggregateSQL(String columnName, int aggregation);
 
/**
* Returns the SQL fragment when parsing a <code>DWithinExpression</code>.
*
* @param columnName the geometry column to test against
* @return
*/
public String getDWithinSQL(String columnName);
 
/**
* Returns the SQL fragment when parsing an <code>HavingSridExpression</code>.
*
* @param columnName the geometry column to test against
* @return
*/
public String getHavingSridSQL(String columnName);
 
 
/**
* Returns the SQL fragment when parsing a <code>IsEmptyExpression</code> or
* <code>IsNotEmpty</code> expression.
*
* @param columnName the geometry column
* @param isEmpty whether the geometry is tested for empty or non-empty
* @return
*/
public String getIsEmptySQL(String columnName, boolean isEmpty);
 
/**
* Returns the name of the native database type for storing geometries.
*
* @return type name
*/
public String getDbGeometryTypeName();
 
/**
* Does this dialect support explicit two-phase filtering when filtering on
* spatial relations?
* <p/>
* In two-phase filtering you can form a SQL WHERE-expression that searches
* for matching objects in two phases. A first phase performs a quick
* bounding box search for neighbouring objects. The second phase calculates
* the precise spatial relation between the testsuite-suite object and the results of
* the first phase.
* <p/>
*/
@Deprecated
public boolean isTwoPhaseFiltering();
 
/**
* Returns true if this <code>SpatialDialect</code> supports a specific filtering function.
* <p/>
* This is intended to signal DB-support for fast window queries, or MBR-overlap queries
*/
public boolean supportsFiltering();
 
/**
* Does this dialect supports the specified <code>SpatialFunction</code>.
*
* @param function <code>SpatialFunction</code>
* @return true if this <code>SpatialDialect</code> supports the spatial function specified by the function parameter.
*/
public boolean supports(SpatialFunction function);
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometryFactory.java
New file
0,0 → 1,104
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.*;
 
/**
* Extension of the GeometryFactory for constructing Geometries with Measure
* support.
*
* @see com.vividsolutions.jts.geom.GeometryFactory
*/
public class MGeometryFactory extends GeometryFactory {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
public MGeometryFactory(PrecisionModel precisionModel, int SRID,
MCoordinateSequenceFactory coordinateSequenceFactory) {
super(precisionModel, SRID, coordinateSequenceFactory);
}
 
public MGeometryFactory(MCoordinateSequenceFactory coordinateSequenceFactory) {
super(coordinateSequenceFactory);
}
 
public MGeometryFactory(PrecisionModel precisionModel) {
this(precisionModel, 0, MCoordinateSequenceFactory.instance());
}
 
public MGeometryFactory(PrecisionModel precisionModel, int SRID) {
this(precisionModel, SRID, MCoordinateSequenceFactory.instance());
}
 
public MGeometryFactory() {
this(new PrecisionModel(), 0);
}
 
/**
* Constructs a MLineString using the given Coordinates; a null or empty
* array will create an empty MLineString.
*
* @param coordinates
* array of MCoordinate defining this geometry's vertices
* @see #createLineString(com.vividsolutions.jts.geom.Coordinate[])
* @return An instance of MLineString containing the coordinates
*/
public MLineString createMLineString(MCoordinate[] coordinates) {
return createMLineString(coordinates != null ? getCoordinateSequenceFactory()
.create(coordinates)
: null);
}
 
public MultiMLineString createMultiMLineString(MLineString[] mlines,
double mGap) {
return new MultiMLineString(mlines, mGap, this);
}
 
public MultiMLineString createMultiMLineString(MLineString[] mlines) {
return new MultiMLineString(mlines, 0.0d, this);
}
 
/**
* Creates a MLineString using the given CoordinateSequence; a null or empty
* CoordinateSequence will create an empty MLineString.
*
* @param coordinates
* a CoordinateSequence possibly empty, or null
* @return An MLineString instance based on the <code>coordinates</code>
* @see #createLineString(com.vividsolutions.jts.geom.CoordinateSequence)
*/
public MLineString createMLineString(CoordinateSequence coordinates) {
return new MLineString(coordinates, this);
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/DoubleComparator.java
New file
0,0 → 1,101
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
/**
* This utility class is used to testsuite-suite doubles for equality
*
* @author Didier H. Besset <p/> Adapted from "Object-oriented implementation of
* numerical methods"
*/
//TODO: This class should be removed.
public final class DoubleComparator {
 
private final static int radix = computeRadix();
 
private final static double machinePrecision = computeMachinePrecision();
 
private final static double defaultNumericalPrecision = Math
.sqrt(machinePrecision);
 
private static int computeRadix() {
int radix = 0;
double a = 1.0d;
double tmp1, tmp2;
do {
a += a;
tmp1 = a + 1.0d;
tmp2 = tmp1 - a;
} while (tmp2 - 1.0d != 0.0d);
double b = 1.0d;
while (radix == 0) {
b += b;
tmp1 = a + b;
radix = (int) (tmp1 - a);
}
return radix;
}
 
public static int getRadix() {
return radix;
}
 
private static double computeMachinePrecision() {
double floatingRadix = getRadix();
double inverseRadix = 1.0d / floatingRadix;
double machinePrecision = 1.0d;
double tmp = 1.0d + machinePrecision;
while (tmp - 1.0d != 0.0) {
machinePrecision *= inverseRadix;
tmp = 1.0d + machinePrecision;
}
return machinePrecision;
}
 
public static double getMachinePrecision() {
return machinePrecision;
}
 
public static double defaultNumericalPrecision() {
return defaultNumericalPrecision;
}
 
public static boolean equals(double a, double b) {
return equals(a, b, defaultNumericalPrecision());
}
 
public static boolean equals(double a, double b, double precision) {
double norm = Math.max(Math.abs(a), Math.abs(b));
boolean result = norm < precision || Math.abs(a - b) < precision * norm;
return result || (Double.isNaN(a) && Double.isNaN(b));
}
 
public static void main(String[] args) {
System.out.println("Machine precision = " + getMachinePrecision());
System.out.println("Radix = " + getRadix());
System.out.println("default numerical precision = "
+ defaultNumericalPrecision());
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinate.java
New file
0,0 → 1,273
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
 
/**
* This coordinate class supports 4D coordinates, where the first 3 measures
* (x,y,z) are coordinates in a 3 dimensional space (cartesian for example), and
* the fourth is a measure value used for linear referencing. Note that the
* measure value is independent of whether the (x,y,z) values are used. For
* example, the z value can not be used while the measure value is used. <p/>
* While this class extends the Coordinate class, it can be used seamlessly as a
* substitute in the event that the Measure value is not used. In these cases
* the Measure value shall simply be Double.NaN
*
* @see com.vividsolutions.jts.geom.Coordinate
*/
public class MCoordinate extends Coordinate {
/**
*
*/
private static final long serialVersionUID = 1L;
 
public double m;
 
/**
* Default constructor
*/
public MCoordinate() {
super();
this.m = Double.NaN;
}
 
public MCoordinate(double x, double y, double z, double m) {
super(x, y, z);
this.m = m;
}
 
public MCoordinate(double x, double y) {
super(x, y);
m = Double.NaN;
}
 
public MCoordinate(Coordinate coord) {
super(coord);
if (coord instanceof MCoordinate)
m = ((MCoordinate) coord).m;
else
m = Double.NaN;
}
 
public MCoordinate(MCoordinate coord) {
super(coord);
m = coord.m;
}
 
/**
* TODO: I'd like to see this method added to the base Coordinate class
* Returns the ordinate value specified in this Coordinate instance. The
* index of the desired ordinates are specified in the CoordinateSequence
* class; hence CoodinateSequence.X returns the x ordinate,
* CoodinateSequence.Y the y ordinate, CoodinateSequence.Z the z ordinate,
* and CoodinateSequence.M the m ordinate. Note that the dimension may not
* imply the desired ordinate in the case where one is using a 2 dimensional
* geometry with a measure value. Therefore, these constants are highly
* recommended.
*
* @param ordinateIndex
* the desired ordinate index.
* @return the value of stored in the ordinate index. Incorrect or unused
* indexes shall return Double.NaN
*/
public double getOrdinate(int ordinateIndex) {
switch (ordinateIndex) {
case CoordinateSequence.X:
return this.x;
case CoordinateSequence.Y:
return this.y;
case CoordinateSequence.Z:
return this.z;
case CoordinateSequence.M:
return this.m;
}
return Double.NaN;
}
 
/**
* TODO: I'd like to see this method added to the base Coordinate class Sets
* the value for a given ordinate. This should be specified using the
* CoordinateSequence ordinate index constants.
*
* @param ordinateIndex
* the desired ordinate index.
* @param value
* the new ordinate value
* @throws IllegalArgumentException
* if the ordinateIndex value is incorrect
* @see #getOrdinate(int)
*/
public void setOrdinate(int ordinateIndex, double value) {
switch (ordinateIndex) {
case CoordinateSequence.X:
this.x = value;
break;
case CoordinateSequence.Y:
this.y = value;
break;
case CoordinateSequence.Z:
this.z = value;
break;
case CoordinateSequence.M:
this.m = value;
break;
default:
throw new IllegalArgumentException("invalid ordinateIndex");
}
}
 
public boolean equals2DWithMeasure(Coordinate other) {
boolean result = this.equals2D(other);
if (result) {
MCoordinate mc = convertCoordinate(other);
result = (Double.compare(this.m, mc.m) == 0);
}
return result;
}
 
public boolean equals3DWithMeasure(Coordinate other) {
boolean result = this.equals3D(other);
if (result) {
MCoordinate mc = convertCoordinate(other);
result = (Double.compare(this.m, mc.m) == 0);
}
return result;
}
 
/*
* Default equality is now equality in 2D-plane. This is required to remain
* consistent with JTS.
*
* TODO:check whether this method is still needed.
*
* (non-Javadoc)
*
* @see com.vividsolutions.jts.geom.Coordinate#equals(java.lang.Object)
*/
public boolean equals(Object other) {
if (other instanceof Coordinate) {
return equals2D((Coordinate) other);
} else {
return false;
}
}
 
public String toString() {
return "(" + x + "," + y + "," + z + "," + " m=" + m + ")";
}
 
/**
* Converts a standard Coordinate instance to an MCoordinate instance. If
* coordinate is already an instance of an MCoordinate, then it is simply
* returned. In cases where it is converted, the measure value of the
* coordinate is initialized to Double.NaN.
*
* @param coordinate
* The coordinate to be converted
* @return an instance of MCoordinate corresponding to the
* <code>coordinate</code> parameter
*/
public static MCoordinate convertCoordinate(Coordinate coordinate) {
if (coordinate == null)
return null;
if (coordinate instanceof MCoordinate)
return (MCoordinate) coordinate;
return new MCoordinate(coordinate);
}
 
/**
* A convenience method for creating a MCoordinate instance where there are
* only 2 coordinates and an lrs measure value. The z value of the
* coordinate shall be set to Double.NaN
*
* @param x
* the x coordinate value
* @param y
* the y coordinate value
* @param m
* the lrs measure value
* @return The constructed MCoordinate value
*/
public static MCoordinate create2dWithMeasure(double x, double y, double m) {
return new MCoordinate(x, y, Double.NaN, m);
}
 
/**
* A convenience method for creating a MCoordinate instance where there are
* only 2 coordinates and an lrs measure value. The z and m value of the
* coordinate shall be set to Double.NaN
*
* @param x
* the x coordinate value
* @param y
* the y coordinate value
* @return The constructed MCoordinate value
*/
public static MCoordinate create2d(double x, double y) {
return new MCoordinate(x, y, Double.NaN, Double.NaN);
}
 
/**
* A convenience method for creating a MCoordinate instance where there are
* 3 coordinates and an lrs measure value.
*
* @param x
* the x coordinate value
* @param y
* the y coordinate value
* @param z
* the z coordinate value
* @param m
* the lrs measure value
* @return The constructed MCoordinate value
*/
public static MCoordinate create3dWithMeasure(double x, double y, double z,
double m) {
return new MCoordinate(x, y, z, m);
}
 
/**
* A convenience method for creating a MCoordinate instance where there are
* 3 coordinates but no lrs measure value. The m value of the coordinate
* shall be set to Double.NaN
*
* @param x
* the x coordinate value
* @param y
* the y coordinate value
* @param z
* the z coordinate value
* @return The constructed MCoordinate value
*/
public static MCoordinate create3d(double x, double y, double z) {
return new MCoordinate(x, y, z, Double.NaN);
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/EventLocator.java
New file
0,0 → 1,79
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
 
import java.util.ArrayList;
import java.util.List;
 
public class EventLocator {
 
/**
* Returns the point on the specified MGeometry where its measure equals the specified position.
*
* @return a Point Geometry
* @throws MGeometryException
*/
public static Point getPointGeometry(MGeometry lrs, double position)
throws MGeometryException {
if (lrs == null) {
throw new MGeometryException("Non-null MGeometry parameter is required.");
}
Coordinate c = lrs.getCoordinateAtM(position);
Point pnt = lrs.getFactory().createPoint(c);
copySRID(lrs.asGeometry(), pnt);
return pnt;
}
 
public static MultiMLineString getLinearGeometry(MGeometry lrs,
double begin, double end) throws MGeometryException {
 
if (lrs == null) {
throw new MGeometryException("Non-null MGeometry parameter is required.");
}
MGeometryFactory factory = (MGeometryFactory) lrs.getFactory();
CoordinateSequence[] cs = lrs.getCoordinatesBetween(begin, end);
List<MLineString> linestrings = new ArrayList<MLineString>(cs.length);
for (int i = 0; i < cs.length; i++) {
MLineString ml;
if (cs[i].size() >= 2) {
ml = factory.createMLineString(cs[i]);
linestrings.add(ml);
}
}
MultiMLineString result = factory.createMultiMLineString(linestrings.toArray(new MLineString[linestrings.size()]));
copySRID(lrs.asGeometry(), result.asGeometry());
return result;
}
 
public static void copySRID(Geometry source, Geometry target) {
target.setSRID(source.getSRID());
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinateSequenceFactory.java
New file
0,0 → 1,86
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import java.io.Serializable;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
 
/**
* Creates MCoordinateSequenceFactory internally represented as an array of
* {@link MCoordinate}s.
*/
public class MCoordinateSequenceFactory implements CoordinateSequenceFactory,
Serializable {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static MCoordinateSequenceFactory instance = new MCoordinateSequenceFactory();
 
private MCoordinateSequenceFactory() {
}
 
/**
* Returns the singleton instance of MCoordinateSequenceFactory
*/
public static MCoordinateSequenceFactory instance() {
return instance;
}
 
/**
* Returns an MCoordinateSequence based on the given array -- the array is
* used directly if it is an instance of MCoordinate[]; otherwise it is
* copied.
*/
public CoordinateSequence create(Coordinate[] coordinates) {
return coordinates instanceof MCoordinate[] ? new MCoordinateSequence(
(MCoordinate[]) coordinates) : new MCoordinateSequence(
coordinates);
}
 
public CoordinateSequence create(CoordinateSequence coordSeq) {
return new MCoordinateSequence(coordSeq);
}
 
/**
* Creates a MCoordinateSequence instance initialized to the size parameter.
* Note that the dimension argument is ignored.
*
* @see com.vividsolutions.jts.geom.CoordinateSequenceFactory#create(int,int)
*/
public CoordinateSequence create(int size, int dimension) {
return new MCoordinateSequence(size);
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MultiMLineString.java
New file
0,0 → 1,279
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.*;
 
public class MultiMLineString extends MultiLineString implements MGeometry {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private final double mGap; // difference in m between end of one part and
 
private boolean monotone = false;
 
private boolean strictMonotone = false;
 
/**
* @param MlineStrings the <code>MLineString</code>s for this
* <code>MultiMLineString</code>, or <code>null</code> or an
* empty array to create the empty geometry. Elements may be
* empty <code>LineString</code>s, but not <code>null</code>s.
*/
public MultiMLineString(MLineString[] MlineStrings, double mGap,
GeometryFactory factory) {
super(MlineStrings, factory);
this.mGap = mGap;
determineMonotone();
}
 
/**
* TODO Improve this, and add more unit tests
*/
private void determineMonotone() {
this.monotone = true;
this.strictMonotone = true;
if (this.isEmpty()) {
return;
}
int mdir = MGeometry.CONSTANT;
for (int i = 0; i < this.geometries.length; i++) {
MLineString ml = (MLineString) this.geometries[0];
if (!ml.isEmpty()) {
mdir = ml.getMeasureDirection();
break;
}
}
for (int i = 0; i < this.geometries.length; i++) {
MLineString ml = (MLineString) this.geometries[i];
if (ml.isEmpty()) continue;
// check whether mlinestrings are all pointing in same direction,
// and
// are monotone
if (!ml.isMonotone(false)
|| (ml.getMeasureDirection() != mdir && !(ml
.getMeasureDirection() == MGeometry.CONSTANT))) {
this.monotone = false;
break;
}
 
if (!ml.isMonotone(true) || (ml.getMeasureDirection() != mdir)) {
this.strictMonotone = false;
break;
}
 
// check whether the geometry measures do not overlap or
// are inconsistent with previous parts
if (i > 0) {
MLineString mlp = (MLineString) this.geometries[i - 1];
if (mdir == MGeometry.INCREASING) {
if (mlp.getMaxM() > ml.getMinM()) {
monotone = false;
} else if (mlp.getMaxM() >= ml.getMinM()) {
strictMonotone = false;
}
} else {
if (mlp.getMinM() < ml.getMaxM()) {
monotone = false;
} else if (mlp.getMinM() <= ml.getMaxM()) {
strictMonotone = false;
}
}
 
}
 
}
if (!monotone) {
this.strictMonotone = false;
}
 
}
 
protected void geometryChangedAction() {
determineMonotone();
}
 
public String getGeometryType() {
return "MultiMLineString";
}
 
public double getMGap() {
return this.mGap;
}
 
public double getMatCoordinate(Coordinate co, double tolerance)
throws MGeometryException {
 
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
 
double mval = Double.NaN;
double dist = Double.POSITIVE_INFINITY;
 
com.vividsolutions.jts.geom.Point p = this.getFactory().createPoint(co);
 
// find points within tolerance for getMatCoordinate
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
// go to next MLineString if the input point is beyond tolerance
if (ml.distance(p) > tolerance)
continue;
 
MCoordinate mc = ml.getClosestPoint(co, tolerance);
if (mc != null) {
double d = mc.distance(co);
if (d <= tolerance && d < dist) {
dist = d;
mval = mc.m;
}
}
}
return mval;
}
 
public Object clone() {
MultiLineString ml = (MultiLineString) super.clone();
return ml;
}
 
public void measureOnLength(boolean keepBeginMeasure) {
double startM = 0.0;
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
if (i == 0) {
ml.measureOnLength(keepBeginMeasure);
} else {
ml.measureOnLength(false);
}
if (startM != 0.0) {
ml.shiftMeasure(startM);
}
startM += ml.getLength() + mGap;
}
this.geometryChanged();
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#getCoordinateAtM(double)
*/
 
public Coordinate getCoordinateAtM(double m) throws MGeometryException {
 
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
 
Coordinate c = null;
for (int i = 0; i < this.getNumGeometries(); i++) {
MGeometry mg = (MGeometry) this.getGeometryN(i);
c = mg.getCoordinateAtM(m);
if (c != null) {
return c;
}
}
return null;
}
 
public CoordinateSequence[] getCoordinatesBetween(double begin, double end)
throws MGeometryException {
 
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE,
"Operation requires geometry with monotonic measures");
}
 
if (this.isEmpty())
return null;
 
java.util.ArrayList<CoordinateSequence> ar = new java.util.ArrayList<CoordinateSequence>();
 
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
for (CoordinateSequence cs : ml.getCoordinatesBetween(begin, end)) {
if (cs.size() > 0) {
ar.add(cs);
}
}
}
return ar.toArray(new CoordinateSequence[ar.size()]);
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#getMinM()
*/
 
public double getMinM() {
double minM = Double.POSITIVE_INFINITY;
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
double d = ml.getMinM();
if (d < minM)
minM = d;
}
return minM;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#getMaxM()
*/
 
public double getMaxM() {
double maxM = Double.NEGATIVE_INFINITY;
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
double d = ml.getMaxM();
if (d > maxM)
maxM = d;
}
return maxM;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#isMonotone()
*/
 
public boolean isMonotone(boolean strictMonotone) {
return strictMonotone ? this.strictMonotone : monotone;
}
 
public Geometry asGeometry() {
return this;
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometryException.java
New file
0,0 → 1,71
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
/**
* @author Karel Maesen
*
*
*/
public class MGeometryException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
public final static int OPERATION_REQUIRES_MONOTONE = 1;
 
public final static int UNIONM_ON_DISJOINT_MLINESTRINGS = 2;
 
public final static int GENERAL_MGEOMETRY_EXCEPTION = 0;
 
// type of exception
private final int type;
 
public MGeometryException(String s) {
super(s);
type = 0;
}
 
public MGeometryException(int type) {
super();
this.type = type;
}
 
public MGeometryException(int type, String msg) {
super(msg);
this.type = type;
}
 
public int getType() {
return type;
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometry.java
New file
0,0 → 1,187
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
 
import java.io.Serializable;
 
/**
* Defines geometries that carry measures in their CoordinateSequence.
*
* @author Karel Maesen
*/
 
public interface MGeometry extends Cloneable, Serializable {
 
/**
* Measures are increasing in the direction of the MGeometry
*/
public final static int INCREASING = 1;
 
/**
* Measures are constant across the Geometry
*/
public final static int CONSTANT = 0;
 
/**
* Measures are decreasing in the direction of the MGeometry
*/
public final static int DECREASING = -1;
 
/**
* Measures are not monotone along the Geometry
*/
public final static int NON_MONOTONE = -3;
 
/**
* Returns the measure value at the Coordinate
*
* @param c
* the Coordinate for which the measure value is sought
* @param tolerance
* distance to the MGeometry within which Coordinate c has to lie
* @return the measure value if Coordinate c is within tolerance of the
* Geometry, else Double.NaN
* <p>
* When the geometry is a ring or is self-intersecting more
* coordinates may be determined by one coordinate. In that case,
* the lowest measure is returned.
* @throws MGeometryException
* when this MGeometry is not monotone
*/
public double getMatCoordinate(Coordinate c, double tolerance)
throws MGeometryException;
 
/**
* Builds measures along the Geometry based on the length from the beginning
* (first coordinate) of the Geometry.
*
* @param keepBeginMeasure -
* if true, the measure of the first coordinate is maintained and
* used as start value, unless this measure is Double.NaN
*/
public void measureOnLength(boolean keepBeginMeasure);
 
/**
* Returns the Coordinate along the Geometry at the measure value
*
* @param m
* measure value
* @return the Coordinate if m is on the MGeometry otherwise null
* @throws MGeometryException
* when MGeometry is not monotone
*/
public Coordinate getCoordinateAtM(double m) throws MGeometryException;
 
/**
* Returns the coordinatesequence(s) containing all coordinates between the
* begin and end measures.
*
* @param begin
* begin measure
* @param end
* end measure
* @return an array containing all coordinatesequences in order between
* begin and end. Each CoordinateSequence covers a contiguous
* stretch of the MGeometry.
* @throws MGeometryException
* when this MGeometry is not monotone
*/
public CoordinateSequence[] getCoordinatesBetween(double begin, double end)
throws MGeometryException;
 
/**
* Returns the GeometryFactory of the MGeometry
*
* @return the GeometryFactory of this MGeometry
*/
public GeometryFactory getFactory();
 
/**
* Returns the minimum M-value of the MGeometry
*
* @return the minimum M-value
*/
public double getMinM();
 
/**
* Returns the maximum M-value of the MGeometry
*
* @return the maximum M-value
*/
public double getMaxM();
 
/**
* Determine whether the LRS measures (not the x,y,z coordinates) in the
* Coordinate sequence of the geometry is Monotone. Monotone implies that
* all measures in a sequence of coordinates are consecutively increasing,
* decreasing or equal according to the definition of the implementing
* geometry. Monotonicity is a pre-condition for most operations on
* MGeometries. The following are examples on Monotone measure sequences on
* a line string:
* <ul>
* <li> [0,1,2,3,4] - Monotone Increasing
* <li> [4,3,2,1] - Monotone Decreasing
* <li> [0,1,1,2,3] - Non-strict Monotone Increasing
* <li> [5,3,3,0] - Non-strict Monotone Decreasing
* </ul>
*
* @return true if the coordinates in the CoordinateSequence of the geometry
* are monotone.
*/
public boolean isMonotone(boolean strict);
 
// /**
// * Strict Monotone is similar to Monotone, with the added constraint that
// all measure coordinates
// * in the CoordinateSequence are ONLY consecutively increasing or
// decreasing. No consecutive
// * duplicate measures are allowed.
// *
// * @return true if the coordinates in the CoordinateSequence of the
// geometry are strictly monotone; that is, consitently
// * increasing or decreasing with no duplicate measures.
// * @see #isMonotone()
// */
// public boolean isStrictMonotone();
 
/**
* Returns this <code>MGeometry</code> as a <code>Geometry</code>.
*
* Modifying the returned <code>Geometry</code> will result in internal state changes.
*
* @return this object as a Geometry.
*/
public Geometry asGeometry();
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MLineString.java
New file
0,0 → 1,689
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.*;
 
import java.util.ArrayList;
import java.util.List;
 
/**
* An implementation of the LineString class with the addition that the
* containing CoordinateSequence can carry measure. Note that this is not a
* strict requirement of the class, and can interact with non-measure geometries
* for JTS topological comparisons regardless.
*
* @author Karel Maesen
*/
public class MLineString extends LineString implements MGeometry {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private boolean monotone = false;
 
private boolean strictMonotone = false;
 
public MLineString(CoordinateSequence points, GeometryFactory factory) {
super(points, factory);
determineMonotone();
}
 
public Object clone() {
LineString ls = (LineString) super.clone();
return new MLineString(ls.getCoordinateSequence(), this.getFactory());
}
 
/**
* Calculates whether the measures in the CoordinateSequence are monotone
* and strict monotone. The strict parameter indicates whether the
* determination should apply the definition of "strict monotonicity" or
* non-strict.
*/
private void determineMonotone() {
this.monotone = true;
this.strictMonotone = true;
if (!this.isEmpty()) {
double m[] = this.getMeasures();
// short circuit if the first value is NaN
if (Double.isNaN(m[0])) {
this.monotone = false;
this.strictMonotone = false;
} else {
int result = 0;
int prevResult = 0;
for (int i = 1; i < m.length && this.monotone; i++) {
result = Double.compare(m[i - 1], m[i]);
this.monotone = !(result * prevResult < 0 || Double
.isNaN(m[i]));
this.strictMonotone &= this.monotone && result != 0;
prevResult = result;
}
}
}
// if not monotone, then certainly not strictly monotone
assert (!(this.strictMonotone && !this.monotone));
}
 
protected void geometryChangedAction() {
determineMonotone();
}
 
/**
* @param co input coordinate in the neighbourhood of the MLineString
* @param tolerance max. distance that co may be from this MLineString
* @return an MCoordinate on this MLineString with appropriate M-value
*/
public MCoordinate getClosestPoint(Coordinate co, double tolerance)
throws MGeometryException {
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
 
if (!this.isEmpty()) {
LineSegment seg = new LineSegment();
Coordinate[] coAr = this.getCoordinates();
seg.p0 = coAr[0];
double d = 0.0;
double projfact = 0.0;
double minDist = Double.POSITIVE_INFINITY;
MCoordinate mincp = null;
for (int i = 1; i < coAr.length; i++) {
seg.p1 = coAr[i];
Coordinate cp = seg.closestPoint(co);
d = cp.distance(co);
if (d <= tolerance && d <= minDist) {
MCoordinate testcp = new MCoordinate(cp);
projfact = seg.projectionFactor(cp);
testcp.m = ((MCoordinate) coAr[i - 1]).m
+ projfact
* (((MCoordinate) coAr[i]).m - ((MCoordinate) coAr[i - 1]).m);
if (d < minDist || testcp.m < mincp.m) {
mincp = testcp;
minDist = d;
}
}
seg.p0 = seg.p1;
}
if (minDist > tolerance) {
return null;
} else {
return mincp;
}
} else {
return null;
}
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#getCoordinateAtM(double)
*/
 
public Coordinate getCoordinateAtM(double m) throws MGeometryException {
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
if (this.isEmpty()) {
return null;
} else {
double mval[] = this.getMeasures();
double lb = getMinM();
double up = getMaxM();
 
if (m < lb || m > up) {
return null;
} else {
// determine linesegment that contains m;
for (int i = 1; i < mval.length; i++) {
if ((mval[i - 1] <= m && m <= mval[i])
|| (mval[i] <= m && m <= mval[i - 1])) {
MCoordinate p0 = (MCoordinate) this
.getCoordinateN(i - 1);
MCoordinate p1 = (MCoordinate) this.getCoordinateN(i);
// r indicates how far in this segment the M-values lies
double r = (m - mval[i - 1]) / (mval[i] - mval[i - 1]);
double dx = r * (p1.x - p0.x);
double dy = r * (p1.y - p0.y);
double dz = r * (p1.z - p0.z);
MCoordinate nc = new MCoordinate(p0.x + dx, p0.y + dy,
p0.z + dz, m);
return nc;
}
}
}
}
return null;
}
 
/*
* (non-Javadoc)
*
* @see com.vividsolutions.jts.geom.Geometry#getGeometryType()
*/
 
public String getGeometryType() {
return "MLineString";
}
 
/*
* (non-Javadoc)
*
* @see com.vividsolutions.jts.geom.Geometry#getMatCoordinate(com.vividsolutions.jts.geom.Coordinate,
* double)
*/
 
public double getMatCoordinate(Coordinate c, double tolerance)
throws MGeometryException {
MCoordinate mco = this.getClosestPoint(c, tolerance);
if (mco == null) {
return Double.NaN;
} else {
return (mco.m);
}
}
 
/**
* get the measure of the specified coordinate
*
* @param n index of the coordinate
* @return The measure of the coordinate. If the coordinate does not exists
* it returns Double.NaN
*/
public double getMatN(int n) {
return ((MCoordinate) (this.getCoordinates()[n])).m;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry##MGeometry#getMaxM()
*/
 
public double getMaxM() {
if (this.isEmpty()) {
return Double.NaN;
} else {
double[] measures = this.getMeasures();
 
if (this.getMeasureDirection() == MGeometry.INCREASING) {
return measures[measures.length - 1];
} else if (this.getMeasureDirection() == MGeometry.DECREASING
|| this.getMeasureDirection() == MGeometry.CONSTANT) {
return measures[0];
} else {
double ma = Double.NEGATIVE_INFINITY;
for (int i = 0; i < measures.length; i++) {
if (ma < measures[i]) {
ma = measures[i];
}
}
return ma;
}
}
}
 
 
/**
* Copies the coordinates of the specified array that fall between fromM and toM to a CoordinateSubSequence.
* <p/>
* The CoordinateSubSequence also contains the array indices of the first and last coordinate in firstIndex, resp.
* lastIndex. If there are no coordinates between fromM and toM, then firstIndex will contain -1, and lastIndex
* will point to the coordinate that is close to fromM or toM.
* <p/>
* This function expects that fromM is less than or equal to toM, and that the coordinates in the array are
* sorted monotonic w.r.t. to their m-values.
*
* @param mcoordinates
* @param fromM
* @param toM
* @param direction INCREASING or DECREASING
* @return a CoordinateSubSequence containing the coordinates between fromM and toM
*/
private CoordinateSubSequence copyCoordinatesBetween(MCoordinate[] mcoordinates, double fromM, double toM, int direction) {
CoordinateSubSequence sseq = new CoordinateSubSequence();
sseq.firstIndex = -1;
sseq.lastIndex = -1;
for (int i = 0; i < mcoordinates.length; i++) {
double m = mcoordinates[i].m;
 
if (m >= fromM && m <= toM) {
sseq.vertices.add(mcoordinates[i]);
if (sseq.firstIndex == -1) {
sseq.firstIndex = i;
}
}
if (direction == MGeometry.INCREASING) {
if (m > toM) break;
sseq.lastIndex = i;
} else {
if (m < fromM) break;
sseq.lastIndex = i;
}
 
}
return sseq;
}
 
/**
* Interpolates a coordinate between mco1, mco2, based on the measured value m
*/
private MCoordinate interpolate(MCoordinate mco1, MCoordinate mco2, double m) {
if (mco1.m > mco2.m) {
MCoordinate h = mco1;
mco1 = mco2;
mco2 = h;
}
 
if (m < mco1.m || m > mco2.m)
throw new IllegalArgumentException("Internal Error: m-value not in interval mco1.m/mco2.m");
 
double r = (m - mco1.m) / (mco2.m - mco1.m);
MCoordinate interpolated = new MCoordinate(
mco1.x + r * (mco2.x - mco1.x),
mco1.y + r * (mco2.y - mco1.y),
mco1.z + r * (mco2.z - mco1.z),
m);
this.getPrecisionModel().makePrecise(interpolated);
return interpolated;
}
 
 
public CoordinateSequence[] getCoordinatesBetween(double fromM, double toM) throws MGeometryException {
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE,
"Operation requires geometry with monotonic measures");
}
 
if (fromM > toM) {
return getCoordinatesBetween(toM, fromM);
}
 
MCoordinateSequence mc;
if (!isOverlapping(fromM, toM)) {
mc = new MCoordinateSequence(new MCoordinate[]{});
} else {
MCoordinate[] mcoordinates = (MCoordinate[]) this.getCoordinates();
CoordinateSubSequence subsequence = copyCoordinatesBetween(mcoordinates, fromM, toM, this.getMeasureDirection());
addInterpolatedEndPoints(fromM, toM, mcoordinates, subsequence);
MCoordinate[] ra = subsequence.vertices.toArray(new MCoordinate[subsequence.vertices.size()]);
mc = new MCoordinateSequence(ra);
}
return new MCoordinateSequence[]{mc};
}
 
private boolean isOverlapping(double fromM, double toM) {
if (this.isEmpty()) return false;
//WARNING: this assumes a monotonic increasing or decreasing measures
MCoordinate beginCo = (MCoordinate) this.getCoordinateN(0);
MCoordinate endCo = (MCoordinate) this.getCoordinateN(this.getNumPoints() - 1);
return !(Math.min(fromM, toM) > Math.max(beginCo.m, endCo.m) ||
Math.max(fromM, toM) < Math.min(beginCo.m, endCo.m));
}
 
private void addInterpolatedEndPoints(double fromM, double toM, MCoordinate[] mcoordinates, CoordinateSubSequence subsequence) {
 
boolean increasing = this.getMeasureDirection() == MGeometry.INCREASING;
double fM, lM;
if (increasing) {
fM = fromM;
lM = toM;
} else {
fM = toM;
lM = fromM;
}
 
if (subsequence.firstIndex == -1) {
MCoordinate fi = interpolate(mcoordinates[subsequence.lastIndex], mcoordinates[subsequence.lastIndex + 1], fM);
subsequence.vertices.add(fi);
MCoordinate li = interpolate(mcoordinates[subsequence.lastIndex], mcoordinates[subsequence.lastIndex + 1], lM);
subsequence.vertices.add(li);
} else {
//interpolate a first vertex if necessary
if (subsequence.firstIndex > 0 && (
increasing && mcoordinates[subsequence.firstIndex].m > fromM ||
!increasing && mcoordinates[subsequence.firstIndex].m < toM
)) {
MCoordinate fi = interpolate(mcoordinates[subsequence.firstIndex - 1], mcoordinates[subsequence.firstIndex], fM);
subsequence.vertices.add(0, fi);
}
//interpolate a last vertex if necessary
if (subsequence.lastIndex < (mcoordinates.length - 1) && (
increasing && mcoordinates[subsequence.lastIndex].m < toM ||
!increasing && mcoordinates[subsequence.lastIndex].m > fromM)) {
MCoordinate li = interpolate(mcoordinates[subsequence.lastIndex], mcoordinates[subsequence.lastIndex + 1], lM);
subsequence.vertices.add(li);
}
}
}
 
private MCoordinate[] inverse(MCoordinate[] mcoordinates) {
for (int i = 0; i < mcoordinates.length / 2; i++) {
MCoordinate h = mcoordinates[i];
mcoordinates[i] = mcoordinates[mcoordinates.length - 1 - i];
mcoordinates[mcoordinates.length - 1 - i] = h;
}
return mcoordinates;
}
 
 
/**
* determine the direction of the measures w.r.t. the direction of the line
*
* @return MGeometry.NON_MONOTONE<BR>
* MGeometry.INCREASING<BR>
* MGeometry.DECREASING<BR>
* MGeometry.CONSTANT
*/
public int getMeasureDirection() {
if (!this.monotone) {
return MGeometry.NON_MONOTONE;
}
MCoordinate c1 = (MCoordinate) this.getCoordinateN(0);
MCoordinate c2 = (MCoordinate) this
.getCoordinateN(this.getNumPoints() - 1);
 
if (c1.m < c2.m) {
return MGeometry.INCREASING;
} else if (c1.m > c2.m) {
return MGeometry.DECREASING;
} else {
return MGeometry.CONSTANT;
}
}
 
/**
* @return the array with measure-values of the vertices
*/
public double[] getMeasures() {
// return the measures of all vertices
if (!this.isEmpty()) {
Coordinate[] co = this.getCoordinates();
double[] a = new double[co.length];
for (int i = 0; i < co.length; i++) {
a[i] = ((MCoordinate) co[i]).m;
}
return a;
} else {
return null;
}
}
 
public double getMinM() {
 
if (this.isEmpty()) {
return Double.NaN;
} else {
double[] a = this.getMeasures();
if (this.getMeasureDirection() == MGeometry.INCREASING) {
return a[0];
} else if (this.getMeasureDirection() == MGeometry.DECREASING
|| this.getMeasureDirection() == MGeometry.CONSTANT) {
return a[a.length - 1];
} else {
 
double ma = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i++) {
if (ma > a[i]) {
ma = a[i];
}
}
return ma;
}
}
}
 
/**
* Assigns the first coordinate in the CoordinateSequence to the
* <code>beginMeasure</code> and the last coordinate in the
* CoordinateSequence to the <code>endMeasure</code>. Measure values for
* intermediate coordinates are then interpolated proportionally based on
* their 2d offset of the overall 2d length of the LineString.
* <p/>
* If the beginMeasure and endMeasure values are equal it is assumed that
* all intermediate coordinates shall be the same value.
*
* @param beginMeasure Measure value for first coordinate
* @param endMeasure Measure value for last coordinate
*/
public void interpolate(double beginMeasure, double endMeasure) {
if (this.isEmpty()) {
return;
}
// interpolate with first vertex = beginMeasure; last vertex =
// endMeasure
Coordinate[] coordinates = this.getCoordinates();
double length = this.getLength();
double mLength = endMeasure - beginMeasure;
double d = 0;
boolean continuous = DoubleComparator.equals(beginMeasure, endMeasure);
double m = beginMeasure;
MCoordinate prevCoord = MCoordinate.convertCoordinate(coordinates[0]);
prevCoord.m = m;
MCoordinate curCoord;
for (int i = 1; i < coordinates.length; i++) {
curCoord = MCoordinate.convertCoordinate(coordinates[i]);
if (continuous) {
curCoord.m = beginMeasure;
} else {
d += curCoord.distance(prevCoord);
m = beginMeasure + (d / length) * mLength;
curCoord.m = m;
prevCoord = curCoord;
}
}
this.geometryChanged();
assert (this.isMonotone(false)) : "interpolate function should always leave MGeometry monotone";
}
 
/**
* Returns the measure length of the segment. This method assumes that the
* length of the LineString is defined by the absolute value of (last
* coordinate - first coordinate) in the CoordinateSequence. If either
* measure is not defined or the CoordinateSequence contains no coordinates,
* then Double.NaN is returned. If there is only 1 element in the
* CoordinateSequence, then 0 is returned.
*
* @return The measure length of the LineString
*/
public double getMLength() {
if (getCoordinateSequence().size() == 0)
return Double.NaN;
if (getCoordinateSequence().size() == 1)
return 0.0D;
else {
int lastIndex = getCoordinateSequence().size() - 1;
double begin = getCoordinateSequence().getOrdinate(0,
CoordinateSequence.M);
double end = getCoordinateSequence().getOrdinate(lastIndex,
CoordinateSequence.M);
return (Double.isNaN(begin) || Double.isNaN(end)) ? Double.NaN
: Math.abs(end - begin);
}
}
 
/**
* Indicates whether the MLineString has monotone increasing or decreasing
* M-values
*
* @return <code>true if MLineString is empty or M-values are increasing (NaN) values, false otherwise</code>
*/
public boolean isMonotone(boolean strict) {
return strict ? this.strictMonotone : this.monotone;
}
 
public Geometry asGeometry() {
return this;
}
 
// TODO get clear on function and implications of normalize
// public void normalize(){
//
// }
 
public void measureOnLength(boolean keepBeginMeasure) {
 
Coordinate[] co = this.getCoordinates();
if (!this.isEmpty()) {
double d = 0.0;
MCoordinate pco = (MCoordinate) co[0];
if (!keepBeginMeasure || Double.isNaN(pco.m)) {
pco.m = 0.0d;
}
MCoordinate mco;
for (int i = 1; i < co.length; i++) {
mco = (MCoordinate) co[i];
d += mco.distance(pco);
mco.m = d;
pco = mco;
}
this.geometryChanged();
}
}
 
/**
* This method reverses the measures assigned to the Coordinates in the
* CoordinateSequence without modifying the positional (x,y,z) values.
*/
public void reverseMeasures() {
if (!this.isEmpty()) {
double m[] = this.getMeasures();
MCoordinate[] coar = (MCoordinate[]) this.getCoordinates();
double nv;
for (int i = 0; i < m.length; i++) {
nv = m[m.length - 1 - i];
coar[i].m = nv;
}
this.geometryChanged();
}
}
 
public void setMeasureAtIndex(int index, double m) {
getCoordinateSequence().setOrdinate(index, CoordinateSequence.M, m);
this.geometryChanged();
}
 
/**
* Shift all measures by the amount parameter. A negative amount shall
* subtract the amount from the measure. Note that this can make for
* negative measures.
*
* @param amount the positive or negative amount by which to shift the measures
* in the CoordinateSequence.
*/
public void shiftMeasure(double amount) {
Coordinate[] coordinates = this.getCoordinates();
MCoordinate mco;
if (!this.isEmpty()) {
for (int i = 0; i < coordinates.length; i++) {
mco = (MCoordinate) coordinates[i];
mco.m = mco.m + amount;
}
}
this.geometryChanged();
}
 
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
 
public String toString() {
Coordinate[] ar = this.getCoordinates();
StringBuffer buf = new StringBuffer(ar.length * 17 * 3);
for (int i = 0; i < ar.length; i++) {
buf.append(ar[i].x);
buf.append(" ");
buf.append(ar[i].y);
buf.append(" ");
buf.append(((MCoordinate) ar[i]).m);
buf.append("\n");
}
return buf.toString();
}
 
public MLineString unionM(MLineString l) throws MGeometryException {
 
if (!this.monotone || !l.monotone) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
Coordinate[] linecoar = l.getCoordinates();
if (l.getMeasureDirection() == MGeometry.DECREASING) {
CoordinateArrays.reverse(linecoar);
}
Coordinate[] thiscoar = this.getCoordinates();
if (this.getMeasureDirection() == MGeometry.DECREASING) {
CoordinateArrays.reverse(thiscoar);
}
 
// either the last coordinate in thiscoar equals the first in linecoar;
// or the last in linecoar equals the first in thiscoar;
MCoordinate lasttco = (MCoordinate) thiscoar[thiscoar.length - 1];
MCoordinate firsttco = (MCoordinate) thiscoar[0];
MCoordinate lastlco = (MCoordinate) linecoar[linecoar.length - 1];
MCoordinate firstlco = (MCoordinate) linecoar[0];
 
MCoordinate[] newcoar = new MCoordinate[thiscoar.length
+ linecoar.length - 1];
if (lasttco.equals2D(firstlco)
&& DoubleComparator.equals(lasttco.m, firstlco.m)) {
System.arraycopy(thiscoar, 0, newcoar, 0, thiscoar.length);
System.arraycopy(linecoar, 1, newcoar, thiscoar.length,
linecoar.length - 1);
} else if (lastlco.equals2D(firsttco)
&& DoubleComparator.equals(lastlco.m, firsttco.m)) {
System.arraycopy(linecoar, 0, newcoar, 0, linecoar.length);
System.arraycopy(thiscoar, 1, newcoar, linecoar.length,
thiscoar.length - 1);
} else {
throw new MGeometryException(
MGeometryException.UNIONM_ON_DISJOINT_MLINESTRINGS);
}
 
CoordinateSequence mcs = this.getFactory()
.getCoordinateSequenceFactory().create(newcoar);
MLineString returnmlinestring = new MLineString(mcs, this.getFactory());
assert (returnmlinestring.isMonotone(false)) : "new unionM-ed MLineString is not monotone";
return returnmlinestring;
}
 
static class CoordinateSubSequence {
private int firstIndex;
private int lastIndex;
private List<MCoordinate> vertices = new ArrayList<MCoordinate>();
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinateSequence.java
New file
0,0 → 1,232
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
 
import java.io.Serializable;
 
/**
* Implements the CoordinateSequence interface. In this implementation,
* Coordinates returned by #toArray and #get are live -- parties that change
* them are actually changing the MCoordinateSequence's underlying data.
*/
public class MCoordinateSequence implements CoordinateSequence, Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
 
private MCoordinate[] coordinates;
 
public static MCoordinate[] copy(Coordinate[] coordinates) {
MCoordinate[] copy = new MCoordinate[coordinates.length];
for (int i = 0; i < coordinates.length; i++) {
copy[i] = new MCoordinate(coordinates[i]);
}
return copy;
}
 
public static MCoordinate[] copy(CoordinateSequence coordSeq) {
MCoordinate[] copy = new MCoordinate[coordSeq.size()];
for (int i = 0; i < coordSeq.size(); i++) {
copy[i] = new MCoordinate(coordSeq.getCoordinate(i));
}
return copy;
}
 
/**
* Copy constructor -- simply aliases the input array, for better
* performance.
*
* @param coordinates
*/
public MCoordinateSequence(MCoordinate[] coordinates) {
this.coordinates = coordinates;
}
 
/**
* Constructor that makes a copy of an array of Coordinates. Always makes a
* copy of the input array, since the actual class of the Coordinates in the
* input array may be different from MCoordinate.
*
* @param copyCoords
*/
public MCoordinateSequence(Coordinate[] copyCoords) {
coordinates = copy(copyCoords);
}
 
/**
* Constructor that makes a copy of a CoordinateSequence.
*
* @param coordSeq
*/
public MCoordinateSequence(CoordinateSequence coordSeq) {
coordinates = copy(coordSeq);
}
 
/**
* Constructs a sequence of a given size, populated with new
* {@link MCoordinate}s.
*
* @param size
* the size of the sequence to create
*/
public MCoordinateSequence(int size) {
coordinates = new MCoordinate[size];
for (int i = 0; i < size; i++) {
coordinates[i] = new MCoordinate();
}
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getDimension()
*/
public int getDimension() {
return 4;
}
 
public Coordinate getCoordinate(int i) {
return coordinates[i];
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getCoordinateCopy(int)
*/
public Coordinate getCoordinateCopy(int index) {
return new Coordinate(coordinates[index]);
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getCoordinate(int,
* com.vividsolutions.jts.geom.Coordinate)
*/
public void getCoordinate(int index, Coordinate coord) {
coord.x = coordinates[index].x;
coord.y = coordinates[index].y;
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getX(int)
*/
public double getX(int index) {
return coordinates[index].x;
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getY(int)
*/
public double getY(int index) {
return coordinates[index].y;
}
 
/**
* @return the measure value of the coordinate in the index
*/
public double getM(int index) {
return coordinates[index].m;
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getOrdinate(int,int)
*/
public double getOrdinate(int index, int ordinateIndex) {
switch (ordinateIndex) {
case CoordinateSequence.X:
return coordinates[index].x;
case CoordinateSequence.Y:
return coordinates[index].y;
case CoordinateSequence.Z:
return coordinates[index].z;
case CoordinateSequence.M:
return coordinates[index].m;
}
return Double.NaN;
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#setOrdinate(int,int,double)
*/
public void setOrdinate(int index, int ordinateIndex, double value) {
switch (ordinateIndex) {
case CoordinateSequence.X:
coordinates[index].x = value;
break;
case CoordinateSequence.Y:
coordinates[index].y = value;
break;
case CoordinateSequence.Z:
coordinates[index].z = value;
break;
case CoordinateSequence.M:
coordinates[index].m = value;
break;
default:
throw new IllegalArgumentException("invalid ordinateIndex");
}
}
 
public Object clone() {
MCoordinate[] cloneCoordinates = new MCoordinate[size()];
for (int i = 0; i < coordinates.length; i++) {
cloneCoordinates[i] = (MCoordinate) coordinates[i].clone();
}
 
return new MCoordinateSequence(cloneCoordinates);
}
 
public int size() {
return coordinates.length;
}
 
public Coordinate[] toCoordinateArray() {
return coordinates;
}
 
public Envelope expandEnvelope(Envelope env) {
for (int i = 0; i < coordinates.length; i++) {
env.expandToInclude(coordinates[i]);
}
return env;
}
 
public String toString() {
StringBuffer strBuf = new StringBuffer();
strBuf.append("MCoordinateSequence [");
for (int i = 0; i < coordinates.length; i++) {
if (i > 0)
strBuf.append(", ");
strBuf.append(coordinates[i]);
}
strBuf.append("]");
return strBuf.toString();
}
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/AbstractDBGeometryType.java
New file
0,0 → 1,214
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
 
import org.hibernate.HibernateException;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
import org.hibernatespatial.cfg.GeometryFactoryHelper;
import org.hibernatespatial.mgeom.MGeometryFactory;
 
import com.vividsolutions.jts.geom.Geometry;
 
/**
* This type is a abstract base type for implementing database specific user
* types for geometry types.
*
* @author Karel Maesen
*/
public abstract class AbstractDBGeometryType implements UserType,
ParameterizedType, Serializable {
private MGeometryFactory geomFactory = null;
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#assemble(java.io.Serializable,
* java.lang.Object)
*/
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object value) throws HibernateException {
return value;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
*/
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#equals(java.lang.Object,
* java.lang.Object)
*/
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (x == null || y == null)
return false;
return ((Geometry) x).equalsExact((Geometry) y);
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
*/
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#isMutable()
*/
public boolean isMutable() {
return false;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,
* java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
Object geomObj = rs.getObject(names[0]);
return convert2JTS(geomObj);
}
 
/**
* Converts the native database geometry object to a JTS Geometry object.
*
* Concrete subclasses should override this method.
*
* @param geomObj
* native database geometry object
* @return JTS Geometry
*/
public abstract Geometry convert2JTS(Object geomObj);
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
* java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, sqlTypes()[0]);
} else {
Geometry jtsGeom = (Geometry) value;
Object dbGeom = conv2DBGeometry(jtsGeom, st.getConnection());
st.setObject(index, dbGeom);
}
}
 
/**
* Converts a JTS geometry object to a native database geometry object.
*
* Concrete subclasses should override this method.
*
* @param jtsGeom
* JTS Geometry
* @return native database geometry object
*/
public abstract Object conv2DBGeometry(Geometry jtsGeom,
Connection connection);
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#replace(java.lang.Object,
* java.lang.Object, java.lang.Object)
*/
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#returnedClass()
*/
public Class returnedClass() {
return Geometry.class;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#sqlTypes()
*
* This should be overriden by concrete subclasses
*/
public abstract int[] sqlTypes();
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.ParameterizedType#setParameterValues(java.util.Properties)
*/
public void setParameterValues(Properties parameters) {
if (parameters != null){
this.geomFactory = GeometryFactoryHelper.createGeometryFactory(parameters);
}
}
public MGeometryFactory getGeometryFactory(){
return (this.geomFactory == null) ? HBSpatialExtension.getDefaultGeomFactory() : this.geomFactory;
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/AttributeInfo.java
New file
0,0 → 1,121
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import javassist.CtClass;
 
import org.hibernatespatial.GeometryUserType;
 
/**
* @author Karel Maesen
*
*
*/
public class AttributeInfo {
 
private String columnName;
 
private String fieldName;
 
private String hibernateType;
private CtClass ctClass;
 
private boolean isIdentifier;
 
public boolean isGeometry() {
return this.hibernateType.equalsIgnoreCase(GeometryUserType.class
.getCanonicalName());
}
 
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((columnName == null) ? 0 : columnName.hashCode());
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AttributeInfo other = (AttributeInfo) obj;
if (columnName == null) {
if (other.columnName != null)
return false;
} else if (!columnName.equals(other.columnName))
return false;
return true;
}
 
public CtClass getCtClass() {
return ctClass;
}
 
public void setCtClass(CtClass ctType) {
this.ctClass = ctType;
}
 
public String getColumnName() {
return columnName;
}
 
public void setColumnName(String columnName) {
this.columnName = columnName;
}
 
public String getFieldName() {
return fieldName;
}
 
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
 
public String getHibernateType() {
return hibernateType;
}
 
public void setHibernateType(String hibernateType) {
this.hibernateType = hibernateType;
}
 
public boolean isIdentifier() {
return isIdentifier;
}
 
public void setIdentifier(boolean isIdentifier) {
this.isIdentifier = isIdentifier;
}
 
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/FeatureMapper.java
New file
0,0 → 1,154
package org.hibernatespatial.pojo;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
 
public class FeatureMapper {
 
private final static Logger LOGGER = LoggerFactory.getLogger(FeatureMapper.class);
 
private final NamingStrategy naming;
private final TypeMapper typeMapper;
 
public FeatureMapper(NamingStrategy naming, TypeMapper typeMapper) {
this.naming = naming;
this.typeMapper = typeMapper;
}
 
public ClassInfo createClassInfo(String catalog, String schema, String tableName, DatabaseMetaData dmd) throws TableNotFoundException, MissingIdentifierException {
String className = naming.createClassName(tableName);
ClassInfo cInfo = new ClassInfo(tableName, className);
readColums(catalog, schema, tableName, dmd, cInfo);
determineIdentifier(catalog, schema, tableName, dmd, cInfo);
return cInfo;
}
 
private void determineIdentifier(String catalog, String schema, String tableName, DatabaseMetaData dmd, ClassInfo cInfo) throws MissingIdentifierException {
String pkn = null;
pkn = determinePrimaryKey(catalog, schema, tableName, dmd);
if (pkn == null) {
pkn = findUniqueIndex(catalog, schema, tableName, dmd);
}
if (pkn == null) throw new MissingIdentifierException(tableName);
setAsIdentifier(cInfo, pkn);
return;
 
}
 
private String findUniqueIndex(String catalog, String schema, String tableName, DatabaseMetaData dmd) {
Map<String, String> indexes = new HashMap<String, String>();
Set<String> rejectedIndexes = new HashSet<String>();
readUniqueIndexes(catalog, schema, tableName, dmd, indexes, rejectedIndexes);
for (String candidate : indexes.keySet()) {
if (!rejectedIndexes.contains(candidate)) return indexes.get(candidate);
}
return null;
}
 
private void readUniqueIndexes(String catalog, String schema, String tableName, DatabaseMetaData dmd, Map<String, String> indexes, Set<String> rejectedIndexes) {
ResultSet rs = null;
try {
rs = dmd.getIndexInfo(catalog, schema, tableName, true, false);
while (rs.next()) {
String colName = rs.getString("COLUMN_NAME");
String indexName = rs.getString("INDEX_NAME");
if (indexName == null) {
indexName = colName;
}
if (indexes.get(indexName) != null) {
rejectedIndexes.add(indexName);
} else {
indexes.put(indexName, colName);
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
rs.close();
} catch (SQLException e) {
//do nothing
}
}
}
 
private String determinePrimaryKey(String catalog, String schema, String tableName, DatabaseMetaData dmd) {
String pkn = null;
ResultSet rs = null;
try {
rs = dmd.getPrimaryKeys(catalog, schema, tableName);
if (!rs.next()) return null;
pkn = rs.getString("COLUMN_NAME");
//check whether the primary key is non-composite
if (rs.next()) return null;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
rs.close();
} catch (SQLException e) {
//do nothing
}
}
return pkn;
}
 
private void readColums(String catalog, String schema, String tableName, DatabaseMetaData dmd, ClassInfo cInfo) throws TableNotFoundException {
ResultSet rs = null;
boolean empty = true;
try {
rs = dmd.getColumns(catalog, schema, tableName, null);
while (rs.next()) {
empty = false;
String colName = rs.getString("COLUMN_NAME");
String dbType = rs.getString("TYPE_NAME");
int javaType = rs.getInt("DATA_TYPE");
addAttribute(cInfo, colName, dbType, javaType);
}
} catch (SQLException ex) {
throw new RuntimeException(ex);
} finally {
try {
rs.close();
} catch (SQLException e) {
// do nothing
}
}
if (empty) {
throw new TableNotFoundException(tableName);
}
}
 
private void setAsIdentifier(ClassInfo cInfo, String pkn) {
for (AttributeInfo ai : cInfo.getAttributes()) {
if (ai.getColumnName().equals(pkn)) {
ai.setIdentifier(true);
break;
}
}
}
 
private void addAttribute(ClassInfo cInfo, String colName, String dbType, int javaType) {
String hibernateType = null;
try {
hibernateType = typeMapper.getHibernateType(dbType, javaType);
AttributeInfo ai = new AttributeInfo();
ai.setColumnName(colName);
ai.setFieldName(naming.createPropertyName(colName));
ai.setHibernateType(hibernateType);
ai.setCtClass(typeMapper.getCtClass(dbType, javaType));
cInfo.addAttribute(ai);
} catch (TypeNotFoundException e) {
LOGGER.warn("No property generated for attribute " + colName + ": " + e.getMessage());
}
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/ClassInfo.java
New file
0,0 → 1,125
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import java.util.ArrayList;
import java.util.List;
 
public class ClassInfo {
 
private final String className;
 
private final String tableName;
 
private final List<AttributeInfo> attributes = new ArrayList<AttributeInfo>();
 
public ClassInfo(String tableName, String className) {
this.className = className;
this.tableName = tableName;
}
 
public AttributeInfo getIdAttribute() throws MissingIdentifierException {
for (AttributeInfo ai : getAttributes()) {
if (ai.isIdentifier()) {
return ai;
}
}
throw new MissingIdentifierException();
}
 
public AttributeInfo getGeomAttribute() throws GeometryNotFoundException {
for (AttributeInfo ai : getAttributes()) {
if (ai.isGeometry()) {
return ai;
}
}
throw new GeometryNotFoundException();
}
 
public List<AttributeInfo> getAttributes() {
return attributes;
}
 
public String getClassName() {
return className;
}
 
public String getTableName() {
return tableName;
}
 
public void addAttribute(AttributeInfo ai) {
this.attributes.add(ai);
}
 
public void removeAttribute(AttributeInfo ai) {
this.attributes.remove(ai);
}
 
public void clearAttributes() {
this.attributes.clear();
}
 
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result
+ ((attributes == null) ? 0 : attributes.hashCode());
result = PRIME * result
+ ((className == null) ? 0 : className.hashCode());
result = PRIME * result
+ ((tableName == null) ? 0 : tableName.hashCode());
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final ClassInfo other = (ClassInfo) obj;
if (attributes == null) {
if (other.attributes != null)
return false;
} else if (!attributes.equals(other.attributes))
return false;
if (className == null) {
if (other.className != null)
return false;
} else if (!className.equals(other.className))
return false;
if (tableName == null) {
if (other.tableName != null)
return false;
} else if (!tableName.equals(other.tableName))
return false;
return true;
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/TableNotFoundException.java
New file
0,0 → 1,58
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* This Exception is thrown when the POJO Utility cannot locate a primary key.
*
* @author Karel Maesen, Geovise BVBA
*
*/
public class TableNotFoundException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static final String basemsg = "Table not found";
 
public TableNotFoundException() {
super(basemsg);
}
 
public TableNotFoundException(String msg) {
super(basemsg + ": " + msg);
}
 
public TableNotFoundException(Throwable cause) {
super(cause);
}
 
public TableNotFoundException(String msg, Throwable cause) {
super(basemsg + ": " + msg, cause);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/MappingsGenerator.java
New file
0,0 → 1,107
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
 
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
 
/**
* This class creates a Hibernate mapping file for a list of tables.
*
* @author Karel Maesen, Geovise BVBA (http://www.geovise.com/)
*/
public class MappingsGenerator {
 
private Document mappingDoc;
 
private String packageName;
 
public MappingsGenerator(String packageName) {
this.packageName = packageName;
}
 
public void write(Writer writer) throws IOException {
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(writer, format);
xmlWriter.write(this.mappingDoc);
xmlWriter.close();
}
 
public Document getMappingsDoc() {
return this.mappingDoc;
}
 
public void load(Collection<ClassInfo> mappedClasses, String schema)
throws MissingIdentifierException {
 
this.mappingDoc = DocumentHelper.createDocument();
this.mappingDoc.addDocType("hibernate-mapping",
"-//Hibernate/Hibernate Mapping DTD 3.0//EN",
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd");
Element root = this.mappingDoc.addElement("hibernate-mapping");
root.addAttribute("package", this.packageName);
if (schema != null){
root.addAttribute("schema", schema);
}
for (ClassInfo classInfo: mappedClasses) {
addTableElement(root, classInfo);
}
}
 
private void addTableElement(Element root, ClassInfo classInfo)
throws MissingIdentifierException {
Element tableEl = root.addElement("class");
tableEl.addAttribute("name", classInfo.getClassName());
tableEl.addAttribute("table", classInfo.getTableName());
AttributeInfo idAttr = classInfo.getIdAttribute();
addColElement(tableEl, idAttr);
for (AttributeInfo ai : classInfo.getAttributes()) {
if (!ai.isIdentifier()) {
addColElement(tableEl, ai);
}
}
 
}
 
private void addColElement(Element tableEl, AttributeInfo ai) {
Element colEl = null;
if (ai.isIdentifier()) {
colEl = tableEl.addElement("id");
} else {
colEl = tableEl.addElement("property");
}
colEl.addAttribute("name", ai.getFieldName());
colEl.addAttribute("column", ai.getColumnName());
colEl.addAttribute("type", ai.getHibernateType());
return;
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/SimpleNamingStrategy.java
New file
0,0 → 1,93
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* This is the default implementation for a <code>NamingStrategy</code>.
*
* @author Karel Maesen, Geovise BVBA (http://www.geovise.com/)
*/
public class SimpleNamingStrategy implements NamingStrategy {
 
public String createClassName(String base) {
String cleaned = toJavaName(base);
cleaned = cleaned.toLowerCase();
return capitalize(cleaned);
}
 
public String createGetterName(String fieldName) {
return "get" + capitalize(fieldName);
}
 
public String createPropertyName(String base) {
String cleaned = toJavaName(base);
cleaned = cleaned.toLowerCase();
return cleaned;
}
 
public String createSetterName(String fieldName) {
return "set" + capitalize(fieldName);
 
}
 
/**
*
* Turns the name into a valid, simplified Java Identifier.
*
* @param name
* @return
*/
private String toJavaName(String name) {
StringBuilder stb = new StringBuilder();
char[] namechars = name.toCharArray();
if (!Character.isJavaIdentifierStart(namechars[0])) {
stb.append("__");
} else {
stb.append(namechars[0]);
}
for (int i = 1; i < namechars.length; i++) {
if (!Character.isJavaIdentifierPart(namechars[i])) {
stb.append("__");
} else {
stb.append(namechars[i]);
}
}
 
return stb.toString();
}
 
private String capitalize(String s) {
char[] ca = s.toCharArray();
ca[0] = Character.toUpperCase(ca[0]);
return new String(ca);
}
 
@SuppressWarnings("unused")
private String uncapitalize(final String s) {
final char[] ca = s.toCharArray();
ca[0] = Character.toLowerCase(ca[0]);
return new String(ca);
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/TypeMapper.java
New file
0,0 → 1,185
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import org.hibernatespatial.GeometryUserType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
 
/**
* The <code>TypeMapper</code> maps a pair consisting of java.sql.Type, and a
* database type name to a CtClass (a representation of a java type used by the
* javassist class building tools) and to a Hibernate type (used when creating a
* mapping file).
*
* @author Karel Maesen, Geovise BVBA (http://www.geovise.com/)
*/
public class TypeMapper {
 
protected final static Logger logger = LoggerFactory.getLogger(TypeMapper.class);
 
private final static String GEOMETRY_USER_TYPE = GeometryUserType.class
.getCanonicalName();
 
private List<TMEntry> entries = new ArrayList<TMEntry>();
 
private String dbGeomType = "";
 
private CtClass ctGeom;
 
// TODO -- create entires for all constants defined in java.sql.Types
public TypeMapper(String dbGeomType) {
 
// first set the type to use for the geometry
this.dbGeomType = dbGeomType;
 
ClassPool pool = ClassPool.getDefault();
// ensure that we can load the JTS classes.
pool.insertClassPath(new ClassClassPath(this.getClass()));
 
CtClass ctString;
CtClass ctDate;
CtClass ctInteger;
CtClass ctBoolean;
CtClass ctFloat;
CtClass ctDouble;
CtClass ctLong;
CtClass ctShort;
CtClass ctBigDecimal;
CtClass ctByte;
CtClass ctBinary;
try {
ctString = pool.get("java.lang.String");
ctDate = pool.get("java.util.Date");
ctGeom = pool.get("com.vividsolutions.jts.geom.Geometry");
ctInteger = pool.get("java.lang.Integer");
ctBoolean = pool.get("java.lang.Boolean");
ctDouble = pool.get("java.lang.Double");
ctLong = pool.get("java.lang.Long");
ctShort = pool.get("java.lang.Short");
ctFloat = pool.get("java.lang.Float");
ctBigDecimal = pool.get("java.math.BigDecimal");
ctByte = pool.get("java.lang.Byte");
ctBinary = pool.get("byte[]");
} catch (NotFoundException e) {
throw new RuntimeException(e);
}
 
 
entries.add(new TMEntry(Types.BIGINT, "integer", ctInteger));
entries.add(new TMEntry(Types.SMALLINT, "short", ctShort));
entries.add(new TMEntry(Types.TINYINT, "byte", ctByte));
entries.add(new TMEntry(Types.BOOLEAN, "boolean", ctBoolean));
entries.add(new TMEntry(Types.BIT, "boolean", ctBoolean));
entries.add(new TMEntry(Types.CHAR, "string", ctString));
entries.add(new TMEntry(Types.DATE, "date", ctDate));
entries.add(new TMEntry(Types.TIMESTAMP, "timestamp", ctDate));
entries.add(new TMEntry(Types.TIME, "time", ctDate));
entries.add(new TMEntry(Types.DECIMAL, "big_decimal", ctBigDecimal));
entries.add(new TMEntry(Types.DOUBLE, "double", ctDouble));
entries.add(new TMEntry(Types.NUMERIC, "big_decimal", ctBigDecimal));
entries.add(new TMEntry(Types.FLOAT, "float", ctFloat));
entries.add(new TMEntry(Types.INTEGER, "integer", ctInteger));
entries.add(new TMEntry(Types.BIGINT, "long", ctLong));
entries.add(new TMEntry(Types.VARCHAR, "string", ctString));
entries.add(new TMEntry(Types.BINARY, "binary", ctBinary));
entries.add(new TMEntry(Types.CLOB, "text", ctString));
}
 
public CtClass getCtClass(String dbType, int sqlType) {
if (dbType.equalsIgnoreCase(this.dbGeomType)) {
return this.ctGeom;
}
for (TMEntry entry : entries) {
if (entry.javaType == sqlType) {
return entry.ctClass;
}
}
return null;
}
 
public String getHibernateType(String dbType, int sqlType) throws TypeNotFoundException {
if (dbType.equalsIgnoreCase(this.dbGeomType)) {
return GEOMETRY_USER_TYPE;
}
for (TMEntry entry : entries) {
if (entry.javaType == sqlType) {
return entry.hibernateTypeName;
}
}
throw new TypeNotFoundException(dbType);
 
}
 
public int[] getMappedSQLTypes() {
int l = this.entries.size();
int[] types = new int[l];
for (int i = 0; i < this.entries.size(); i++) {
types[i] = this.entries.get(i).javaType;
}
return types;
}
 
public void addTypeMapping(int sqlType, String hibernateType,
CtClass ctClass) {
this.entries.add(new TMEntry(sqlType, hibernateType, ctClass));
}
 
public void removeTypeMapping(int sqlType) {
TMEntry tm = null;
for (TMEntry t : this.entries) {
if (t.javaType == sqlType) {
tm = t;
break;
}
}
if (tm != null) {
this.entries.remove(tm);
}
}
 
private static class TMEntry {
protected int javaType = 0;
 
protected String hibernateTypeName = "";
 
protected CtClass ctClass;
 
protected TMEntry(int jt, String ht, CtClass jc) {
this.javaType = jt;
this.hibernateTypeName = ht;
this.ctClass = jc;
}
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/GeometryNotFoundException.java
New file
0,0 → 1,59
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* This Exception is thrown when the POJO Utility cannot locate a
* Geometry-valued attribute.
*
* @author Karel Maesen, Geovise BVBA
*
*/
public class GeometryNotFoundException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static final String basemsg = "No Geometry found.";
 
public GeometryNotFoundException() {
super(basemsg);
}
 
public GeometryNotFoundException(String msg) {
super(basemsg + ":" + msg);
}
 
public GeometryNotFoundException(Throwable cause) {
super(cause);
}
 
public GeometryNotFoundException(String msg, Throwable cause) {
super(basemsg + ":" + msg, cause);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/FeatureClassGenerator.java
New file
0,0 → 1,65
package org.hibernatespatial.pojo;
 
import java.security.ProtectionDomain;
 
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
 
public class FeatureClassGenerator {
 
private final String packageName;
private final NamingStrategy naming;
private final static ClassPool pool = ClassPool.getDefault();
 
public FeatureClassGenerator(String packageName, NamingStrategy naming) {
this.packageName = packageName;
this.naming = naming;
}
 
public Class<?> generate(ClassInfo classInfo) {
 
try {
String classname = packageName + "." + classInfo.getClassName();
CtClass pojo = pool.makeClass(classname);
for (AttributeInfo ai : classInfo.getAttributes()) {
CtField field = createField(ai, pojo);
CtMethod getter = createGetterMethod(field);
CtMethod setter = createSetterMethod(field);
pojo.addField(field);
pojo.addMethod(getter);
pojo.addMethod(setter);
}
ProtectionDomain pd = pojo.getClass().getProtectionDomain();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> clazz = pojo.toClass(cl, pd);
pojo.detach();
return clazz;
} catch (CannotCompileException e){
e.printStackTrace(); //TODO -- provide proper logging
throw new RuntimeException("Problem generating class for table " + classInfo.getTableName(), e);
}
}
 
private CtMethod createGetterMethod(CtField field) throws CannotCompileException {
String fn = field.getName();
return CtNewMethod.getter(this.naming.createGetterName(fn), field);
}
 
private CtMethod createSetterMethod(CtField field)
throws CannotCompileException {
String fn = field.getName();
return CtNewMethod.setter(naming.createSetterName(fn), field);
}
 
private CtField createField(AttributeInfo ai, CtClass declaring)
throws CannotCompileException {
CtField f = new CtField(ai.getCtClass(), ai.getFieldName(), declaring);
return f;
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/MissingIdentifierException.java
New file
0,0 → 1,58
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* This Exception is thrown when the POJO Utility cannot locate a primary key.
*
* @author Karel Maesen, Geovise BVBA
*
*/
public class MissingIdentifierException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static final String basemsg = "No suitable identifier found in table";
 
public MissingIdentifierException() {
super(basemsg);
}
 
public MissingIdentifierException(String msg) {
super(basemsg + ":" + msg);
}
 
public MissingIdentifierException(Throwable cause) {
super(cause);
}
 
public MissingIdentifierException(String msg, Throwable cause) {
super(basemsg + ":" + msg, cause);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/NamingStrategy.java
New file
0,0 → 1,70
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* A <code>NamingStrategy</code> determines how to derive suitable class and
* member names corresponding to database tables and columns.
*
* @author Karel Maesen, Geovise BVBA (http://www.geovise.com/)
*/
public interface NamingStrategy {
 
/**
* Create a valid name for a member variable based on the specified input
* name.
*
* @param base
* the input name.
* @return a valid java identifier for a member variable.
*/
public String createPropertyName(String base);
 
/**
* Create a valid name for a setter for the property
*
* @param propertyName
* @return valid java identifier for a property setter
*/
public String createSetterName(String propertyName);
 
/**
* Create a valid name for a getter for the property
*
* @param propertyName
* @return valid java identifier for a property getter
*/
public String createGetterName(String propertyName);
 
/**
* Create a valid name for a Java class based on the specified input name.
*
* @param base
* the input name.
* @return a valid java identifier for a class.
*/
public String createClassName(String base);
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/AutoMapper.java
New file
0,0 → 1,280
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import org.dom4j.Document;
import org.hibernatespatial.HBSpatialExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.*;
 
/**
* @author Karel Maesen, Geovise BVBA
*/
public class AutoMapper {
 
protected final static Logger logger = LoggerFactory.getLogger(AutoMapper.class);
 
protected final static String PACKAGE_NAME = "org.hibernatespatial.features.generated";
 
private static Map<TableName, Class<?>> tableClassMap = new HashMap<TableName, Class<?>>();
 
private static Map<TableName, ClassInfo> tableClassInfoMap = new HashMap<TableName, ClassInfo>();
 
private static NamingStrategy naming = new SimpleNamingStrategy();
 
/**
* Returns the Hibernate mapping document for the specified tables
* <p/>
* <p>To create the mapping, a <code>Connection</code> object must be
* provided to provide access to the specified tables.
* This connection will not be closed on return.</p>
*
* @param conn JDBC <code>Connection</code> used during mapping
* @param catalog database catalog
* @param schema database schema
* @param tableNames list of table names
* @return the XML mapping document that maps the tables specified by the catalog, schema and tablenames arguments.
* @throws SQLException
*/
public static synchronized Document map(Connection conn, String catalog, String schema, Collection<String> tableNames) throws SQLException {
TypeMapper typeMapper = new TypeMapper(HBSpatialExtension.getDefaultSpatialDialect().getDbGeometryTypeName());
DatabaseMetaData dmd = conn.getMetaData();
FeatureMapper fMapper = new FeatureMapper(naming, typeMapper);
FeatureClassGenerator fGenerator = new FeatureClassGenerator(PACKAGE_NAME, naming);
 
for (String tableName : tableNames) {
TableName table = new TableName(catalog, schema, tableName);
if (tableClassInfoMap.get(table) != null) {
logger.info("Class info for table " + tableName + " in catalog/schema " + catalog + "/" + schema + " has already been mapped.");
continue;
}
logger.info("Generating class info for table " + tableName + " in catalog/schema " + catalog + "/" + schema);
ClassInfo cInfo;
try {
cInfo = fMapper.createClassInfo(catalog, schema, tableName, dmd);
logger.info("Generating class " + cInfo.getClassName() + " for table " + tableName);
Class<?> clazz = fGenerator.generate(cInfo);
tableClassMap.put(table, clazz);
tableClassInfoMap.put(table, cInfo);
 
} catch (TableNotFoundException e) {
logger.warn(e.getMessage());
} catch (MissingIdentifierException e) {
logger.warn(e.getMessage());
}
}
logger.info("Generating Hibernate Mapping file");
MappingsGenerator mappingGenerator = new MappingsGenerator(PACKAGE_NAME);
try {
mappingGenerator.load(tableClassInfoMap.values(), schema);
} catch (MissingIdentifierException e) {
throw new RuntimeException(e);
}
return mappingGenerator.getMappingsDoc();
}
 
/**
* Returns the <code>Class</code> object to which the specified table is mapped
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @return class to which the table specified by the arguments is mapped
*/
public static Class<?> getClass(String catalog, String schema, String tableName) {
TableName tbn = new TableName(catalog, schema, tableName);
return tableClassMap.get(tbn);
}
 
/**
* Returns the tables mapped by this automapper.
*
* @return a List of mapped tables. Each table is represented by a String array with the first
* component the catalog, the second the schema, and the third the table name.
*/
public static List<String[]> getMappedTables() {
List<String[]> list = new ArrayList<String[]>();
for (TableName tbn : tableClassMap.keySet()) {
String[] sa = new String[3];
sa[0] = tbn.catalog;
sa[1] = tbn.schema;
sa[2] = tbn.tableName;
list.add(sa);
}
return list;
}
 
/**
* Returns the attribute names of the class to with the specified table is mapped
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @return list of attribute (field) names of the class that corresponds with the table identified by the arguments
*/
public static List<String> getAttributes(String catalog, String schema, String tableName) {
List<AttributeInfo> attributes = getAttributeInfos(catalog, schema, tableName);
List<String> result = new ArrayList<String>();
for (AttributeInfo attributeInfo : attributes) {
result.add(attributeInfo.getFieldName());
}
return result;
}
 
private static List<AttributeInfo> getAttributeInfos(String catalog, String schema, String tableName) {
TableName tbn = new TableName(catalog, schema, tableName);
ClassInfo cInfo = tableClassInfoMap.get(tbn);
if (cInfo == null) return new ArrayList<AttributeInfo>();
return cInfo.getAttributes();
}
 
/**
* Returns the Identifier attribute
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @return the attribute name which functions as a unique identifier for the objects corresponding
* to rows in the specified table
* @throws MissingIdentifierException when no Identifier property is available
*/
public static String getIdAttribute(String catalog, String schema, String tableName) throws MissingIdentifierException {
TableName tbn = new TableName(catalog, schema, tableName);
ClassInfo cInfo = tableClassInfoMap.get(tbn);
return cInfo.getIdAttribute().getFieldName();
}
 
/**
* Returns the (default) <code>Geometry</code>-valued attribute
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @return the name of the <code>Geometry</code>-valued attribute
* @throws GeometryNotFoundException when no <code>Geometry</code>-valued property is available
*/
public static String getGeometryAttribute(String catalog, String schema, String tableName) throws GeometryNotFoundException {
TableName tbn = new TableName(catalog, schema, tableName);
ClassInfo cInfo = tableClassInfoMap.get(tbn);
return cInfo.getGeomAttribute().getFieldName();
}
 
/**
* Returns the name of the setter-method for the attribute
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @param attribute name of the attribute of the class to which this class is mapped
* @return the name of the setter-method of the attribute specified by the arguments
*/
public static String getAttributeSetterName(String catalog, String schema, String tableName, String attribute) {
getAttributeInfo(catalog, schema, tableName, attribute);
return naming.createSetterName(attribute);
}
 
/**
* Returns the name of the getter-method for the attribute
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @param attribute name of the attribute of the class to which this class is mapped
* @return the name of the getter-method of the attribute specified by the arguments
* */
public static String getAttributeGetterName(String catalog, String schema, String tableName, String attribute) {
getAttributeInfo(catalog, schema, tableName, attribute);
return naming.createGetterName(attribute);
}
 
private static AttributeInfo getAttributeInfo(String catalog, String schema, String tableName, String attribute) {
if (attribute == null) throw new IllegalArgumentException("Null attribute received.");
for (AttributeInfo candidate : getAttributeInfos(catalog, schema, tableName)) {
if (candidate.getFieldName().equals(attribute)) {
return candidate;
}
}
throw new IllegalArgumentException(String.format("%s is not an attribute of the class to which table %s is mapped.", attribute, tableName));
}
 
private static class TableName {
String catalog;
String schema;
String tableName;
 
private TableName(String catalog, String schema, String tableName) {
this.catalog = catalog;
this.schema = schema;
this.tableName = tableName;
}
 
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((catalog == null) ? 0 : catalog.hashCode());
result = prime * result
+ ((schema == null) ? 0 : schema.hashCode());
result = prime * result
+ ((tableName == null) ? 0 : tableName.hashCode());
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof TableName))
return false;
TableName other = (TableName) obj;
if (catalog == null) {
if (other.catalog != null)
return false;
} else if (!catalog.equals(other.catalog))
return false;
if (schema == null) {
if (other.schema != null)
return false;
} else if (!schema.equals(other.schema))
return false;
if (tableName == null) {
if (other.tableName != null)
return false;
} else if (!tableName.equals(other.tableName))
return false;
return true;
}
 
 
}
}
Property changes:
Added: svn:keywords
+ Id
Added: svn:mergeinfo
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/TypeNotFoundException.java
New file
0,0 → 1,60
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.pojo;
 
/**
* This Exception is thrown when the POJO Utility cannot locate a primary key.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: Jun 24, 2010
*/
public class TypeNotFoundException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static final String basemsg = "Type not found";
 
public TypeNotFoundException() {
super(basemsg);
}
 
public TypeNotFoundException(String msg) {
super(basemsg + ":" + msg);
}
 
public TypeNotFoundException(Throwable cause) {
super(cause);
}
 
public TypeNotFoundException(String msg, Throwable cause) {
super(basemsg + ":" + msg, cause);
}
 
}
 
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialRelation.java
New file
0,0 → 1,58
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
/**
* These spatial relations are all defined in "OpenGIS Simple Feature
* Specification for SQL, Rev. 1.1" of the Open Geospatial Consortium (OGC).
*
* @author Karel Maesen
*/
public interface SpatialRelation {
 
public static int EQUALS = 0;
 
public static int DISJOINT = 1;
 
public static int TOUCHES = 2;
 
public static int CROSSES = 3;
 
public static int WITHIN = 4;
 
public static int OVERLAPS = 5;
 
public static int CONTAINS = 6;
 
public static int INTERSECTS = 7;
 
@Deprecated
public static int FILTER = 8;
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/GeometryUserType.java
New file
0,0 → 1,247
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
import org.hibernate.HibernateException;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
 
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
 
/**
* This class ensures that Hibernate can work with
* the JTS <code>Geometry</code> type.
* <p/>
* To properly convert <code>Geometry</code> objects to database specific
* wrapper objects, acces is needed to a spatially enabled database dialect.
* This dialect can be specified as a parameter to the type. If no parameter is
* supplied, the default Dialect will be used (set in HBSpatialExtension).
*
* @author Karel Maesen
*/
public class GeometryUserType implements UserType, ParameterizedType, Serializable {
 
private SpatialDialect spatialDialect = null;
 
private UserType delegate = null;
 
public static String DIALECT_PARAM_NAME = "dialect";
 
private void configure(Properties properties) {
if (properties == null || properties.getProperty(DIALECT_PARAM_NAME) == null) {
spatialDialect = HBSpatialExtension.getDefaultSpatialDialect();
} else {
spatialDialect = HBSpatialExtension.createSpatialDialect(properties
.getProperty(DIALECT_PARAM_NAME));
}
if (spatialDialect == null) {
throw new HibernateSpatialException(
"No spatial Dialect could be created");
}
delegate = spatialDialect.getGeometryUserType();
if (delegate instanceof ParameterizedType && properties != null) {
((ParameterizedType) delegate).setParameterValues(properties);
}
}
 
private void initialize() {
if (delegate == null) {
configure(null);
}
}
 
/**
* @param arg0
* @param arg1
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#assemble(java.io.Serializable,
* java.lang.Object)
*/
public Object assemble(Serializable arg0, Object arg1)
throws HibernateException {
initialize();
return delegate.assemble(arg0, arg1);
}
 
/**
* @param arg0
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object arg0) throws HibernateException {
return delegate.deepCopy(arg0);
}
 
/**
* @param arg0
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
*/
public Serializable disassemble(Object arg0) throws HibernateException {
initialize();
return delegate.disassemble(arg0);
}
 
/**
* @param arg0
* @param arg1
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#equals(java.lang.Object,
* java.lang.Object)
*/
public boolean equals(Object arg0, Object arg1) throws HibernateException {
initialize();
return delegate.equals(arg0, arg1);
}
 
/**
* @param obj
* @return
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
initialize();
return delegate.equals(obj);
}
 
/**
* @return
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
initialize();
return delegate.hashCode();
}
 
/**
* @param arg0
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
*/
public int hashCode(Object arg0) throws HibernateException {
initialize();
return delegate.hashCode(arg0);
}
 
/**
* @return
* @see org.hibernate.usertype.UserType#isMutable()
*/
public boolean isMutable() {
initialize();
return delegate.isMutable();
}
 
/**
* @param arg0
* @param arg1
* @param arg2
* @return
* @throws HibernateException
* @throws SQLException
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,
* java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet arg0, String[] arg1, Object arg2)
throws HibernateException, SQLException {
initialize();
return delegate.nullSafeGet(arg0, arg1, arg2);
}
 
/**
* @param arg0
* @param arg1
* @param arg2
* @throws HibernateException
* @throws SQLException
* @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
* java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement arg0, Object arg1, int arg2)
throws HibernateException, SQLException {
initialize();
delegate.nullSafeSet(arg0, arg1, arg2);
}
 
/**
* @param arg0
* @param arg1
* @param arg2
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#replace(java.lang.Object,
* java.lang.Object, java.lang.Object)
*/
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
initialize();
return delegate.replace(arg0, arg1, arg2);
}
 
/**
* @return
* @see org.hibernate.usertype.UserType#returnedClass()
*/
public Class returnedClass() {
initialize();
return delegate.returnedClass();
}
 
/**
* @return
* @see org.hibernate.usertype.UserType#sqlTypes()
*/
public int[] sqlTypes() {
initialize();
return delegate.sqlTypes();
}
 
/**
* @return
* @see java.lang.Object#toString()
*/
public String toString() {
initialize();
return delegate.toString();
}
 
public void setParameterValues(Properties properties) {
configure(properties);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/util/MetadataInspector.java
New file
0,0 → 1,119
package org.hibernatespatial.util;
 
import java.sql.*;
 
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Oct 28, 2010
*/
public class MetadataInspector {
 
 
static String driver;
static String dbURI;
static String userName;
static String passWord;
static String table;
 
public static void main(String[] args) throws Exception {
 
 
readArgs(args);
 
// Connection reference
Connection conn = null;
try {
 
// Load database driver
try {
Class.forName(driver);
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
 
// Make connection
conn = DriverManager.getConnection(dbURI, userName, passWord);
 
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * from " + table);
 
// Get the ResultSet meta data
ResultSetMetaData rmd = rs.getMetaData();
rs.next();
if (rmd == null) {
 
System.out.println("ResultSet meta data not available");
 
} else {
 
int columnCount = rmd.getColumnCount();
 
// Display number of Columns in the ResultSet
System.out.println("Number of Columns in the table : " + columnCount);
 
 
for (int i = 1; i <= columnCount; i++) {
 
// Display number of Column name
System.out.println("Column Name : " + rmd.getColumnName(i));
 
// Display number of Column Type
System.out.println("Column TypeName : " + rmd.getColumnTypeName(i));
 
 
System.out.println("Column type : " + rmd.getColumnType(i));
 
Object o = rs.getObject(i);
System.out.println("Column object class: " + o.getClass().getName());
 
 
// Display if Column can be NOT NULL
switch (rmd.isNullable(i)) {
 
case ResultSetMetaData.columnNoNulls:
System.out.println(" NOT NULL");
break;
case ResultSetMetaData.columnNullable:
System.out.println(" NULLABLE");
break;
case ResultSetMetaData.columnNullableUnknown:
System.out.println(" NULLABLE Unkown");
}
System.out.println();
}
}
} finally {
 
// Close connection
if (conn != null) {
try {
conn.close();
} catch (SQLException ex) {
System.out.println("Error in closing Conection");
}
}
}
}
 
// private static String getJavaJDBCTypeName(int type){
//
// }
 
 
private static void readArgs(String[] args) {
try {
driver = args[0];
dbURI = args[1];
userName = args[2];
passWord = args[3];
table = args[4];
 
} catch (Exception e) {
System.out.printf("Usage: metadataInspector <driver> <dbUri> <userName> <passWord> <table>");
System.exit(1);
}
 
}
 
}
/branches/Jts_mgeom_wkb/hibernate-spatial/src/main/java/org/hibernatespatial/HibernateSpatialException.java
New file
0,0 → 1,55
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
/**
* Exception for Hibernate Spatial
*
* @author Karel Maesen
*/
public class HibernateSpatialException extends RuntimeException {
 
/**
* generated serialVersionUID
*/
private static final long serialVersionUID = -2153256823661407568L;
 
public HibernateSpatialException(String msg) {
super(msg);
}
 
public HibernateSpatialException(Throwable cause) {
super(cause);
}
 
public HibernateSpatialException(String msg, Throwable cause) {
super(msg, cause);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/Jts_mgeom_wkb/hibernate-spatial/src/site/site.xml
New file
0,0 → 1,73
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ $Id:$
~
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for geographic data.
~
~ Copyright © 2007-2010 Geovise BVBA
~
~ This library is free software; you can redistribute it and/or
~ modify it under the terms of the GNU Lesser General Public
~ License as published by the Free Software Foundation; either
~ version 2.1 of the License, or (at your option) any later version.
~
~ This library is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this library; if not, write to the Free Software
~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
~
~ For more information, visit: http://www.hibernatespatial.org/
-->
 
<project name="Hibernate Spatial">
 
<bannerLeft>
<name>Hibernate Spatial</name>
<href>http://www.hibernatespatial.org/</href>
</bannerLeft>
 
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-default-skin</artifactId>
</skin>
 
<publishDate format="yyyy MMM dd"/>
 
<body>
 
<menu name="Overview" inherit="top">
<item name="Introduction" href="index.html"/>
<item name="Usage" href="usage.html"/>
<item name="Road Map" href="roadmap.html"/>
</menu>
<menu name="Getting Hibernate Spatial" inherit="top">
<item name="Releases" href="download.html"/>
<item name="Sources" href="source-repository.html"/>
<item name="License" href="license.html"/>
<item name="Source code insight"
href="insight.html"/>
</menu>
<menu name="Documentation" inherit="top">
<item name="Tutorial" href="tutorial.html"/>
<item name="Maven Quick Start" href="mavenquick.html"/>
<item name="Configuring providers" href="providers.html"/>
<item name="Getting Help" href="gettinghelp.html"/>
<item name="JavaDocs" href="apidocs/index.html"/>
</menu>
 
 
<menu name="Providers" inherit="top">
<item name="Oracle10g" href="hibernate-spatial-oracle"/>
<item name="Postgresql" href="hibernate-spatial-postgis"/>
<item name="Microsft SQL Server" href="hibernate-spatial-sqlserver"/>
<item name="MySQL" href="hibernate-spatial-mysql"/>
<item name="GeoDB (H2)" href="hibernate-spatial-h2-geodb" />
</menu>
 
</body>
</project>
/branches/Jts_mgeom_wkb/hibernate-spatial/src/site/resources/css/site.css
New file
0,0 → 1,4
.source {
overflow: auto;
}
 
/branches/Jts_mgeom_wkb/hibernate-spatial/src/site/xdoc/mavenquick.xml
New file
0,0 → 1,82
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ $Id:$
~
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for geographic data.
~
~ Copyright © 2007-2010 Geovise BVBA
~
~ This library is free software; you can redistribute it and/or
~ modify it under the terms of the GNU Lesser General Public
~ License as published by the Free Software Foundation; either
~ version 2.1 of the License, or (at your option) any later version.
~
~ This library is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this library; if not, write to the Free Software
~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
~
~ For more information, visit: http://www.hibernatespatial.org/
-->
 
<document>
<properties>
<author>Karel Maesen</author>
<title>Maven Quick Start</title>
</properties>
 
<body>
<section name="Maven Quick Start">
<p>If you use maven for your project, it's very easy to start using Hibernate Spatial.</p>
<p>First, add the Hibernate Spatial and GeoTools repositories to you pom.xml
</p>
<source>
<![CDATA[
...
<repositories>
<repository>
<id>OSGEO GeoTools repo</id>
<url>http://download.osgeo.org/webdav/geotools</url>
</repository>
<repository>
<id>Hibernate Spatial repo</id>
<url>http://www.hibernatespatial.org/repository</url>
</repository>
</repositories>
...
]]>
</source>
<p>Secondly, add the Hibernate Spatial Provider as a dependency. E.g., when using Postgis/Postgresql, add
the
hibernate-spatial-postgis artifact. Other possibilities are: hibernate-spatial-oracle, or
hibernate-spatial-mysql
</p>
 
<source>
<![CDATA[
...
<dependencies>
...
<dependency>
<groupId>org.hibernatespatial</groupId>
<artifactId>hibernate-spatial-postgis</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
...
]]>
</source>
 
<p>Maven will now transitively resolve the dependencies to JTS, Hibernate and Hibernate Spatial (core
module). Now you're good to go.
</p>
</section>
</body>
</document>
/branches/Jts_mgeom_wkb/hibernate-spatial/src/site/xdoc/roadmap.xml
New file
0,0 → 1,14
<?xml version="1.0" encoding="UTF-8"?>
<document>
<properties>
<author>Karel Maesen</author>
<title>Road Map</title>
</properties>
 
<body>
<iframe
style="width: 100%; height: 800px"
src="http://www.hibernatespatial.org/jira/browse/HIBSPA?report=com.atlassian.jira.plugin.system.project:roadmap-panel">
</iframe>
</body>
</document>
/branches/Jts_mgeom_wkb/hibernate-spatial/src/site/xdoc/tutorial.xml
New file
0,0 → 1,1037
<?xml version="1.0" encoding="UTF-8"?>
 
<document>
<properties>
<author>Karel Maesen</author>
<title>Tutorial</title>
</properties>
 
<body>
 
<section name="Introduction">
<p>
This tutorial gives a quick overview of how to get
Hibernate Spatial working. We will develop a simple
application that stores, and retrieves some
simple data objects. The data objects are "special" in
that they have a property of type Geometry.
</p>
<p>
This tutorial assumes
that you are familiar with Hibernate, and the basic
concepts of working with geographic data. It is also based on the
<a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html">
Hibernate Tutorial</a>and uses the same example. If you
haven't read the Hibernate Tutorial, and are new to Hibernate, then
<strong>please read it before proceeding here</strong>.
</p>
<p>
<p>
The Hibernate Tutorial uses the HSQLDB in-memory
database to keep things simple. Since Hibernate
Spatial doesn't (yet) support HSQLDB, we have no
such luck. We require a postgis database. For
information on how to create a postgis database, you should consult
<a href="http://postgis.refractions.net/docs/">the postgis documentation</a>.
</p>
</p>
</section>
 
<section name="Creating a Spatially-Enabled EventManager">
<p>
We will create a small application to store and retrieve events we want to attend. (This is
the same use case as in the Hibernate Tutorial).
</p>
<subsection name="Setup">
<p>
We first need to set up our development environment. We will use the
<a href="http://maven.org/">Maven</a>
build tool in this tutorial (as this is also used in the Hibernate Tutorial).
</p>
<p>Maven can generate the basic structure of our simple application using the<code>mvn
archetype:generate</code>.
For this example, we specify type 15 (the default) and set
<code>groupId</code>
to<code>org.hibernatespatial.tutorials</code>,
<code>artifactId</code>
to
<code>event-tutorial</code>
and
<code>package</code>
to<code>event</code>.
</p>
<source>
mvn archetype:generate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [archetype:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] Preparing archetype:generate
[INFO] No goals needed for project - skipping
[INFO] Setting property: classpath.resource.loader.class =>
'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] [archetype:generate {execution: default-cli}]
Choose archetype:
1: internal -> appfuse-basic-jsf (AppFuse archetype for creating a web application with Hibernate,
Spring and JSF)
2: internal -> appfuse-basic-spring (AppFuse archetype for creating a web application with
Hibernate, Spring and Spring MVC)
3: internal -> appfuse-basic-struts (AppFuse archetype for creating a web application with
Hibernate, Spring and Struts 2)
4: internal -> appfuse-basic-tapestry (AppFuse archetype for creating a web application with
Hibernate, Spring and Tapestry 4)
5: internal -> appfuse-core (AppFuse archetype for creating a jar application with Hibernate and
Spring and XFire)
6: internal -> appfuse-modular-jsf (AppFuse archetype for creating a modular application with
Hibernate, Spring and JSF)
7: internal -> appfuse-modular-spring (AppFuse archetype for creating a modular application with
Hibernate, Spring and Spring MVC)
8: internal -> appfuse-modular-struts (AppFuse archetype for creating a modular application with
Hibernate, Spring and Struts 2)
9: internal -> appfuse-modular-tapestry (AppFuse archetype for creating a modular application with
Hibernate, Spring and Tapestry 4)
10: internal -> maven-archetype-j2ee-simple (A simple J2EE Java application)
11: internal -> maven-archetype-marmalade-mojo (A Maven plugin development project using marmalade)
12: internal -> maven-archetype-mojo (A Maven Java plugin development project)
13: internal -> maven-archetype-portlet (A simple portlet application)
14: internal -> maven-archetype-profiles ()
15: internal -> maven-archetype-quickstart ()
16: internal -> maven-archetype-site-simple (A simple site generation project)
17: internal -> maven-archetype-site (A more complex site project)
18: internal -> maven-archetype-webapp (A simple Java web application)
19: internal -> struts2-archetype-starter (A starter Struts 2 application with Sitemesh, DWR, and
Spring)
20: internal -> struts2-archetype-blank (A minimal Struts 2 application)
21: internal -> struts2-archetype-portlet (A minimal Struts 2 application that can be deployed as a
portlet)
22: internal -> struts2-archetype-dbportlet (A starter Struts 2 portlet that demonstrates a simple
CRUD interface with db backing)
23: internal -> struts2-archetype-plugin (A Struts 2 plugin)
24: internal -> shale-archetype-blank (A blank Shale web application with JSF)
25: internal -> maven-adf-archetype (Archetype to ease the burden of creating a new application
based with ADF)
26: internal -> data-app (A new Databinder application with sources and resources.)
27: internal -> jini-service-archetype (Archetype for Jini service project creation)
28: internal -> softeu-archetype-seam (JSF+Facelets+Seam Archetype)
29: internal -> softeu-archetype-seam-simple (JSF+Facelets+Seam (no persistence) Archetype)
30: internal -> softeu-archetype-jsf (JSF+Facelets Archetype)
31: internal -> jpa-maven-archetype (JPA application)
32: internal -> spring-osgi-bundle-archetype (Spring-OSGi archetype)
33: internal -> confluence-plugin-archetype (Atlassian Confluence plugin archetype)
34: internal -> maven-archetype-har (Hibernate Archive)
35: internal -> maven-archetype-sar (JBoss Service Archive)
36: internal -> wicket-archetype-quickstart (A simple Apache Wicket project)
Choose a number:
(1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36)
15: :
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Define value for groupId: : org.hibernatespatial.tutorials
Define value for artifactId: : event-tutorial
Define value for version: 1.0-SNAPSHOT: :
Define value for package: : event
Confirm properties configuration:
groupId: org.hibernatespatial.tutorials
artifactId: event-tutorial
version: 1.0-SNAPSHOT
package: event
Y: : Y
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
Downloading:
http://repo1.maven.org/maven2/org/apache/maven/archetypes/maven-archetype-quickstart/1.0/maven-archetype-quickstart-1.0.jar
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating OldArchetype: maven-archetype-quickstart:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.hibernatespatial.tutorials
[INFO] Parameter: packageName, Value: event
[INFO] Parameter: package, Value: event
[INFO] Parameter: artifactId, Value: event-tutorial
[INFO] Parameter: basedir, Value: /home/test
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] ********************* End of debug info from resources from generated POM
***********************
[INFO] OldArchetype created in dir: /home/test/event-tutorial
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 36 seconds
[INFO] Finished at: Mon Apr 05 17:23:22 CEST 2010
[INFO] Final Memory: 15M/158M
[INFO] ------------------------------------------------------------------------
 
 
</source>
<p>This results in the following directory structure.</p>
<source>
<![CDATA[
.
|-- pom.xml
`-- src
|-- main
| |-- java
| | |-- event
| | `-- App.java
`-- test
`-- java
`-- event
]]>
</source>
<p>We now need to edit the pom to add the required dependencies and repositories (see also the<a
href="mavenquick.html">Maven Quick Start</a>.).
</p>
<source>
<![CDATA[
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernatespatial.tutorials</groupId>
<artifactId>event-tutorial</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>event-tutorial</name>
<url>http://maven.apache.org</url>
 
<build>
<!-- we dont want the version to be part of the generated war file name -->
<finalName>${artifactId}</finalName>
</build>
 
 
<dependencies>
 
<!-- Hibernate Spatial for postgis. This will include Hibernate Spatial Core and JTS -->
<dependency>
<groupId>org.hibernatespatial</groupId>
<artifactId>hibernate-spatial-postgis</artifactId>
<version>1.0</version>
</dependency>
 
<!-- the Postgis JDBC driver -->
<dependency>
<groupId>org.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>1.3.5</version>
</dependency>
 
<!-- the postgresql driver -->
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>provided</scope>
<version>8.4-701.jdbc3</version>
</dependency>
 
<!-- Hibernate uses slf4j for logging, for our purposes here use the simple backend -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.5.11</version>
</dependency>
 
</dependencies>
 
 
<!-- add repositories for JTS and Hibernate Spatial and Hibernate (JBoss) -->
<repositories>
<repository>
<id>OSGEO GeoTools repo</id>
<url>http://download.osgeo.org/webdav/geotools</url>
</repository>
<repository>
<id>Hibernate Spatial repo</id>
<url>http://www.hibernatespatial.org/repository</url>
</repository>
<!-- add JBOSS repository for easy access to Hibernate libraries -->
<repository>
<id>JBOSS</id>
<url>http://repository.jboss.com/maven2</url>
</repository>
</repositories>
</project>
]]>
</source>
 
<p>With the command
<code>mvn dependency:list</code>
we can see which libraries are required for our minimal
Hibernate Spatial application.
</p>
 
<source>
mvn dependency:list
....
[INFO] The following files have been resolved:
[INFO] antlr:antlr:jar:2.7.6:compile
[INFO] com.vividsolutions:jts:jar:1.10:compile
[INFO] commons-collections:commons-collections:jar:3.1:compile
[INFO] dom4j:dom4j:jar:1.6.1:compile
[INFO] javassist:javassist:jar:3.11.0.GA:compile
[INFO] javax.transaction:jta:jar:1.1:compile
[INFO] org.hibernate:hibernate-core:jar:3.3.2.GA:compile
[INFO] org.hibernatespatial:hibernate-spatial:jar:1.0:compile
[INFO] org.hibernatespatial:hibernate-spatial-postgis:jar:1.0:compile
[INFO] org.postgis:postgis-jdbc:jar:1.3.5:compile
[INFO] org.slf4j:slf4j-api:jar:1.5.11:compile
[INFO] org.slf4j:slf4j-simple:jar:1.5.11:compile
[INFO] postgresql:postgresql:jar:8.4-701.jdbc3:provided
[INFO] xml-apis:xml-apis:jar:1.0.b2:compile
 
</source>
<p>Hibernate Spatial works with a wide range of versions of these libraries, so don't be too concerned
if you see
either more recent or slightly older versions.
</p>
 
</subsection>
 
<subsection name="The Event Class">
<p>Our persistent class is the
<code>Event</code>
class. Since this class
contains a geometry-valued property (a property of type Geometry), its instances
are geographic objects, or features.
</p>
<source>
<![CDATA[
package event;
 
import java.util.Date;
 
import com.vividsolutions.jts.geom.Point;
 
public class Event {
private Long id;
private String title;
private Date date;
private Point location;
 
public Event() {
}
 
public Long getId() {
return id;
}
 
private void setId(Long id) {
this.id = id;
}
 
public Date getDate() {
return date;
}
 
public void setDate(Date date) {
this.date = date;
}
 
public String getTitle() {
return title;
}
 
public void setTitle(String title) {
this.title = title;
}
 
public Point getLocation() {
return this.location;
}
 
public void setLocation(Point location) {
this.location = location;
}
}
]]>
</source>
<p>We put this file in the
<code>./src/main/java/event</code>
directory of the development directory.
</p>
</subsection>
 
<subsection name="The Mapping file">
<p>
To map this class to the database table, we create the following Hibernate Mapping file:
</p>
<source>
<![CDATA[
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="event">
<class name="Event" table="EVENTS">
 
<id name="id" column="EVENT_ID">
<generator class="native"/>
</id>
 
<property name="date" type="timestamp" column="EVENT_DATE"/>
 
<property name="title" type="string"/>
 
<property name="location" type="org.hibernatespatial.GeometryUserType" column="LOC"/>
</class>
</hibernate-mapping>
]]>
</source>
<p>Hibernate Spatial provides the
<code>GeometryUserType</code>
that enables Hibernate to store the
<code>location</code>
property properly.
</p>
 
<p>We save this mapping file in
<code>./src/main/resources/event/Event.hbm.xml</code>
along-side the java source file.
</p>
</subsection>
<subsection name="The Hibernate Configuration">
<p>
We proceed with the hibernate configuration file. The only difference
w.r.t. normal Hibernate configurations files is in the dialect
property. Hibernate Spatial extends the Hibernate<code>Dialect</code>s so that the spatial
features of the database are available within HQL and the
<code>SpatialCriteria</code>
(see below). So instead of using
the (in our case) PostgreSQLDialect, we use Hibernate Spatial's
extension of that dialect which is the PostGISDialect.
Our
<code>hibernate.cfg.xml</code>
looks like this:
<source>
<![CDATA[
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
 
<session-factory>
 
<!-- Database connection settings -->
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/events</property>
<property name="connection.username">postgres</property>
<property name="connection.password"></property>
 
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
 
<!-- SPATIAL SQL dialect -->
<property name="dialect">org.hibernatespatial.postgis.PostgisDialect</property>
 
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
 
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
 
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
 
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
 
<mapping resource="event/Event.hbm.xml"/>
 
</session-factory>
 
</hibernate-configuration>
]]>
 
</source>
As is usual when building with maven, we store this file in the
<code>./src/main/resources</code>
directory.
</p>
<p>
Note that this configuration file means that Hibernate will connect to the "events"
database on localhost, with username "postgres" and no password.
(on the test system used, postgres requires no password). You may need to change these
values depending on your set-up.
</p>
<p>
Also notice that the "hbm2dll.auto" property is activated. This will re-create the
database everytime the application is run (more precisely when the Hibernate SessionFactory is run).
</p>
</subsection>
</section>
 
<subsection name="The HibernateUtil helper">
The
<code>HibernatUtil</code>
class creates the Hibernate SessionFactory for the application, and provides a getter
to it. (The code below is copied from the Hibernate Tutorial without change).
<source>
<![CDATA[
package util;
 
 
import org.hibernate.*;
import org.hibernate.cfg.*;
 
public class HibernateUtil {
 
private static final SessionFactory sessionFactory;
 
static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
 
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
 
}
 
]]>
</source>
 
</subsection>
<subsection name="The EventManager">
<p>
We are now ready to write a first version of the main application class<code>EventManager</code>.
<source>
<![CDATA[
package event;
 
import org.hibernate.Session;
 
import java.util.Date;
 
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;
import com.vividsolutions.jts.io.ParseException;
 
import util.HibernateUtil;
 
public class EventManager {
 
public static void main(String[] args) {
EventManager mgr = new EventManager();
 
if (args[0].equals("store")) {
mgr.createAndStoreEvent("My Event", new Date(), args[1]);
}
 
HibernateUtil.getSessionFactory().close();
}
 
private void createAndStoreEvent(String title, Date theDate, String wktPoint) {
 
//First interpret the WKT string to a point
WKTReader fromText = new WKTReader();
Geometry geom = null;
try {
geom = fromText.read(wktPoint);
} catch (ParseException e) {
throw new RuntimeException("Not a WKT string:" + wktPoint);
}
if (!geom.getGeometryType().equals("Point")) {
throw new RuntimeException("Geometry must be a point. Got a " + geom.getGeometryType());
}
 
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 
session.beginTransaction();
 
Event theEvent = new Event();
theEvent.setTitle(title);
theEvent.setDate(theDate);
theEvent.setLocation((Point) geom);
session.save(theEvent);
 
session.getTransaction().commit();
}
}
]]>
</source>
We modified the
<code>EventManger</code>
implementation of the Hibernate Tutorial so that it stores
a point for the event. The point is given as a String in the Well-Known Text (WKT) format. See
<a href="http://www.vividsolutions.com/jts/javadoc/com/vividsolutions/jts/io/WKTReader.html">the JTS
WTKReader JavaDoc
</a>
for more information about the WTK format.
</p>
<p>
The development directory now looks like this.
<source>
<![CDATA[
.
|-- pom.xml
`-- src
|-- main
| |-- java
| | |-- event
| | | |-- Event.java
| | | `-- EventManager.java
| | `-- util
| | `-- HibernateUtil.java
| `-- resources
| |-- event
| | `-- Event.hbm.xml
| `-- hibernate.cfg.xml
`-- test
`-- java
`-- event
]]>
</source>
</p>
<p>
We can now build this program using maven:
<source>
<![CDATA[ $ mvn compile ]]>
</source>
 
 
We can now execute the program using maven as follows:
<br/>
(Note: the backslash in <code>POINT(10\ 0)</code>. this escapes the space in the POINT WKT
representation.)
<source>
<![CDATA[ mvn exec:java -Dexec.mainClass="event.EventManager" -Dexec.args="store POINT(10\ 5)"]]>