| /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 <Geometry Tagged Text>. |
| * @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 <Point Text>. |
| * @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 <LineString Text>. |
| * @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 <LineString Text>. |
| * @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 <MultiPoint Text>. |
| * @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 <Polygon Text>. |
| * @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 <MultiLineString Text>. |
| * @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 <MultiPolygon Text>. |
| * @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 <GeometryCollection Text>. |
| * @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)"]]> |