| /branches/jts_measured_geometry/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.junit.Test; |
| import static org.junit.Assert.*; |
| import org.hibernatespatial.Circle; |
| /** |
| * 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); |
| 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); |
| 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); |
| testAngle = angleIncr + twoPi; |
| expected = angleIncr; |
| actual = Circle.normalizeAngle(testAngle); |
| assertEquals(expected, actual); |
| testAngle = angleIncr - twoPi; |
| expected = angleIncr; |
| actual = Circle.normalizeAngle(testAngle); |
| assertEquals(expected, actual); |
| } |
| @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_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestStoreRetrieve.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-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.hibernate.Criteria; |
| import org.hibernate.Session; |
| import org.hibernate.SessionFactory; |
| import org.hibernate.Transaction; |
| import org.hibernate.cfg.Configuration; |
| import org.hibernatespatial.HBSpatialExtension; |
| import org.hibernatespatial.cfg.HSConfiguration; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import java.sql.SQLException; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import static org.junit.Assert.*; |
| /** |
| * This test class verifies whether the <code>Geometry</code>s retrieved |
| * are equal to the <code>Geometry</code>s stored. |
| */ |
| public class TestStoreRetrieve { |
| private static Logger LOGGER = LoggerFactory.getLogger(TestStoreRetrieve.class); |
| private final TestData testData; |
| private final DataSourceUtils dataSourceUtils; |
| private final GeometryEquality geometryEquality; |
| private final SessionFactory factory; |
| public TestStoreRetrieve(DataSourceUtils dataSourceUtils, TestData testData, GeometryEquality geometryEquality) { |
| this.geometryEquality = geometryEquality; |
| this.testData = testData; |
| this.dataSourceUtils = dataSourceUtils; |
| LOGGER.info("Setting up Hibernate"); |
| Configuration config = new Configuration(); |
| config.configure(); |
| config.addClass(GeomEntity.class); |
| //configure Hibernate Spatial based on this config |
| HSConfiguration hsc = new HSConfiguration(); |
| hsc.configure(config); |
| HBSpatialExtension.setConfiguration(hsc); |
| // build the session factory |
| factory = config.buildSessionFactory(); |
| LOGGER.info("Hibernate set-up complete."); |
| } |
| public TestStoreRetrieve(DataSourceUtils dataSourceUtils, TestData testData) { |
| this(dataSourceUtils, testData, new GeometryEquality()); |
| } |
| public void setUp() throws SQLException { |
| dataSourceUtils.deleteTestData(); |
| } |
| public void test_store_retrieve() throws ParseException { |
| Map<Integer, GeomEntity> stored = new HashMap<Integer, GeomEntity>(); |
| storeTestObjects(stored); |
| retrieveAndCompare(stored); |
| } |
| public void test_store_retrieve_null_geometry() { |
| storeNullGeometry(); |
| retrieveNullGeometry(); |
| } |
| private void retrieveAndCompare(Map<Integer, GeomEntity> stored) { |
| int id = -1; |
| try { |
| Session session = factory.getCurrentSession(); |
| session.beginTransaction(); |
| for (GeomEntity storedEntity : stored.values()) { |
| id = storedEntity.getId(); |
| GeomEntity retrievedEntity = (GeomEntity) session.get(GeomEntity.class, id); |
| Geometry retrievedGeometry = retrievedEntity.getGeom(); |
| Geometry storedGeometry = storedEntity.getGeom(); |
| String msg = createFailureMessage(storedEntity.getId(), storedGeometry, retrievedGeometry); |
| assertTrue(msg, geometryEquality.test(storedGeometry, retrievedGeometry)); |
| } |
| } catch (Exception e) { |
| throw new RuntimeException(String.format("Failure on case: %d", id), e); |
| } |
| finally { |
| factory.getCurrentSession().getTransaction().rollback(); |
| } |
| } |
| private String createFailureMessage(int id, Geometry storedGeometry, Geometry retrievedGeometry) { |
| String expectedText = (storedGeometry != null ? storedGeometry.toText() : "NULL"); |
| String retrievedText = (retrievedGeometry != null ? retrievedGeometry.toText() : "NULL"); |
| return String.format("Equality test failed for %d.\nExpected: %s\nReceived:%s", id, expectedText, retrievedText); |
| } |
| private void storeTestObjects(Map<Integer, GeomEntity> stored) { |
| Session session = null; |
| Transaction tx = null; |
| int id = -1; |
| try { |
| session = factory.openSession(); |
| // Every test instance is committed seperately |
| // to improve feedback in case of test failure |
| for (TestDataElement element : testData) { |
| id = element.id; |
| tx = session.beginTransaction(); |
| GeomEntity entity = GeomEntity.createFrom(element); |
| stored.put(entity.getId(), entity); |
| session.save(entity); |
| tx.commit(); |
| } |
| } catch (Exception e) { |
| if (tx != null) tx.rollback(); |
| throw new RuntimeException("Failed storing test object with id:" + id, e); |
| } finally { |
| if (session != null) session.close(); |
| } |
| } |
| private void storeNullGeometry() { |
| GeomEntity entity = null; |
| Session session = null; |
| Transaction tx = null; |
| try { |
| session = factory.openSession(); |
| tx = session.beginTransaction(); |
| entity = new GeomEntity(); |
| entity.setId(1); |
| entity.setType("NULL OBJECT"); |
| session.save(entity); |
| tx.commit(); |
| } catch (Exception e) { |
| if (tx != null) tx.rollback(); |
| throw new RuntimeException("Failed storing test object with id:" + entity.getId(), e); |
| } finally { |
| if (session != null) session.close(); |
| } |
| } |
| private void retrieveNullGeometry() { |
| try { |
| Session session = factory.getCurrentSession(); |
| session.beginTransaction(); |
| Criteria criteria = session.createCriteria(GeomEntity.class); |
| List<GeomEntity> retrieved = criteria.list(); |
| assertEquals("Expected exactly one result", 1, retrieved.size()); |
| GeomEntity entity = retrieved.get(0); |
| assertNull(entity.getGeom()); |
| } finally { |
| factory.getCurrentSession().getTransaction().rollback(); |
| } |
| } |
| } |
| Property changes: |
| Added: svn:keywords |
| + Id |
| /branches/jts_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestSpatialRestrictions.java |
|---|
| New file |
| 0,0 → 1,171 |
| /* |
| * $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.hibernate.Criteria; |
| import org.hibernate.Session; |
| import org.hibernate.SessionFactory; |
| import org.hibernate.cfg.Configuration; |
| import org.hibernate.criterion.Criterion; |
| import org.hibernatespatial.HBSpatialExtension; |
| import org.hibernatespatial.cfg.HSConfiguration; |
| import org.hibernatespatial.criterion.SpatialRestrictions; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import java.sql.SQLException; |
| import java.util.List; |
| import java.util.Map; |
| import static junit.framework.Assert.assertEquals; |
| import static org.junit.Assert.fail; |
| /** |
| * Created by IntelliJ IDEA. |
| * User: maesenka |
| * Date: Mar 18, 2010 |
| * Time: 10:02:24 PM |
| * To change this template use File | Settings | File Templates. |
| */ |
| public class TestSpatialRestrictions { |
| private static Logger LOGGER = LoggerFactory.getLogger(TestSpatialRestrictions.class); |
| private final AbstractExpectationsFactory expectationsFactory; |
| private static SessionFactory factory; |
| public TestSpatialRestrictions(AbstractExpectationsFactory expectationsFactory) { |
| this.expectationsFactory = expectationsFactory; |
| } |
| public static void setUpBeforeClass() { |
| // set up hibernate and register Spatialtest as a persistent entity |
| LOGGER.info("Setting up Hibernate"); |
| Configuration config = new Configuration(); |
| config.configure(); |
| config.addClass(GeomEntity.class); |
| //configure Hibernate Spatial based on this config |
| HSConfiguration hsc = new HSConfiguration(); |
| hsc.configure(config); |
| HBSpatialExtension.setConfiguration(hsc); |
| // build the session factory |
| factory = config.buildSessionFactory(); |
| LOGGER.info("Hibernate set-up complete."); |
| } |
| public void test_within() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getWithin(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.within("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| public void test_filter() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getFilter(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.filter("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| public void test_contains() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getContains(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.contains("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| public void test_crosses() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getCrosses(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.crosses("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| public void test_touches() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getTouches(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.touches("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| public void test_disjoint() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getDisjoint(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.disjoint("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| public void test_eq() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getEquals(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.eq("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| public void test_intersects() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getIntersects(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.intersects("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| public void test_overlaps() throws SQLException { |
| Map<Integer, Boolean> dbexpected = expectationsFactory.getOverlaps(expectationsFactory.getTestPolygon()); |
| Criterion spatialCriterion = SpatialRestrictions.overlaps("geom", expectationsFactory.getTestPolygon()); |
| retrieveAndCompare(dbexpected, spatialCriterion); |
| } |
| private void retrieveAndCompare(Map<Integer, Boolean> dbexpected, Criterion spatialCriterion) { |
| try { |
| Session session = factory.getCurrentSession(); |
| session.beginTransaction(); |
| Criteria criteria = session.createCriteria(GeomEntity.class); |
| criteria.add(spatialCriterion); |
| compare(dbexpected, criteria.list()); |
| } finally { |
| //rollback because we have only read-only access. |
| factory.getCurrentSession().getTransaction().rollback(); |
| } |
| } |
| //TODO -- clean this up! |
| private void compare(Map<Integer, Boolean> dbexpected, List list) { |
| int cnt = 0; |
| for (Integer id : dbexpected.keySet()) { |
| if (dbexpected.get(id)) { |
| cnt++; |
| if (!findInList(id, (List<GeomEntity>) list)) |
| fail(String.format("Expected object with id= %d, but not found in result", id)); |
| } |
| } |
| assertEquals(cnt, list.size()); |
| LOGGER.info(String.format("Found %d objects within test polygon.", cnt)); |
| } |
| private boolean findInList(Integer id, List<GeomEntity> list) { |
| for (GeomEntity entity : list) { |
| if (entity.getId() == id) return true; |
| } |
| return false; |
| } |
| } |
| Property changes: |
| Added: svn:keywords |
| + Id |
| /branches/jts_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/test/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_measured_geometry/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_measured_geometry/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_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/test/DataSourceUtils.java |
|---|
| New file |
| 0,0 → 1,344 |
| /* |
| * $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 { |
| public final static String TEST_POLYGON_WKT = "POLYGON((0 0, 50 0, 100 100, 0 100, 0 0))"; |
| 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_measured_geometry/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_measured_geometry/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_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/test/AbstractExpectationsFactory.java |
|---|
| New file |
| 0,0 → 1,701 |
| /* |
| * $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.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 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 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 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 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, 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, 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); |
| /** |
| * 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(dataSourceUtils.TEST_POLYGON_WKT); |
| polygon.setSRID(getTestSrid()); |
| return polygon; |
| } 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_measured_geometry/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_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/TestMLineStringGetCoordinatesBetween.java |
|---|
| New file |
| 0,0 → 1,513 |
| /* |
| * $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.MCoordinate; |
| 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_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/TestEventLocator.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 © 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.MCoordinate; |
| 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_measured_geometry/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_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/MLineStringTest.java |
|---|
| New file |
| 0,0 → 1,741 |
| /** |
| * $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.MCoordinate; |
| 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.00000000000000001); |
| assertEquals(mcexp.y, mctest.y, 0.00000000000000001); |
| assertEquals(mcexp.z, mctest.z, 0.00000000000000001); |
| 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, mcotest); |
| 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, mctest); |
| } 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 == 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++; |
| } |
| // if we go in reverse we should meet all points in reverse order |
| cs = arbitraryLine.getCoordinatesBetween(maxM, minM); |
| assertNotNull(cs); |
| assertTrue(cs.length > 0); |
| coar = cs[0].toCoordinateArray(); |
| j = 0; |
| for (int i = maxIdx; i >= minIdx; 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, mctest); |
| 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); |
| // in this case, a 2nd and 3rd coordinates are the same instance, |
| // giving one a duplicate internal measure |
| // The state is monotone, and dynseg from measures 0-1 should yield |
| // the equivalent of a similar |
| // Line where the duplicate coordinate does not exist. In other |
| // words the duplicate is essentially ignored. |
| MLineString nonStrictDupPointLine = mgeomFactory |
| .createMLineString(new MCoordinate[]{mc0, mc1, mc1, mc2, |
| mc3}); |
| MLineString strictLine = mgeomFactory |
| .createMLineString(new MCoordinate[]{mc0, mc1, mc2, mc3}); |
| CoordinateSequence[] nonStrictDupSeq = nonStrictDupPointLine |
| .getCoordinatesBetween(mc0.m, mc2_1.m); |
| CoordinateSequence[] strictSeq = strictLine.getCoordinatesBetween( |
| mc0.m, mc1.m); |
| assertEquals(nonStrictDupSeq.length, 1); |
| assertEquals(strictSeq.length, 1); |
| assertTrue(coordCompare.compare(nonStrictDupSeq[0], strictSeq[0]) == 0); |
| assertEquals(strictSeq[0].size(), 2); |
| // 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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/jts/test/TestMeasuredGeometryConstruction.java |
|---|
| New file |
| 0,0 → 1,77 |
| package org.hibernatespatial.jts.test; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.CoordinateSequence; |
| import com.vividsolutions.jts.geom.GeometryFactory; |
| import com.vividsolutions.jts.geom.LineString; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinate; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequence; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequenceFactory; |
| import org.junit.Test; |
| import static junit.framework.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| /** |
| * Tests the construction of <code>MeasuredGeometry</code>s. |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 29, 2010 |
| */ |
| public class TestMeasuredGeometryConstruction { |
| MeasuredCoordinateSequenceFactory coordinateFactory = new MeasuredCoordinateSequenceFactory(); |
| GeometryFactory geometryFactory = new GeometryFactory(coordinateFactory); |
| @Test |
| public void test_linestring_created_with_measuredcoordinatesequence() { |
| MeasuredCoordinateSequence coordinates = coordinateFactory.create(3, 2); |
| coordinates.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(1,2,3)); |
| coordinates.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(3,4,5)); |
| coordinates.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(6,7,8)); |
| LineString lineString = geometryFactory.createLineString(coordinates); |
| assertTrue(lineString.getCoordinateN(0).equals2D(new Coordinate(1,2))); |
| assertTrue(lineString.getCoordinateN(1).equals2D(new Coordinate(3,4))); |
| assertTrue(lineString.getCoordinateN(2).equals2D(new Coordinate(6,7))); |
| assertEquals(3, lineString.getCoordinateSequence().getOrdinate(0, CoordinateSequence.M), Math.ulp(10d)); |
| assertEquals(5, lineString.getCoordinateSequence().getOrdinate(1, CoordinateSequence.M), Math.ulp(10d)); |
| assertEquals(8, lineString.getCoordinateSequence().getOrdinate(2, CoordinateSequence.M), Math.ulp(10d)); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(0, CoordinateSequence.Z))); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(1, CoordinateSequence.Z))); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(2, CoordinateSequence.Z))); |
| } |
| @Test |
| public void test_linestring_created_with_coordinatesequence() { |
| Coordinate[] coordinates = new Coordinate[]{ |
| new Coordinate(1,2), |
| new Coordinate(3,4), |
| new Coordinate(6,7)}; |
| LineString lineString = geometryFactory.createLineString(coordinates); |
| assertTrue(lineString.getCoordinateN(0).equals2D(new Coordinate(1,2))); |
| assertTrue(lineString.getCoordinateN(1).equals2D(new Coordinate(3,4))); |
| assertTrue(lineString.getCoordinateN(2).equals2D(new Coordinate(6,7))); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(0, CoordinateSequence.M))); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(1, CoordinateSequence.M))); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(2, CoordinateSequence.M))); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(0, CoordinateSequence.Z))); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(1, CoordinateSequence.Z))); |
| assertTrue(Double.isNaN(lineString.getCoordinateSequence().getOrdinate(2, CoordinateSequence.Z))); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/jts/geom/TestMeasuredCoordinateSequence.java |
|---|
| New file |
| 0,0 → 1,307 |
| package org.hibernatespatial.jts.geom; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.CoordinateSequence; |
| import com.vividsolutions.jts.geom.impl.CoordinateArraySequence; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinate; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateArraySequence; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequence; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequenceFactory; |
| import org.junit.Test; |
| import static org.junit.Assert.*; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 22, 2010 |
| */ |
| public class TestMeasuredCoordinateSequence { |
| private MeasuredCoordinateSequence seq; |
| @Test |
| public void test_constructor_size() { |
| MeasuredCoordinateSequenceFactory mcsf = new MeasuredCoordinateSequenceFactory(); |
| seq = mcsf.create(2, 4); |
| Coordinate c0 = new Coordinate(1, 2, 3); |
| seq.setMeasuredCoordinate(0, new MeasuredCoordinate(c0, 4)); |
| Coordinate c1 = new Coordinate(5, 6, 7); |
| seq.setMeasuredCoordinate(1, new MeasuredCoordinate(c1, 8)); |
| assertEquals(c0, seq.getCoordinate(0)); |
| assertEquals(4d, seq.getM(0), Math.ulp(4d)); |
| assertEquals(c1, seq.getCoordinate(1)); |
| assertEquals(8d, seq.getM(1), Math.ulp(8d)); |
| try { |
| seq.setMeasuredCoordinate(2, new MeasuredCoordinate(c1, 8)); |
| fail(); |
| } catch (ArrayIndexOutOfBoundsException e) { |
| } |
| } |
| @Test |
| public void test_constructor_coordinate_array() { |
| Coordinate[] coordinates = new Coordinate[]{ |
| new Coordinate(1, 1), |
| new Coordinate(2, 3), |
| new Coordinate(4, 5) |
| }; |
| seq = new MeasuredCoordinateArraySequence(coordinates); |
| assertEquals(coordinates.length, seq.size()); |
| assertEquals(4, seq.getDimension()); |
| assertEquals(4, seq.getOrdinate(2, CoordinateSequence.X), Math.ulp(4f)); |
| assertEquals(5, seq.getOrdinate(2, CoordinateSequence.Y), Math.ulp(5f)); |
| assertEquals(Double.NaN, seq.getOrdinate(2, CoordinateSequence.M), 0.1f); |
| //test null parameter |
| seq = new MeasuredCoordinateArraySequence((Coordinate[])null); |
| assertEquals(0, seq.size()); |
| } |
| @Test |
| public void test_constructor_coordinateseq() { |
| CoordinateSequence s = new CoordinateArraySequence(10); |
| seq = new MeasuredCoordinateArraySequence(s); |
| assertEquals(10, seq.size()); |
| MeasuredCoordinateSequence ms = new MeasuredCoordinateArraySequence(3); |
| ms.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(1, 2, 1)); |
| ms.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(3, 4, 2)); |
| ms.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(5, 6, 3)); |
| seq = new MeasuredCoordinateArraySequence((CoordinateSequence) ms); |
| assertEquals(1, seq.getOrdinate(0, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(2, seq.getOrdinate(0, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(0, CoordinateSequence.Z))); |
| assertEquals(1, seq.getOrdinate(0, CoordinateSequence.M), Math.ulp(10)); |
| assertEquals(3, seq.getOrdinate(1, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(4, seq.getOrdinate(1, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(1, CoordinateSequence.Z))); |
| assertEquals(2, seq.getOrdinate(1, CoordinateSequence.M), Math.ulp(10)); |
| assertEquals(5, seq.getOrdinate(2, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(6, seq.getOrdinate(2, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(2, CoordinateSequence.Z))); |
| assertEquals(3, seq.getOrdinate(2, CoordinateSequence.M), Math.ulp(10)); |
| //test null paramater |
| seq = new MeasuredCoordinateArraySequence((CoordinateSequence)null); |
| assertEquals(0, seq.size()); |
| } |
| @Test |
| public void test_constructor_coordinateseq_doubles() { |
| CoordinateSequence s = new CoordinateArraySequence(10); |
| double[] measures = new double[10]; |
| seq = new MeasuredCoordinateArraySequence(s, measures); |
| assertEquals(10, seq.size()); |
| try { |
| double[] m2 = new double[8]; |
| seq = new MeasuredCoordinateArraySequence(s, m2); |
| fail(); |
| } catch (IllegalArgumentException e) { |
| } |
| seq = new MeasuredCoordinateArraySequence((CoordinateSequence) null, null); |
| assertEquals(0, seq.size()); |
| //test null paramater |
| seq = new MeasuredCoordinateArraySequence((CoordinateSequence)null, null); |
| assertEquals(0, seq.size()); |
| } |
| @Test |
| public void test_constructor_coordinates_doubles() { |
| Coordinate[] s = new Coordinate[10]; |
| double[] measures = new double[10]; |
| seq = new MeasuredCoordinateArraySequence(s, measures); |
| assertEquals(10, seq.size()); |
| try { |
| double[] m2 = new double[8]; |
| seq = new MeasuredCoordinateArraySequence(s, m2); |
| fail(); |
| } catch (IllegalArgumentException e) { |
| } |
| seq = new MeasuredCoordinateArraySequence((Coordinate[]) null, null); |
| assertEquals(0, seq.size()); |
| } |
| @Test |
| public void test_constructor_measurecoordinateseq() { |
| MeasuredCoordinateSequence ms = new MeasuredCoordinateArraySequence(3); |
| ms.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(1, 2, 1)); |
| ms.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(3, 4, 2)); |
| ms.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(5, 6, 3)); |
| seq = new MeasuredCoordinateArraySequence(ms); |
| assertEquals(1, seq.getOrdinate(0, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(2, seq.getOrdinate(0, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(0, CoordinateSequence.Z))); |
| assertEquals(1, seq.getOrdinate(0, CoordinateSequence.M), Math.ulp(10)); |
| assertEquals(3, seq.getOrdinate(1, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(4, seq.getOrdinate(1, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(1, CoordinateSequence.Z))); |
| assertEquals(2, seq.getOrdinate(1, CoordinateSequence.M), Math.ulp(10)); |
| assertEquals(5, seq.getOrdinate(2, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(6, seq.getOrdinate(2, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(2, CoordinateSequence.Z))); |
| assertEquals(3, seq.getOrdinate(2, CoordinateSequence.M), Math.ulp(10)); |
| seq = new MeasuredCoordinateArraySequence((MeasuredCoordinateSequence) null); |
| assertEquals(0, seq.size()); |
| } |
| @Test |
| public void test_constructor_measurecoordinates() { |
| MeasuredCoordinate[] ms = new MeasuredCoordinate[3]; |
| ms[0] = MeasuredCoordinate.to2DM(1, 2, 1); |
| ms[1] = MeasuredCoordinate.to2DM(3, 4, 2); |
| ms[2] = MeasuredCoordinate.to2DM(5, 6, 3); |
| seq = new MeasuredCoordinateArraySequence(ms); |
| assertEquals(1, seq.getOrdinate(0, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(2, seq.getOrdinate(0, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(0, CoordinateSequence.Z))); |
| assertEquals(1, seq.getOrdinate(0, CoordinateSequence.M), Math.ulp(10)); |
| assertEquals(3, seq.getOrdinate(1, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(4, seq.getOrdinate(1, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(1, CoordinateSequence.Z))); |
| assertEquals(2, seq.getOrdinate(1, CoordinateSequence.M), Math.ulp(10)); |
| assertEquals(5, seq.getOrdinate(2, CoordinateSequence.X), Math.ulp(10)); |
| assertEquals(6, seq.getOrdinate(2, CoordinateSequence.Y), Math.ulp(10)); |
| assertTrue(Double.isNaN(seq.getOrdinate(2, CoordinateSequence.Z))); |
| assertEquals(3, seq.getOrdinate(2, CoordinateSequence.M), Math.ulp(10)); |
| seq = new MeasuredCoordinateArraySequence((MeasuredCoordinate[]) null); |
| assertEquals(0, seq.size()); |
| } |
| @Test |
| public void test_can_set_m_ordinates() { |
| seq = new MeasuredCoordinateArraySequence(2); |
| seq.setOrdinate(0, CoordinateSequence.X, 0); |
| seq.setOrdinate(0, CoordinateSequence.Y, 1); |
| seq.setOrdinate(0, CoordinateSequence.Z, 2); |
| seq.setOrdinate(0, CoordinateSequence.M, 3); |
| for (int i = 0; i < seq.getDimension(); i++) { |
| assertEquals(i, seq.getOrdinate(0, i), Math.ulp(10)); |
| } |
| } |
| @Test |
| public void test_if_on_create_m_ordinates_are_NaN() { |
| seq = new MeasuredCoordinateArraySequence(2); |
| seq.setOrdinate(0, CoordinateSequence.X, 0); |
| seq.setOrdinate(0, CoordinateSequence.Y, 1); |
| seq.setOrdinate(0, CoordinateSequence.Z, 2); |
| assertTrue(Double.isNaN(seq.getOrdinate(0, CoordinateSequence.M))); |
| assertTrue(Double.isNaN(seq.getM(0))); |
| } |
| @Test |
| public void test_get_m() { |
| seq = new MeasuredCoordinateArraySequence(2); |
| seq.setOrdinate(0, CoordinateSequence.X, 0); |
| seq.setOrdinate(0, CoordinateSequence.Y, 1); |
| seq.setOrdinate(0, CoordinateSequence.Z, 2); |
| seq.setOrdinate(0, CoordinateSequence.M, 3); |
| assertEquals(0, seq.getX(0), Math.ulp(10d)); |
| assertEquals(1, seq.getY(0), Math.ulp(10d)); |
| assertEquals(2, seq.getZ(0), Math.ulp(10d)); |
| assertEquals(3, seq.getM(0), Math.ulp(10d)); |
| } |
| @Test |
| public void test_setCoordinateAndM() { |
| seq = new MeasuredCoordinateArraySequence(2); |
| seq.setMeasuredCoordinate(0, MeasuredCoordinate.to3DM(0, 1, 2, 3)); |
| for (int i = 0; i < seq.getDimension(); i++) { |
| assertEquals(i, seq.getOrdinate(0, i), Math.ulp(10d)); |
| } |
| } |
| @Test |
| public void test_test_copy_measured_coordinate_index_coordinate(){ |
| seq = new MeasuredCoordinateArraySequence(4); |
| seq.setMeasuredCoordinate(2, MeasuredCoordinate.to3DM(0, 1, 2, 3)); |
| MeasuredCoordinate mCoordinate = new MeasuredCoordinate(); |
| seq.getMeasuredCoordinate(0, mCoordinate); |
| assertEquals(0, mCoordinate.getX(), Math.ulp(10d)); |
| assertEquals(0, mCoordinate.getY(), Math.ulp(10d)); |
| assertEquals(Double.NaN, mCoordinate.getZ(), Math.ulp(10d)); |
| assertEquals(Double.NaN, mCoordinate.getM(), Math.ulp(10d)); |
| seq.getMeasuredCoordinate(2, mCoordinate); |
| assertEquals(0, mCoordinate.getX(), Math.ulp(10d)); |
| assertEquals(1, mCoordinate.getY(), Math.ulp(10d)); |
| assertEquals(2, mCoordinate.getZ(), Math.ulp(10d)); |
| assertEquals(3, mCoordinate.getM(), Math.ulp(10d)); |
| seq.setMeasuredCoordinate(1, MeasuredCoordinate.to2D(0, 1)); |
| seq.getMeasuredCoordinate(1, mCoordinate); |
| assertEquals(0, mCoordinate.getX(), Math.ulp(10d)); |
| assertEquals(1, mCoordinate.getY(), Math.ulp(10d)); |
| assertEquals(Double.NaN, mCoordinate.getZ(), Math.ulp(10d)); |
| assertEquals(Double.NaN, mCoordinate.getM(), Math.ulp(10d)); |
| seq.setMeasuredCoordinate(3, MeasuredCoordinate.to2DM(0, 1, 2)); |
| seq.getMeasuredCoordinate(3, mCoordinate); |
| assertEquals(0, mCoordinate.getX(), Math.ulp(10d)); |
| assertEquals(1, mCoordinate.getY(), Math.ulp(10d)); |
| assertEquals(Double.NaN, mCoordinate.getZ(), Math.ulp(10d)); |
| assertEquals(2, mCoordinate.getM(), Math.ulp(10d)); |
| } |
| @Test |
| public void test_clone() { |
| seq = new MeasuredCoordinateArraySequence(2); |
| MeasuredCoordinate mc0 = MeasuredCoordinate.to3DM(0, 1, 2, 3); |
| MeasuredCoordinate mc1 = MeasuredCoordinate.to3DM(4, 5, 6, 7); |
| seq.setMeasuredCoordinate(0, mc0); |
| seq.setMeasuredCoordinate(1, mc1); |
| MeasuredCoordinateArraySequence cloned = (MeasuredCoordinateArraySequence) seq.clone(); |
| //check that clone has same values as original |
| assertTrue(mc0.equals3DWithMeasure(cloned.getMeasuredCoordinate(0))); |
| assertTrue(mc1.equals3DWithMeasure(cloned.getMeasuredCoordinate(1))); |
| //check independence |
| cloned.setOrdinate(0, CoordinateSequence.M, 10); |
| cloned.setOrdinate(1, CoordinateSequence.M, 11); |
| //check that clone has same values as original |
| assertEquals(3, seq.getOrdinate(0, CoordinateSequence.M), Math.ulp(10d)); |
| assertEquals(7, seq.getOrdinate(1, CoordinateSequence.M), Math.ulp(10d)); |
| assertFalse(mc0.equals3DWithMeasure(cloned.getMeasuredCoordinate(0))); |
| assertFalse(mc1.equals3DWithMeasure(cloned.getMeasuredCoordinate(1))); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/jts/linearref/TestMeasuredLineString.java |
|---|
| New file |
| 0,0 → 1,428 |
| package org.hibernatespatial.jts.linearref; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.GeometryFactory; |
| import com.vividsolutions.jts.geom.LineString; |
| import com.vividsolutions.jts.geom.Point; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinate; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequence; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequenceFactory; |
| import org.junit.Before; |
| import org.junit.Test; |
| import static junit.framework.Assert.assertNull; |
| import static junit.framework.Assert.fail; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 29, 2010 |
| */ |
| public class TestMeasuredLineString { |
| MeasuredCoordinateSequenceFactory coordinateFactory = new MeasuredCoordinateSequenceFactory(); |
| GeometryFactory geometryFactory = new GeometryFactory(coordinateFactory); |
| MeasuredLineString mli; |
| LineString[] testLineStrings; |
| @Before |
| public void setUp() { |
| MeasuredCoordinateSequence seq0 = coordinateFactory.create(4, 4); |
| seq0.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(1, 2, 0)); |
| seq0.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(2, 3, 1)); |
| seq0.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(3, 4, 2)); |
| seq0.setMeasuredCoordinate(3, MeasuredCoordinate.to2DM(4, 5, 3)); |
| //monotonic increasing |
| MeasuredCoordinateSequence seq1 = coordinateFactory.create(4, 4); |
| seq1.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(0, 0, 0)); |
| seq1.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(1, 0, 1)); |
| seq1.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(2, 0, 2)); |
| seq1.setMeasuredCoordinate(3, MeasuredCoordinate.to2DM(3, 0, 3)); |
| //monotonic decreasing |
| MeasuredCoordinateSequence seq2 = coordinateFactory.create(4, 4); |
| seq2.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(3, 0, 3)); |
| seq2.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(2, 0, 2)); |
| seq2.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(1, 0, 1)); |
| seq2.setMeasuredCoordinate(3, MeasuredCoordinate.to2DM(0, 0, 0)); |
| //non-monotonic |
| MeasuredCoordinateSequence seq3 = coordinateFactory.create(4, 4); |
| seq3.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(1, 0, 0)); |
| seq3.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(2, 0, 5)); |
| seq3.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(3, 0, 2)); |
| seq3.setMeasuredCoordinate(3, MeasuredCoordinate.to2DM(8, 0, 7)); |
| //non-measured |
| MeasuredCoordinateSequence seq4 = coordinateFactory.create(4, 4); |
| seq4.setMeasuredCoordinate(0, MeasuredCoordinate.to2D(1, 0)); |
| seq4.setMeasuredCoordinate(1, MeasuredCoordinate.to2D(2, 0)); |
| seq4.setMeasuredCoordinate(2, MeasuredCoordinate.to2D(3, 0)); |
| seq4.setMeasuredCoordinate(3, MeasuredCoordinate.to2D(8, 0)); |
| //non-strict monotonic increasing |
| MeasuredCoordinateSequence seq5 = coordinateFactory.create(4, 4); |
| seq5.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(0, 0, 0)); |
| seq5.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(1, 0, 1)); |
| seq5.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(2, 0, 1)); |
| seq5.setMeasuredCoordinate(3, MeasuredCoordinate.to2DM(3, 0, 2)); |
| //monotonic decreasing |
| MeasuredCoordinateSequence seq6 = coordinateFactory.create(4, 4); |
| seq6.setMeasuredCoordinate(0, MeasuredCoordinate.to2DM(3, 0, 2)); |
| seq6.setMeasuredCoordinate(1, MeasuredCoordinate.to2DM(2, 0, 1)); |
| seq6.setMeasuredCoordinate(2, MeasuredCoordinate.to2DM(1, 0, 1)); |
| seq6.setMeasuredCoordinate(3, MeasuredCoordinate.to2DM(0, 0, 0)); |
| testLineStrings = new LineString[]{ |
| geometryFactory.createLineString(seq0), |
| geometryFactory.createLineString(seq1), |
| geometryFactory.createLineString(seq2), |
| geometryFactory.createLineString(seq3), |
| geometryFactory.createLineString(seq4), |
| geometryFactory.createLineString(seq5), |
| geometryFactory.createLineString(seq6) |
| }; |
| } |
| @Test |
| public void test_constructor_on_null() { |
| try { |
| mli = new MeasuredLineString(null); |
| fail(); |
| } catch (IllegalArgumentException e) { |
| //OK |
| } |
| } |
| @Test |
| public void test_get_measure_at_coordinate() { |
| mli = new MeasuredLineString(testLineStrings[1]); |
| double received = mli.getMeasureAtCoordinate(new Coordinate(1.5d, 0d), 0.01d); |
| assertEquals(1.5d, received, Math.ulp(5d)); |
| received = mli.getMeasureAtCoordinate(new Coordinate(0.0d, 0d), 0.01d); |
| assertEquals(0d, received, Math.ulp(5d)); |
| received = mli.getMeasureAtCoordinate(new Coordinate(2.0d, 0d), 0.01d); |
| assertEquals(2d, received, Math.ulp(5d)); |
| received = mli.getMeasureAtCoordinate(new Coordinate(3.009d, 0d), 0.01d); |
| assertEquals(3d, received, Math.ulp(5d)); |
| received = mli.getMeasureAtCoordinate(new Coordinate(5.0d, 0d), 0.01d); |
| assertTrue(Double.isNaN(received)); |
| } |
| @Test |
| public void test_get_coordinate_at_measure_monotone_increasing() { |
| mli = new MeasuredLineString(testLineStrings[1]); |
| assertNull(mli.getCoordinateAtMeasure(-1d)); |
| assertNull(mli.getCoordinateAtMeasure(3.2d)); |
| assertEquals(MeasuredCoordinate.to2DM(0, 0, 0), mli.getCoordinateAtMeasure(0)); |
| assertEquals(MeasuredCoordinate.to2DM(0.8, 0, 0.8), mli.getCoordinateAtMeasure(0.8)); |
| assertEquals(MeasuredCoordinate.to2DM(2.1, 0.0, 2.1), mli.getCoordinateAtMeasure(2.1)); |
| assertEquals(MeasuredCoordinate.to2DM(3.0, 0, 3.0), mli.getCoordinateAtMeasure(3)); |
| } |
| @Test |
| public void test_get_coordinate_at_measure_non_strict_monotone_increasing() { |
| mli = new MeasuredLineString(testLineStrings[5]); |
| assertNull(mli.getCoordinateAtMeasure(-1d)); |
| assertNull(mli.getCoordinateAtMeasure(3.2d)); |
| assertEquals(MeasuredCoordinate.to2DM(0, 0, 0), mli.getCoordinateAtMeasure(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0, 0, 1.0), mli.getCoordinateAtMeasure(1.0)); |
| } |
| @Test |
| public void test_get_coordinate_at_measure_monotone_decreasing() { |
| mli = new MeasuredLineString(testLineStrings[2]); |
| assertNull(mli.getCoordinateAtMeasure(-1d)); |
| assertNull(mli.getCoordinateAtMeasure(3.2d)); |
| assertEquals(MeasuredCoordinate.to2DM(0, 0, 0), mli.getCoordinateAtMeasure(0)); |
| assertEquals(MeasuredCoordinate.to2DM(0.8, 0, 0.8), mli.getCoordinateAtMeasure(0.8)); |
| assertEquals(MeasuredCoordinate.to2DM(2.1, 0.0, 2.1), mli.getCoordinateAtMeasure(2.1)); |
| assertEquals(MeasuredCoordinate.to2DM(3.0, 0, 3.0), mli.getCoordinateAtMeasure(3)); |
| } |
| @Test |
| public void test_get_coordinate_at_measure_non_monotone() { |
| mli = new MeasuredLineString(testLineStrings[3]); |
| assertNull(mli.getCoordinateAtMeasure(-1d)); |
| assertNull(mli.getCoordinateAtMeasure(9d)); |
| assertEquals(MeasuredCoordinate.to2DM(1, 0, 0), mli.getCoordinateAtMeasure(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.5, 0, 2.5), mli.getCoordinateAtMeasure(2.5)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0, 0.0, 5.0d), mli.getCoordinateAtMeasure(5.0d)); |
| assertEquals(MeasuredCoordinate.to2DM(7.0, 0, 6.0), mli.getCoordinateAtMeasure(6)); |
| } |
| @Test |
| public void test_min_measure() { |
| for (int i = 0; i < 4; i++) { |
| mli = new MeasuredLineString(testLineStrings[i]); |
| assertEquals(0.0d, mli.getMinMeasure(), Math.ulp(1.0d)); |
| } |
| mli = new MeasuredLineString(testLineStrings[4]); |
| assertTrue(Double.isNaN(mli.getMinMeasure())); |
| } |
| @Test |
| public void test_max_measure() { |
| for (int i = 0; i < 3; i++) { |
| mli = new MeasuredLineString(testLineStrings[i]); |
| assertEquals(3.0d, mli.getMaxMeasure(), Math.ulp(1.0d)); |
| } |
| mli = new MeasuredLineString(testLineStrings[3]); |
| assertEquals(7.0d, mli.getMaxMeasure(), Math.ulp(1.0d)); |
| mli = new MeasuredLineString(testLineStrings[4]); |
| assertTrue(Double.isNaN(mli.getMaxMeasure())); |
| } |
| @Test |
| public void test_get_coordinates_between_monotone_increasing() { |
| mli = new MeasuredLineString(testLineStrings[1]); |
| MeasuredCoordinateSequence[] sequences = mli.getCoordinatesBetween(1.5d, 2.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(1.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 2.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(2.5d, 0.0d, 2.5d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(0.25d, 0.75d); |
| assertEquals(1, sequences.length); |
| assertEquals(2, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.25d, 0.0d, 0.25d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(0.75d, 0.0d, 0.75d), sequences[0].getMeasuredCoordinate(1)); |
| sequences = mli.getCoordinatesBetween(0d, 1.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.0d, 0.0d, 0.0d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(1.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(1.5d, 0d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.0d, 0.0d, 0.0d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(1.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(-1d, 1.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.0d, 0.0d, 0.0d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(1.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(-1d, -0.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(0, sequences[0].size()); |
| sequences = mli.getCoordinatesBetween(0.5d, 5d); |
| assertEquals(1, sequences.length); |
| assertEquals(4, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.5d, 0.0d, 0.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 2.0d), sequences[0].getMeasuredCoordinate(2)); |
| assertEquals(MeasuredCoordinate.to2DM(3.0d, 0.0d, 3.0d), sequences[0].getMeasuredCoordinate(3)); |
| sequences = mli.getCoordinatesBetween(2.5d, 2.75d); |
| assertEquals(1, sequences.length); |
| assertEquals(2, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(2.5d, 0.0d, 2.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(2.75d, 0.0d, 2.75d), sequences[0].getMeasuredCoordinate(1)); |
| sequences = mli.getCoordinatesBetween(0.0d, 0.0d); |
| assertEquals(1, sequences.length); |
| assertEquals(0, sequences[0].size()); |
| sequences = mli.getCoordinatesBetween(0.0d, 1.0d); |
| assertEquals(1, sequences.length); |
| assertEquals(2, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.0d, 0.0d, 0.0d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| } |
| @Test |
| public void test_get_coordinates_between_monotone_decreasing() { |
| mli = new MeasuredLineString(testLineStrings[2]); |
| MeasuredCoordinateSequence[] sequences = mli.getCoordinatesBetween(1.5d, 2.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(2.5d, 0.0d, 2.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 2.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(1.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(0d, 1.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(1.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(0.0d, 0.0d, 0.0d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(1.5d, 0d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(1.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(0.0d, 0.0d, 0.0d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(-1d, 1.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(1.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(0.0d, 0.0d, 0.0d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(-1d, -0.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(0, sequences[0].size()); |
| sequences = mli.getCoordinatesBetween(0.5d, 5d); |
| assertEquals(1, sequences.length); |
| assertEquals(4, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(3.0d, 0.0d, 3.0d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 2.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(2)); |
| assertEquals(MeasuredCoordinate.to2DM(0.5d, 0.0d, 0.5d), sequences[0].getMeasuredCoordinate(3)); |
| sequences = mli.getCoordinatesBetween(0.0d, 0.0d); |
| assertEquals(1, sequences.length); |
| assertEquals(0, sequences[0].size()); |
| sequences = mli.getCoordinatesBetween(0.0d, 1.0d); |
| assertEquals(1, sequences.length); |
| assertEquals(2, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(0.0d, 0.0d, 0.0d), sequences[0].getMeasuredCoordinate(1)); |
| } |
| @Test |
| public void test_get_coordinates_between_non_strict_monotone_increasing() { |
| mli = new MeasuredLineString(testLineStrings[5]); |
| MeasuredCoordinateSequence[] sequences = mli.getCoordinatesBetween(0.5d, 1.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(4, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.5d, 0.0d, 0.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(2)); |
| assertEquals(MeasuredCoordinate.to2DM(2.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(3)); |
| sequences = mli.getCoordinatesBetween(0.5d, 1.0d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.5d, 0.0d, 0.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(1.5d, 0.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(4, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(0.5d, 0.0d, 0.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(2)); |
| assertEquals(MeasuredCoordinate.to2DM(2.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(3)); |
| } |
| @Test |
| public void test_get_coordinates_between_non_strict_monotone_decreasing() { |
| mli = new MeasuredLineString(testLineStrings[6]); |
| MeasuredCoordinateSequence[] sequences = mli.getCoordinatesBetween(0.5d, 1.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(4, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(2.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(2)); |
| assertEquals(MeasuredCoordinate.to2DM(0.5d, 0.0d, 0.5d), sequences[0].getMeasuredCoordinate(3)); |
| sequences = mli.getCoordinatesBetween(0.5d, 1.0d); |
| assertEquals(1, sequences.length); |
| assertEquals(3, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(0.5d, 0.0d, 0.5d), sequences[0].getMeasuredCoordinate(2)); |
| sequences = mli.getCoordinatesBetween(1.5d, 0.5d); |
| assertEquals(1, sequences.length); |
| assertEquals(4, sequences[0].size()); |
| assertEquals(MeasuredCoordinate.to2DM(2.5d, 0.0d, 1.5d), sequences[0].getMeasuredCoordinate(0)); |
| assertEquals(MeasuredCoordinate.to2DM(2.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(1)); |
| assertEquals(MeasuredCoordinate.to2DM(1.0d, 0.0d, 1.0d), sequences[0].getMeasuredCoordinate(2)); |
| assertEquals(MeasuredCoordinate.to2DM(0.5d, 0.0d, 0.5d), sequences[0].getMeasuredCoordinate(3)); |
| } |
| @Test |
| public void test_get_coordinates_between_non_monotone() { |
| mli = new MeasuredLineString(testLineStrings[3]); |
| try { |
| MeasuredCoordinateSequence[] sequences = mli.getCoordinatesBetween(1.5d, 2.5d); |
| fail(); |
| } catch(IllegalStateException e){ |
| //OK |
| } |
| } |
| @Test |
| public void test_locate_along(){ |
| mli = new MeasuredLineString(testLineStrings[1]); |
| Point received = (Point)mli.locateAlong(0.0d); |
| MeasuredCoordinateSequence mseq = (MeasuredCoordinateSequence)received.getCoordinateSequence(); |
| assertEquals(MeasuredCoordinate.to2DM(0,0,0), mseq.getMeasuredCoordinate(0)); |
| received = (Point)mli.locateAlong(0.5d); |
| mseq = (MeasuredCoordinateSequence)received.getCoordinateSequence(); |
| assertEquals(MeasuredCoordinate.to2DM(0.5,0,0.5), mseq.getMeasuredCoordinate(0)); |
| received = (Point)mli.locateAlong(2.5d); |
| mseq = (MeasuredCoordinateSequence)received.getCoordinateSequence(); |
| assertEquals(MeasuredCoordinate.to2DM(2.5,0,2.5), mseq.getMeasuredCoordinate(0)); |
| received = (Point)mli.locateAlong(3.5d); |
| assertTrue(received.isEmpty()); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/wkb/TestWKBGeometryType.java |
|---|
| New file |
| 0,0 → 1,25 |
| package org.hibernatespatial.wkb; |
| import org.junit.Test; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 11, 2010 |
| */ |
| public class TestWKBGeometryType { |
| @Test |
| public void test_code_point(){ |
| WKBGeometryType wgt = WKBGeometryType.valueOf(1); |
| assertEquals(WKBGeometryType.POINT, wgt); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/wkb/TestWKB.java |
|---|
| New file |
| 0,0 → 1,81 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.Geometry; |
| import com.vividsolutions.jts.io.ParseException; |
| import org.hibernatespatial.test.EWKTReader; |
| import org.hibernatespatial.test.GeometryEquality; |
| import org.junit.Test; |
| import java.util.*; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 11, 2010 |
| */ |
| public class TestWKB { |
| public static final Map<String, String> testcases = new HashMap<String, String>(); |
| public static final EWKTReader wktReader = new EWKTReader(); |
| public static final GeometryEquality equalityTest = new GeometryEquality(); |
| static { |
| testcases.put("POINT(10 3)", "010100000000000000000024400000000000000840"); |
| testcases.put("POINT(1 2 3)", "0101000080000000000000F03F00000000000000400000000000000840"); |
| testcases.put("POINT(1 2 3 4)", "01010000C0000000000000F03F000000000000004000000000000008400000000000001040"); |
| testcases.put("POINTM(1 2 4)", "0101000040000000000000F03F00000000000000400000000000001040"); |
| testcases.put("SRID=4326;POINT(1 2 3 4)", "01010000E0E6100000000000000000F03F000000000000004000000000000008400000000000001040"); |
| testcases.put(" LINESTRING(1 2,3 4,5 6)", "010200000003000000000000000000F03F00000000000000400000000000000840000000000000104000000000000014400000000000001840"); |
| } |
| @Test |
| public void test_decode() throws ParseException, UnsupportedConversionException { |
| for (String wkt : testcases.keySet()) { |
| Geometry geom; |
| if (wkt.startsWith("SRID=")) { |
| String[] tokens=wkt.split(";"); |
| int srid = getSrid(tokens[0]); |
| geom = wktReader.read(tokens[1]); |
| geom.setSRID(srid); |
| }else{ |
| geom = wktReader.read(wkt); |
| } |
| Bytes bytes = Bytes.from(testcases.get(wkt)); |
| Geometry received = WKB.fromWKB(bytes); |
| assertTrue("Failure decoding: " + wkt, equalityTest.test(geom, received)); |
| } |
| } |
| private int getSrid(String sridDeclaration) { |
| String[] tokens = sridDeclaration.split("="); |
| return Integer.parseInt(tokens[1]); |
| } |
| @Test |
| public void test_encode() throws ParseException, UnsupportedConversionException { |
| for (String wkt : testcases.keySet()) { |
| Geometry geom = wktReader.read(wkt); |
| Bytes bytes = WKB.toWKB(geom, WKBByteOrder.NDR); |
| assertEquals("Failure encoding: " + wkt, testcases.get(wkt), bytes.toString()); |
| } |
| } |
| //TODO -- use all test cases -- find a cleaner way to test for ndr/xdr encoding/decoding |
| @Test |
| public void test_point_with_ndr_byte_order() throws ParseException, UnsupportedConversionException { |
| String wkt = "POINT(10 3)"; |
| Geometry geom = wktReader.read(wkt); |
| Bytes bytes = WKB.toWKB(geom, WKBByteOrder.NDR); |
| assertNotNull(bytes); |
| System.out.println("bytes = " + bytes.toString()); |
| assertTrue(equalityTest.test(geom, WKB.fromWKB(bytes))); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/test/java/org/hibernatespatial/wkb/TestBytes.java |
|---|
| New file |
| 0,0 → 1,242 |
| package org.hibernatespatial.wkb; |
| import org.junit.Test; |
| import static junit.framework.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Oct 29, 2010 |
| */ |
| public class TestBytes { |
| @Test |
| public void testBytesFromString() { |
| String byteTxt = "0120E6FF"; |
| Bytes bStream = Bytes.from(byteTxt); |
| assertEquals(4, bStream.limit()); |
| assertEquals(1, bStream.get()); |
| assertEquals(32, bStream.get()); |
| assertEquals((byte) 230, bStream.get()); |
| assertEquals((byte) 255, bStream.get()); |
| } |
| @Test |
| public void test_bytes_from_odd_length_string() { |
| String byteTxt = "0120E6FFE"; |
| Bytes bStream = Bytes.from(byteTxt); |
| assertEquals(4, bStream.limit()); |
| } |
| @Test |
| public void test_throws_NumberFormatException_if_string_not_hexadecimal() { |
| try { |
| Bytes.from("02FFKK"); |
| fail(); |
| } catch (NumberFormatException e) { |
| //OK |
| } |
| } |
| @Test |
| public void test_return_empty_Bytes_on_empty_string() { |
| Bytes bytes = Bytes.from(""); |
| assertTrue(bytes.isEmpty()); |
| assertEquals(0, bytes.limit()); |
| } |
| @Test |
| public void test_throw_IllegalArgumentException_on_null_string() { |
| try { |
| Bytes bytes = Bytes.from((String) null); |
| fail(); |
| } catch (IllegalArgumentException e) { |
| //OK |
| } |
| } |
| @Test |
| public void test_toString(){ |
| String hxStr = "037FB4C7"; |
| Bytes bytes = Bytes.from(hxStr); |
| assertEquals(hxStr, bytes.toString()); |
| } |
| @Test |
| public void test_big_endian_int() { |
| String hxStr = "037FB4C7"; |
| int expectedValue = 58700999; |
| Bytes bytes = Bytes.from(hxStr); |
| bytes.setWKBByteOrder(WKBByteOrder.XDR); |
| assertEquals(expectedValue, bytes.getInt()); |
| } |
| @Test |
| public void test_string_or_bytes_gives_same_result() { |
| String hxStr = "037FB4C7"; |
| byte[] byteArray = new byte[]{0x03, 0x7F, (byte) 0xB4, (byte) 0xC7}; |
| int expectedValue = 58700999; |
| Bytes bytes = Bytes.from(hxStr); |
| bytes.setWKBByteOrder(WKBByteOrder.XDR); |
| assertEquals(expectedValue, bytes.getInt()); |
| Bytes bytesFromArray = Bytes.from(byteArray); |
| bytesFromArray.setWKBByteOrder(WKBByteOrder.XDR); |
| assertEquals(expectedValue, bytesFromArray.getInt()); |
| } |
| @Test |
| public void test_little_endian_int() { |
| String hxStr = "C7B47F03"; |
| int expectedValue = 58700999; |
| Bytes bytes = Bytes.from(hxStr); |
| bytes.setWKBByteOrder(WKBByteOrder.NDR); |
| assertEquals(expectedValue, bytes.getInt()); |
| } |
| @Test |
| public void test_insufficient_bytes_for_retrieving_long_throws_exception() { |
| String hxStr = "C7B47F03"; |
| Bytes bytes = Bytes.from(hxStr); |
| try { |
| Long lng = bytes.getLong(); |
| } catch (RuntimeException e) { |
| //OK |
| } |
| } |
| @Test |
| public void test_get_unsigned_as_long() { |
| String hxStr = "FFFFFFFF"; |
| Bytes bytes = Bytes.from(hxStr); |
| long expected = 4294967295L; |
| assertEquals(expected, bytes.getUInt()); |
| bytes = Bytes.from("80000000"); |
| assertEquals(2147483648L, bytes.getUInt()); |
| bytes = Bytes.from("00000001"); |
| assertEquals(1L, bytes.getUInt()); |
| bytes = Bytes.from("7FFFFFFF"); |
| assertEquals(2147483647L, bytes.getUInt()); |
| } |
| @Test |
| public void test_retrieve_byteorder() { |
| String hxStr = "FFFFFFFF"; |
| Bytes bytes = Bytes.from(hxStr); |
| bytes.setWKBByteOrder(WKBByteOrder.XDR); |
| assertEquals(WKBByteOrder.XDR, bytes.getWKBByteOrder()); |
| bytes.setWKBByteOrder(WKBByteOrder.NDR); |
| assertEquals(WKBByteOrder.NDR, bytes.getWKBByteOrder()); |
| } |
| @Test |
| public void test_create_bytes_having_specified_size() { |
| Bytes bytes = Bytes.allocate(100); |
| assertEquals(100, bytes.capacity()); |
| } |
| @Test |
| public void test_put_xdr_double() { |
| double expected = 1234.56789; |
| Bytes bytes = Bytes.allocate(8); |
| bytes.setWKBByteOrder(WKBByteOrder.XDR); |
| bytes.putDouble(expected); |
| bytes.rewind(); |
| double d = bytes.getDouble(); |
| assertEquals(expected, d); |
| } |
| @Test |
| public void test_put_ndr_double() { |
| double expected = 1234.56789; |
| Bytes bytes = Bytes.allocate(8); |
| bytes.setWKBByteOrder(WKBByteOrder.NDR); |
| bytes.putDouble(expected); |
| bytes.rewind(); |
| double d = bytes.getDouble(); |
| assertEquals(expected, d); |
| } |
| @Test |
| public void test_put_byte() { |
| byte expected = (byte) 0xFF; |
| Bytes bytes = Bytes.allocate(1); |
| bytes.put(expected); |
| bytes.rewind(); |
| assertEquals(expected, bytes.get()); |
| } |
| @Test |
| public void test_put_int() { |
| int expected = 0xFF; |
| Bytes bytes = Bytes.allocate(4); |
| bytes.putInt(expected); |
| bytes.rewind(); |
| assertEquals(expected, bytes.getInt()); |
| } |
| @Test |
| public void test_put_long() { |
| long expected = Long.MAX_VALUE; |
| Bytes bytes = Bytes.allocate(8); |
| bytes.putLong(expected); |
| bytes.rewind(); |
| assertEquals(expected, bytes.getLong()); |
| } |
| @Test |
| public void test_put_float() { |
| float expected = 1234.567f; |
| Bytes bytes = Bytes.allocate(4); |
| bytes.putFloat(expected); |
| bytes.rewind(); |
| assertEquals(expected, bytes.getFloat()); |
| } |
| @Test |
| public void test_put_uint() { |
| long expected = 4294967295L; |
| Bytes bytes = Bytes.allocate(4); |
| bytes.putUInt(expected); |
| bytes.rewind(); |
| assertEquals(expected, bytes.getUInt()); |
| } |
| @Test |
| public void test_put_too_large_value_in_uint_throws_exception() { |
| long value = Bytes.UINT_MAX_VALUE; |
| Bytes bytes = Bytes.allocate(4); |
| bytes.putUInt(value); |
| bytes.rewind(); |
| assertEquals(value, bytes.getUInt()); |
| value++; |
| Bytes bytes2 = Bytes.allocate(4); |
| try { |
| bytes2.putUInt(value); |
| fail(); |
| } catch (RuntimeException e) { |
| //OK |
| } |
| } |
| } |
| /branches/jts_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBGeometryType.java |
|---|
| New file |
| 0,0 → 1,32 |
| package org.hibernatespatial.wkb; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 11, 2010 |
| */ |
| public enum WKBGeometryType { |
| POINT((byte)1), |
| LINESTRING((byte)2); |
| byte code; |
| private WKBGeometryType(byte code){ |
| this.code = code; |
| } |
| public static WKBGeometryType valueOf(int code){ |
| //drop the higher-order bits |
| byte codeByte = (byte)code; |
| for (WKBGeometryType type : values()){ |
| if (type.code == codeByte) return type; |
| } |
| throw new IllegalArgumentException("Numeric code " + code + " not known"); |
| } |
| public long getTypeCode() { |
| return this.code; |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBLineStringEncoder.java |
|---|
| New file |
| 0,0 → 1,31 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.LineString; |
| import org.hibernatespatial.jts.geom.CoordinateDimension; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 12, 2010 |
| */ |
| public class WKBLineStringEncoder extends WKBEncoder<LineString> { |
| @Override |
| protected long getGeometryType() { |
| return 0; //To change body of implemented methods use File | Settings | File Templates. |
| } |
| @Override |
| protected void writeNumComponents(LineString geometry, Bytes output) { |
| //To change body of implemented methods use File | Settings | File Templates. |
| } |
| @Override |
| protected void writeComponents(LineString geometry, CoordinateDimension dimension, Bytes output) { |
| //To change body of implemented methods use File | Settings | File Templates. |
| } |
| @Override |
| protected int calculateSize(LineString geom, CoordinateDimension dimension) { |
| return 0; //To change body of implemented methods use File | Settings | File Templates. |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKB.java |
|---|
| New file |
| 0,0 → 1,80 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.Geometry; |
| import com.vividsolutions.jts.geom.GeometryFactory; |
| import com.vividsolutions.jts.geom.LineString; |
| import com.vividsolutions.jts.geom.Point; |
| import org.hibernatespatial.mgeom.MGeometryFactory; |
| import java.util.HashMap; |
| import java.util.Map; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Oct 29, 2010 |
| */ |
| public class WKB { |
| public static final int Z_FLAG = 0x80000000; |
| public static final int M_FLAG = 0x40000000; |
| public static final int SRID_FLAG = 0x20000000; |
| public static class Encoders { |
| private static final Map ENCODERS = new HashMap(); |
| static { |
| register(Point.class, new WKBPointEncoder()); |
| register(LineString.class, new WKBLineStringEncoder()); |
| } |
| public static <G extends Geometry> void register(Class<G> geometryClass, WKBEncoder<G> encoderClass){ |
| ENCODERS.put(geometryClass, encoderClass); |
| } |
| public static <G extends Geometry> WKBEncoder<G> getFor(G geometry){ |
| return (WKBEncoder<G>)ENCODERS.get(geometry.getClass()); |
| } |
| } |
| public static class Decoders { |
| private static final Map<WKBGeometryType, WKBElementDecoder> DECODERS = new HashMap<WKBGeometryType, WKBElementDecoder>(); |
| private static final WKBDecoder DECODER; |
| static { |
| GeometryFactory factory = new MGeometryFactory(); |
| DECODER = new WKBDecoder(); |
| DECODERS.put(WKBGeometryType.POINT, new WKBPointDecoder(factory)); |
| DECODERS.put(WKBGeometryType.LINESTRING, new WKBLineStringDecoder(factory)); |
| } |
| public static WKBElementDecoder getFor(WKBGeometryType type){ |
| return DECODERS.get(type); |
| } |
| public static WKBDecoder getWKBDecoder(){ |
| return DECODER; |
| } |
| } |
| public static <G extends Geometry> Bytes toWKB(G geometry) throws UnsupportedConversionException { |
| return toWKB(geometry, null); |
| } |
| public static <G extends Geometry> Bytes toWKB(G geometry, WKBByteOrder byteOrder) throws UnsupportedConversionException { |
| WKBEncoder<G> encoder = Encoders.getFor(geometry); |
| return encoder.encode(geometry, byteOrder); |
| } |
| public static Geometry fromWKB(Bytes bytes) { |
| return Decoders.getWKBDecoder().decode(bytes); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBByteOrder.java |
|---|
| New file |
| 0,0 → 1,44 |
| package org.hibernatespatial.wkb; |
| import java.nio.ByteOrder; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Oct 29, 2010 |
| */ |
| public enum WKBByteOrder { |
| XDR(ByteOrder.BIG_ENDIAN, (byte)0), |
| NDR(ByteOrder.LITTLE_ENDIAN, (byte)1); |
| ByteOrder order; |
| byte orderByte; |
| private WKBByteOrder(ByteOrder order, byte orderByte){ |
| this.order = order; |
| this.orderByte = orderByte; |
| } |
| public static WKBByteOrder valueOf(byte orderByte){ |
| for(WKBByteOrder wbo : values()){ |
| if(orderByte == wbo.byteValue()) return wbo; |
| } |
| throw new IllegalArgumentException("Order byte must be 0 or 1"); |
| } |
| ByteOrder getByteOrder(){ |
| return this.order; |
| } |
| byte byteValue() { |
| return orderByte; |
| } |
| static WKBByteOrder valueOf(ByteOrder byteOrder){ |
| for (WKBByteOrder wkbOrder : values()){ |
| if (wkbOrder.getByteOrder() == byteOrder) return wkbOrder; |
| } |
| throw new IllegalArgumentException(); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBElementDecoder.java |
|---|
| New file |
| 0,0 → 1,37 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.Geometry; |
| import com.vividsolutions.jts.geom.GeometryFactory; |
| import org.hibernatespatial.jts.geom.CoordinateDimension; |
| import org.hibernatespatial.mgeom.MCoordinate; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 12, 2010 |
| */ |
| public abstract class WKBElementDecoder { |
| private final GeometryFactory factory; |
| public WKBElementDecoder(GeometryFactory factory){ |
| this.factory = factory; |
| } |
| protected GeometryFactory factory(){ |
| return this.factory; |
| } |
| public abstract Geometry decode(Bytes nativeGeom, CoordinateDimension dimension); |
| protected Coordinate readCoordinate(Bytes bytes, CoordinateDimension dimension) { |
| MCoordinate coordinate = new MCoordinate(bytes.getDouble(), bytes.getDouble()); |
| if (dimension.hasZ()) { |
| coordinate.z = bytes.getDouble(); |
| } |
| if (dimension.hasM()){ |
| coordinate.m = bytes.getDouble(); |
| } |
| return coordinate; |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBEncoder.java |
|---|
| New file |
| 0,0 → 1,90 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.Geometry; |
| import org.hibernatespatial.jts.geom.CoordinateDimension; |
| import org.hibernatespatial.mgeom.MCoordinate; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 11, 2010 |
| */ |
| public abstract class WKBEncoder<G extends Geometry> { |
| public Bytes encode(G geom) { |
| return encode(geom, null); |
| } |
| public Bytes encode(G geom, WKBByteOrder wbo) { |
| CoordinateDimension dimension = CoordinateDimension.valueFor(hasZ(geom), hasM(geom)); |
| Bytes output = Bytes.allocate(calculateSize(geom, dimension)); |
| if (wbo != null) { |
| output.setWKBByteOrder(wbo); |
| } |
| writeByteOrder(output); |
| writeTypeCodeAndSRID(geom, dimension, output); |
| writeNumComponents(geom, output); |
| writeComponents(geom, dimension, output); |
| output.rewind(); |
| return output; |
| } |
| protected void writeByteOrder(Bytes output){ |
| output.put(output.getWKBByteOrder().byteValue()); |
| } |
| protected void writeCoordinate(Coordinate coordinate, CoordinateDimension dimension, Bytes output) { |
| output.putDouble(coordinate.x); |
| output.putDouble(coordinate.y); |
| if(dimension.hasZ()){ |
| output.putDouble(coordinate.z); |
| } |
| if (dimension.hasM()){ |
| double m = 0.0; |
| if (coordinate instanceof MCoordinate){ |
| m = ((MCoordinate)coordinate).m; |
| } |
| output.putDouble(m); |
| } |
| } |
| protected boolean hasM(Geometry geom) { |
| Coordinate co = geom.getCoordinate(); |
| if (co instanceof MCoordinate) { |
| return ! Double.isNaN(((MCoordinate)co).m); |
| } |
| return false; |
| } |
| protected boolean hasZ(Geometry geom) { |
| return !Double.isNaN(geom.getCoordinate().z); |
| } |
| protected void writeTypeCodeAndSRID(G geometry, CoordinateDimension dimension, Bytes output){ |
| long typeCode = getGeometryType(); |
| boolean hasSRID = (geometry.getSRID() > 0); |
| if (hasSRID) |
| typeCode |= WKB.SRID_FLAG; |
| if (dimension.hasM()) |
| typeCode |= WKB.M_FLAG; |
| if (dimension.hasZ()) |
| typeCode |= WKB.Z_FLAG; |
| output.putUInt(typeCode); |
| if(hasSRID){ |
| output.putInt(geometry.getSRID()); |
| } |
| } |
| protected abstract long getGeometryType(); |
| protected abstract void writeNumComponents(G geometry, Bytes output); |
| protected abstract void writeComponents(G geometry, CoordinateDimension dimension, Bytes output); |
| protected abstract int calculateSize(G geom, CoordinateDimension dimension); |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBPointDecoder.java |
|---|
| New file |
| 0,0 → 1,26 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.Geometry; |
| import com.vividsolutions.jts.geom.GeometryFactory; |
| import org.hibernatespatial.jts.geom.CoordinateDimension; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 11, 2010 |
| */ |
| public class WKBPointDecoder extends WKBElementDecoder { |
| public WKBPointDecoder(GeometryFactory factory) { |
| super(factory); |
| } |
| public Geometry decode(Bytes bytes, CoordinateDimension dimension) { |
| Coordinate coordinate = readCoordinate(bytes, dimension); |
| return factory().createPoint(coordinate); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/Bytes.java |
|---|
| New file |
| 0,0 → 1,198 |
| package org.hibernatespatial.wkb; |
| import java.nio.BufferOverflowException; |
| import java.nio.BufferUnderflowException; |
| import java.nio.ByteBuffer; |
| import java.nio.ByteOrder; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Oct 29, 2010 |
| */ |
| public class Bytes { |
| static final long UINT_MAX_VALUE = 4294967295L; |
| final private ByteBuffer buffer; |
| private Bytes(ByteBuffer buffer) { |
| this.buffer = buffer; |
| } |
| public static Bytes from(String text) { |
| if (text == null) throw new IllegalArgumentException("Null not allowed."); |
| int size = text.length() / 2; // this will drop the last char, if text is not even. |
| byte[] byteArray = new byte[size]; |
| ByteBuffer buffer = ByteBuffer.wrap(byteArray); |
| for (int i = 0; i < text.length() - 1; i += 2) { |
| byte b = (byte) Integer.parseInt(text.substring(i, i + 2), 16); |
| buffer.put(b); |
| } |
| buffer.rewind(); |
| return new Bytes(buffer); |
| } |
| public String toString(){ |
| StringBuilder builder = new StringBuilder(); |
| rewind(); |
| for (int i = 0; i < limit(); i++){ |
| int hexValue = readByte(); |
| appendByte(builder, hexValue); |
| } |
| return builder.toString(); |
| } |
| private void appendByte(StringBuilder builder, int hexValue) { |
| String byteStr = Integer.toHexString(hexValue).toUpperCase(); |
| if (byteStr.length() == 1 ) { |
| builder.append("0").append(byteStr); |
| } else { |
| builder.append(byteStr); |
| } |
| } |
| private int readByte() { |
| int hexValue = get(); |
| hexValue = (hexValue << 24) >>> 24; |
| return hexValue; |
| } |
| public static Bytes from(byte[] bytes){ |
| ByteBuffer buffer = ByteBuffer.wrap(bytes); |
| return new Bytes(buffer); |
| } |
| public static Bytes allocate(int capacity) { |
| return new Bytes(ByteBuffer.allocate(capacity)); |
| } |
| public byte get() { |
| try{ |
| return this.buffer.get(); |
| } catch(BufferOverflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public void put(byte value){ |
| try{ |
| this.buffer.put(value); |
| }catch(BufferOverflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public int capacity(){ |
| return this.buffer.capacity(); |
| } |
| public int limit() { |
| return this.buffer.limit(); |
| } |
| public Bytes limit(int newLimit) { |
| buffer.limit(newLimit); |
| return this; |
| } |
| public void rewind(){ |
| this.buffer.rewind(); |
| } |
| public boolean isEmpty() { |
| return buffer.limit() == 0; |
| } |
| public void setWKBByteOrder(WKBByteOrder wbo){ |
| this.buffer.order(wbo.getByteOrder()); |
| } |
| public int getInt() { |
| try { |
| return this.buffer.getInt(); |
| }catch (BufferUnderflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public void putInt(int value){ |
| try{ |
| this.buffer.putInt(value); |
| }catch(BufferOverflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public long getLong(){ |
| try { |
| return this.buffer.getLong(); |
| }catch (BufferUnderflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public void putLong(long value){ |
| try{ |
| this.buffer.putLong(value); |
| }catch(BufferOverflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public float getFloat(){ |
| try { |
| return this.buffer.getFloat(); |
| }catch (BufferUnderflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public void putFloat(float value){ |
| try{ |
| this.buffer.putFloat(value); |
| }catch(BufferOverflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public double getDouble(){ |
| try { |
| return this.buffer.getDouble(); |
| }catch (BufferUnderflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public void putDouble(Double value){ |
| try{ |
| this.buffer.putDouble(value); |
| }catch(BufferOverflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public long getUInt() { |
| try { |
| long value = this.buffer.getInt(); // read integer in a long |
| return (value << 32) >>> 32; //shift 32-bytes left (dropping all |
| } catch(BufferUnderflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public void putUInt(long value){ |
| if (value > UINT_MAX_VALUE ) throw new RuntimeException("Value received doesn't fit in unsigned integer"); |
| try{ |
| this.buffer.putInt((int)value); |
| }catch(BufferOverflowException e){ |
| throw new RuntimeException(e); |
| } |
| } |
| public WKBByteOrder getWKBByteOrder() { |
| ByteOrder order = this.buffer.order(); |
| return WKBByteOrder.valueOf(order); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBLineStringDecoder.java |
|---|
| New file |
| 0,0 → 1,29 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.CoordinateSequence; |
| import com.vividsolutions.jts.geom.Geometry; |
| import com.vividsolutions.jts.geom.GeometryFactory; |
| import org.hibernatespatial.jts.geom.CoordinateDimension; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 12, 2010 |
| */ |
| public class WKBLineStringDecoder extends WKBElementDecoder { |
| public WKBLineStringDecoder(GeometryFactory factory) { |
| super(factory); |
| } |
| @Override |
| public Geometry decode(Bytes bytes, CoordinateDimension dimension) { |
| int numPoints = bytes.getInt(); |
| CoordinateSequence coordinates = factory().getCoordinateSequenceFactory().create(numPoints, dimension.getNumDimensions()); |
| for (long i = 0; i < numPoints; numPoints++){ |
| Coordinate co = readCoordinate(bytes,dimension); |
| // TO BE COMPLETED...... |
| } |
| return factory().createLinearRing(coordinates); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBDecoder.java |
|---|
| New file |
| 0,0 → 1,57 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.Geometry; |
| import org.hibernatespatial.jts.geom.CoordinateDimension; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 11, 2010 |
| */ |
| public class WKBDecoder { |
| public Geometry decode(Bytes bytes){ |
| bytes.rewind(); |
| alignByteOrder(bytes); |
| int typeCode = readTypeCode(bytes); |
| WKBGeometryType type = WKBGeometryType.valueOf(typeCode); |
| int srid = readSRID(bytes, typeCode); |
| WKBElementDecoder decoder = WKB.Decoders.getFor(type); |
| Geometry geom = decoder.decode(bytes, getCoordinateDimension(typeCode)); |
| setSRID(geom, srid, typeCode); |
| return geom; |
| } |
| private CoordinateDimension getCoordinateDimension(int typeCode){ |
| boolean hasM = (typeCode & WKB.M_FLAG) == WKB.M_FLAG; |
| boolean hasZ = (typeCode & WKB.Z_FLAG) == WKB.Z_FLAG; |
| return CoordinateDimension.valueFor(hasZ, hasM); |
| } |
| private void setSRID(Geometry geom, int srid, int typeCode) { |
| if (hasSrid(typeCode)) geom.setSRID(srid); |
| } |
| private int readSRID(Bytes bytes, int typeCode) { |
| if (hasSrid(typeCode)){ |
| return bytes.getInt(); |
| } |
| return -1; |
| } |
| private boolean hasSrid(int typeCode) { |
| return (typeCode & WKB.SRID_FLAG) == WKB.SRID_FLAG; |
| } |
| private int readTypeCode(Bytes bytes) { |
| return (int)bytes.getUInt(); |
| } |
| private void alignByteOrder(Bytes bytes) { |
| byte orderByte = bytes.get(); |
| WKBByteOrder byteOrder = WKBByteOrder.valueOf(orderByte); |
| bytes.setWKBByteOrder(byteOrder); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/UnsupportedConversionException.java |
|---|
| New file |
| 0,0 → 1,8 |
| package org.hibernatespatial.wkb; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 12, 2010 |
| */ |
| public class UnsupportedConversionException extends Exception { |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/wkb/WKBPointEncoder.java |
|---|
| New file |
| 0,0 → 1,37 |
| package org.hibernatespatial.wkb; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.Point; |
| import org.hibernatespatial.jts.geom.CoordinateDimension; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 11, 2010 |
| */ |
| public class WKBPointEncoder extends WKBEncoder<Point> { |
| protected long getGeometryType() { |
| return WKBGeometryType.POINT.getTypeCode(); |
| } |
| @Override |
| protected void writeNumComponents(Point geometry, Bytes output) { |
| } |
| @Override |
| protected void writeComponents(Point geometry, CoordinateDimension dim, Bytes output) { |
| Coordinate coordinate = geometry.getCoordinate(); |
| writeCoordinate(coordinate, dim, output); |
| } |
| @Override |
| protected int calculateSize(Point geom, CoordinateDimension dimension) { |
| int size = 21; //minimal size |
| if (geom.getSRID() > 0) size += 4; |
| if (dimension.hasZ()) size += 8; |
| if (dimension.hasM()) size += 8; |
| return size; |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialFunction.java |
|---|
| New file |
| 0,0 → 1,45 |
| 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"), |
| filter("Min. boundingbox overlap") //Minimum Bounding Rectangle overlaps |
| ; |
| private final String description; |
| SpatialFunction(String specification) { |
| this.description = specification; |
| } |
| } |
| /branches/jts_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/SpatialRestrictions.java |
|---|
| New file |
| 0,0 → 1,132 |
| /** |
| * $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, value, |
| SpatialRelation.EQUALS); |
| } |
| public static SpatialRelateExpression within(String propertyName, Geometry value) { |
| return new SpatialRelateExpression(propertyName, value, value, |
| SpatialRelation.WITHIN); |
| } |
| public static SpatialRelateExpression contains(String propertyName, Geometry value) { |
| return new SpatialRelateExpression(propertyName, value, value, |
| SpatialRelation.CONTAINS); |
| } |
| public static SpatialRelateExpression crosses(String propertyName, Geometry value) { |
| return new SpatialRelateExpression(propertyName, value, value, |
| SpatialRelation.CROSSES); |
| } |
| public static SpatialRelateExpression disjoint(String propertyName, Geometry value) { |
| return new SpatialRelateExpression(propertyName, null, value, |
| SpatialRelation.DISJOINT); |
| } |
| public static SpatialRelateExpression intersects(String propertyName, Geometry value) { |
| return new SpatialRelateExpression(propertyName, value, value, |
| SpatialRelation.INTERSECTS); |
| } |
| public static SpatialRelateExpression overlaps(String propertyName, Geometry value) { |
| return new SpatialRelateExpression(propertyName, value, value, |
| SpatialRelation.OVERLAPS); |
| } |
| public static SpatialRelateExpression touches(String propertyName, Geometry value) { |
| return new SpatialRelateExpression(propertyName, value, 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 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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/SpatialRelateExpression.java |
|---|
| New file |
| 0,0 → 1,134 |
| /** |
| * $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 testsuite-suite geometry |
| * |
| * @author Karel Maesen |
| */ |
| public class SpatialRelateExpression implements Criterion { |
| /** |
| * The geometry property |
| */ |
| private String propertyName = null; |
| /** |
| * The testsuite-suite geometry |
| */ |
| private Geometry value = null; |
| /** |
| * An optional (bounding box) filter geometry. |
| */ |
| private Geometry filter = null; |
| /** |
| * The spatial relation that is queried for. |
| */ |
| private int spatialRelation = -1; |
| private static final long serialVersionUID = 1L; |
| public SpatialRelateExpression(String propertyName, Geometry filter, |
| Geometry value, int spatialRelation) { |
| this.propertyName = propertyName; |
| this.spatialRelation = spatialRelation; |
| this.filter = filter; |
| 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 { |
| Dialect dialect = criteriaQuery.getFactory().getDialect(); |
| boolean twoPhaseFiltering = false; |
| if (dialect instanceof SpatialDialect) { |
| SpatialDialect sDialect = (SpatialDialect) dialect; |
| twoPhaseFiltering = sDialect.isTwoPhaseFiltering(); |
| } |
| if (filter != null && twoPhaseFiltering) |
| return new TypedValue[]{ |
| criteriaQuery.getTypedValue(criteria, propertyName, filter), |
| criteriaQuery.getTypedValue(criteria, propertyName, value)}; |
| else { |
| 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; |
| if (filter != null && seDialect.isTwoPhaseFiltering()) { |
| return seDialect.getSpatialRelateSQL(columns[0], |
| spatialRelation, true); |
| } else { |
| return seDialect.getSpatialRelateSQL(columns[0], |
| spatialRelation, false); |
| } |
| } else { |
| throw new IllegalStateException( |
| "Dialect must be spatially enabled dialect"); |
| } |
| } |
| } |
| Property changes: |
| Added: svn:keywords |
| + Id |
| /branches/jts_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/geom/MeasuredCoordinateArraySequence.java |
|---|
| New file |
| 0,0 → 1,183 |
| package org.hibernatespatial.jts.geom; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.CoordinateSequence; |
| import com.vividsolutions.jts.geom.Envelope; |
| import com.vividsolutions.jts.geom.impl.CoordinateArraySequence; |
| import java.util.Arrays; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 12, 2010 |
| */ |
| public class MeasuredCoordinateArraySequence implements MeasuredCoordinateSequence { |
| private final double[] measures; |
| private final CoordinateSequence coordinates; |
| public MeasuredCoordinateArraySequence(int size){ |
| this.coordinates = new CoordinateArraySequence(size); |
| this.measures = initMeasures(size); |
| } |
| public MeasuredCoordinateArraySequence(Coordinate[] coordinates) { |
| if (coordinates == null) |
| coordinates = new Coordinate[0]; |
| this.coordinates = new CoordinateArraySequence(coordinates); |
| this.measures = initMeasures(coordinates.length); |
| } |
| public MeasuredCoordinateArraySequence(CoordinateSequence coordinateSequence){ |
| this.coordinates = new CoordinateArraySequence(coordinateSequence); |
| if (coordinateSequence instanceof MeasuredCoordinateSequence){ |
| MeasuredCoordinateSequence sequence = (MeasuredCoordinateSequence) coordinateSequence; |
| this.measures = copyMeasures(sequence); |
| } else { |
| this.measures = initMeasures(this.coordinates.size()); |
| } |
| } |
| public MeasuredCoordinateArraySequence(CoordinateSequence coordinateSequence, double[] measures){ |
| this.coordinates = new CoordinateArraySequence(coordinateSequence); |
| if (measures == null) { |
| measures = initMeasures(0); |
| } |
| if (this.coordinates.size() != measures.length) { |
| throw new IllegalArgumentException("CoordinateSequence and measure-array must have the same length."); |
| } |
| this.measures = measures; |
| } |
| public MeasuredCoordinateArraySequence(MeasuredCoordinateSequence sequence){ |
| this.coordinates = new CoordinateArraySequence(sequence); |
| this.measures = copyMeasures(sequence); |
| } |
| public MeasuredCoordinateArraySequence(MeasuredCoordinate[] measuredCoordinates){ |
| this(measuredCoordinates == null ? 0 : measuredCoordinates.length); |
| for (int i = 0; i < this.coordinates.size(); i++) { |
| setMeasuredCoordinate(i, measuredCoordinates[i]); |
| } |
| } |
| private double[] copyMeasures(MeasuredCoordinateSequence sequence) { |
| if (sequence == null){ |
| return new double[0]; |
| } |
| double[] measures = sequence.toMeasureArray(); |
| double[] copied = new double[measures.length]; |
| System.arraycopy(measures, 0, copied, 0, measures.length); |
| return copied; |
| } |
| public MeasuredCoordinateArraySequence(Coordinate[] coordinates, double[] mvalues) { |
| this.coordinates = new CoordinateArraySequence(coordinates); |
| if (mvalues == null){ |
| mvalues = initMeasures(0); |
| } |
| if (this.coordinates.size() != mvalues.length) { |
| throw new IllegalArgumentException("Coordinate array and value array must be of the same length"); |
| } |
| this.measures = mvalues; |
| } |
| public int getDimension() { |
| return 4; |
| } |
| public Coordinate getCoordinate(int i) { |
| return this.coordinates.getCoordinate(i); |
| } |
| public Coordinate getCoordinateCopy(int i) { |
| return this.coordinates.getCoordinateCopy(i); |
| } |
| public void getCoordinate(int index, Coordinate coord) { |
| this.coordinates.getCoordinate(index, coord); |
| } |
| //Keep this?? |
| public void getMeasuredCoordinate(int index, MeasuredCoordinate measuredCoordinate) { |
| for (int i = 0; i < getDimension(); i++){ |
| measuredCoordinate.setOrdinate(i, this.getOrdinate(index, i)); |
| } |
| } |
| public double getX(int index) { |
| return this.coordinates.getX(index); |
| } |
| public double getY(int index) { |
| return this.coordinates.getY(index); |
| } |
| public double getZ(int index){ |
| return this.coordinates.getCoordinate(index).z; |
| } |
| public double getM(int index){ |
| return this.measures[index]; |
| } |
| public double getOrdinate(int index, int ordinateIndex) { |
| if (ordinateIndex == CoordinateSequence.M){ |
| return measures[index]; |
| } |
| return this.coordinates.getOrdinate(index, ordinateIndex); |
| } |
| public int size() { |
| return this.coordinates.size(); |
| } |
| public void setOrdinate(int index, int ordinateIndex, double value) { |
| if (ordinateIndex == CoordinateSequence.M){ |
| measures[index] = value; |
| return; |
| } |
| this.coordinates.setOrdinate(index,ordinateIndex, value); |
| } |
| public Coordinate[] toCoordinateArray() { |
| return this.coordinates.toCoordinateArray(); |
| } |
| public double[] toMeasureArray() { |
| return this.measures; |
| } |
| public Envelope expandEnvelope(Envelope env) { |
| return this.coordinates.expandEnvelope(env); |
| } |
| public void setMeasuredCoordinate(int index, MeasuredCoordinate coordinate) { |
| setOrdinate(index, CoordinateSequence.M, coordinate.getM()); |
| setOrdinate(index, CoordinateSequence.X, coordinate.getX()); |
| setOrdinate(index, CoordinateSequence.Y, coordinate.getY()); |
| setOrdinate(index, CoordinateSequence.Z, coordinate.getZ()); |
| } |
| public MeasuredCoordinate getMeasuredCoordinate(int index) { |
| return MeasuredCoordinate.from(this.coordinates.getCoordinate(index), this.measures[index]); |
| } |
| private double[] initMeasures(int size) { |
| double[] measures = new double[size]; |
| for (int i = 0; i < size; i++) { |
| measures[i] = Double.NaN; |
| } |
| return measures; |
| } |
| @Override |
| public Object clone() { |
| CoordinateSequence seq = (CoordinateSequence)this.coordinates.clone(); |
| if (measures == null){ |
| return new MeasuredCoordinateArraySequence(seq); |
| } |
| return new MeasuredCoordinateArraySequence(seq, Arrays.copyOf(measures, measures.length)); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/geom/MeasuredCoordinateSequence.java |
|---|
| New file |
| 0,0 → 1,22 |
| package org.hibernatespatial.jts.geom; |
| import com.vividsolutions.jts.geom.CoordinateSequence; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 24, 2010 |
| */ |
| public interface MeasuredCoordinateSequence extends CoordinateSequence { |
| public double getZ(int index); |
| public double getM(int index); |
| public void setMeasuredCoordinate(int index, MeasuredCoordinate coordinate); |
| public MeasuredCoordinate getMeasuredCoordinate(int index); |
| public void getMeasuredCoordinate(int index, MeasuredCoordinate measuredCoordinate); |
| public double[] toMeasureArray(); |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/geom/CoordinateDimension.java |
|---|
| New file |
| 0,0 → 1,43 |
| package org.hibernatespatial.jts.geom; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 12, 2010 |
| */ |
| //TODO -- move to top-level |
| public enum CoordinateDimension { |
| XY (false, false), |
| XYZ (true, false), |
| XYM (false, true), |
| XYZM(true, true); |
| private final boolean hasZ; |
| private final boolean hasM; |
| private CoordinateDimension(boolean hasZ, boolean hasM){ |
| this.hasZ = hasZ; |
| this.hasM = hasM; |
| } |
| public boolean hasZ(){ |
| return hasZ; |
| } |
| public boolean hasM(){ |
| return hasM; |
| } |
| public int getNumDimensions(){ |
| if (hasM() && hasZ()) return 4; |
| if (hasZ() || hasM()) return 3; |
| return 2; |
| } |
| public static CoordinateDimension valueFor(boolean hasZ, boolean hasM){ |
| for(CoordinateDimension dim : values()){ |
| if (dim.hasZ == hasZ && dim.hasM == hasM) return dim; |
| } |
| throw new IllegalStateException("Non-existent CoordinateDimension"); //this is never thrown. |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/geom/MeasuredCoordinate.java |
|---|
| New file |
| 0,0 → 1,206 |
| package org.hibernatespatial.jts.geom; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.CoordinateSequence; |
| /** |
| * A wrapper for <code>Coordinate</code>s that associates it with a measure value. |
| * |
| * @author Karel Maesen, Geovise BVBA |
| * |
| */ |
| public class MeasuredCoordinate { |
| private double m = Coordinate.NULL_ORDINATE; |
| private Coordinate coordinate; |
| public MeasuredCoordinate(Coordinate c, double m) { |
| this.coordinate = c; |
| this.m = m; |
| } |
| public MeasuredCoordinate() { |
| this.coordinate = new Coordinate(); |
| this.m = Double.NaN; |
| } |
| public Coordinate getCoordinate(){ |
| return this.coordinate; |
| } |
| public double getX() { |
| return this.coordinate.x; |
| } |
| public double getY() { |
| return this.coordinate.y; |
| } |
| public double getZ() { |
| return this.coordinate.z; |
| } |
| public double getM() { |
| return m; |
| } |
| /** |
| * 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.coordinate.x; |
| case CoordinateSequence.Y: |
| return this.coordinate.y; |
| case CoordinateSequence.Z: |
| return this.coordinate.z; |
| case CoordinateSequence.M: |
| return this.m; |
| } |
| return Double.NaN; |
| } |
| /** |
| * 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.coordinate.x = value; |
| break; |
| case CoordinateSequence.Y: |
| this.coordinate.y = value; |
| break; |
| case CoordinateSequence.Z: |
| this.coordinate.z = value; |
| break; |
| case CoordinateSequence.M: |
| this.m = value; |
| break; |
| default: |
| throw new IllegalArgumentException("invalid ordinateIndex"); |
| } |
| } |
| public boolean equals2DWithMeasure(MeasuredCoordinate other) { |
| return this.coordinate.equals2D(other.coordinate) && (Double.compare(this.m, other.m) == 0) ; |
| } |
| public boolean equals3DWithMeasure(MeasuredCoordinate other) { |
| return this.coordinate.equals3D(other.coordinate) && |
| (Double.compare(this.m, other.m) == 0); |
| } |
| public String toString() { |
| return "(" + this.coordinate.x + "," + this.coordinate.y + "," + this.coordinate.z + "," + " m=" + this.m + ")"; |
| } |
| public static MeasuredCoordinate from(Coordinate c) { |
| return new MeasuredCoordinate(c, Double.NaN); |
| } |
| public static MeasuredCoordinate from(Coordinate c, double m){ |
| return new MeasuredCoordinate(c, m); |
| } |
| /** |
| * A convenience method for creating a MeasuredCoordinate 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 MeasuredCoordinate to2DM(double x, double y, double m) { |
| Coordinate c = new Coordinate(x,y); |
| return new MeasuredCoordinate(c, 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 MeasuredCoordinate to2D(double x, double y) { |
| Coordinate c = new Coordinate(x,y); |
| return new MeasuredCoordinate(c, 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 MeasuredCoordinate to3DM(double x, double y, double z, |
| double m) { |
| Coordinate c = new Coordinate(x, y, z); |
| return new MeasuredCoordinate(c, 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 MeasuredCoordinate to3D(double x, double y, double z) { |
| Coordinate c = new Coordinate(x,y,z); |
| return new MeasuredCoordinate(c, Double.NaN); |
| } |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) return true; |
| if (o == null || getClass() != o.getClass()) return false; |
| MeasuredCoordinate that = (MeasuredCoordinate) o; |
| if (Double.compare(that.m, m) != 0) return false; |
| if (coordinate != null ? !coordinate.equals(that.coordinate) : that.coordinate != null) return false; |
| return true; |
| } |
| @Override |
| public int hashCode() { |
| int result; |
| long temp; |
| temp = m != +0.0d ? Double.doubleToLongBits(m) : 0L; |
| result = (int) (temp ^ (temp >>> 32)); |
| result = 31 * result + (coordinate != null ? coordinate.hashCode() : 0); |
| return result; |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/geom/MeasuredCoordinateSequenceFactory.java |
|---|
| New file |
| 0,0 → 1,33 |
| package org.hibernatespatial.jts.geom; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.CoordinateSequence; |
| import com.vividsolutions.jts.geom.CoordinateSequenceFactory; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 22, 2010 |
| */ |
| public class MeasuredCoordinateSequenceFactory implements CoordinateSequenceFactory { |
| public MeasuredCoordinateSequence create(Coordinate[] coordinates) { |
| return new MeasuredCoordinateArraySequence(coordinates); |
| } |
| public MeasuredCoordinateSequence create(CoordinateSequence coordSeq) { |
| return new MeasuredCoordinateArraySequence(coordSeq); |
| } |
| public MeasuredCoordinateSequence create(int size, int dimension) { |
| return new MeasuredCoordinateArraySequence(size); |
| } |
| public MeasuredCoordinateSequence create(Coordinate[] coordinates, double[] measures){ |
| return new MeasuredCoordinateArraySequence(coordinates, measures); |
| } |
| public MeasuredCoordinateSequence create(MeasuredCoordinate[] measuredCoordinates){ |
| return new MeasuredCoordinateArraySequence(measuredCoordinates); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/linearref/MeasuredLineSegment.java |
|---|
| New file |
| 0,0 → 1,146 |
| package org.hibernatespatial.jts.linearref; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.LineSegment; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinate; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Dec 1, 2010 |
| */ |
| public class MeasuredLineSegment { |
| private final LineSegment segment; |
| private final MeasuredCoordinate start; |
| private final MeasuredCoordinate end; |
| MeasuredLineSegment(MeasuredCoordinate start, MeasuredCoordinate end) { |
| this.start = start; |
| this.end = end; |
| this.segment = new LineSegment(start.getCoordinate(), end.getCoordinate()); |
| } |
| public double getStartM() { |
| return start.getM(); |
| } |
| public double getEndM() { |
| return end.getM(); |
| } |
| public double measureAlong(double factor) { |
| return getStartM() + factor * (getEndM() - getStartM()); |
| } |
| public double segmentFraction(double measure) { |
| double fraction = (measure - getStartM()) / (getEndM() - getStartM()); |
| if (fraction < 0d) return 0d; |
| if (fraction > 1d) return 1d; |
| if (Double.isNaN(fraction)) return 1d; //ensures that if measure=startM and endM == startM, the end measure is selected |
| return fraction; |
| } |
| public MeasuredCoordinate getMeasuredCoordinate(double measure) { |
| double fraction = this.segmentFraction(measure); |
| return measuredPointAlong(fraction); |
| } |
| public MeasuredCoordinate measuredPointAlong(double fraction) { |
| Coordinate co = this.pointAlong(fraction); |
| double measure = this.measureAlong(fraction); |
| return new MeasuredCoordinate(co, measure); |
| } |
| public boolean measureInSegment(double measure) { |
| return (getStartM() <= measure && measure <= getEndM()) || |
| getStartM() >= measure && measure >= getEndM(); |
| } |
| //Delegated methods. |
| public Coordinate intersection(LineSegment line) { |
| return segment.intersection(line); |
| } |
| public double getLength() { |
| return segment.getLength(); |
| } |
| public boolean isHorizontal() { |
| return segment.isHorizontal(); |
| } |
| public boolean isVertical() { |
| return segment.isVertical(); |
| } |
| public int orientationIndex(LineSegment seg) { |
| return segment.orientationIndex(seg); |
| } |
| public int orientationIndex(Coordinate p) { |
| return segment.orientationIndex(p); |
| } |
| public void reverse() { |
| segment.reverse(); |
| } |
| public void normalize() { |
| segment.normalize(); |
| } |
| public double angle() { |
| return segment.angle(); |
| } |
| public Coordinate midPoint() { |
| return segment.midPoint(); |
| } |
| public double distance(LineSegment ls) { |
| return segment.distance(ls); |
| } |
| public double distance(Coordinate p) { |
| return segment.distance(p); |
| } |
| public double distancePerpendicular(Coordinate p) { |
| return segment.distancePerpendicular(p); |
| } |
| public Coordinate pointAlong(double segmentLengthFraction) { |
| return segment.pointAlong(segmentLengthFraction); |
| } |
| public Coordinate pointAlongOffset(double segmentLengthFraction, double offsetDistance) { |
| return segment.pointAlongOffset(segmentLengthFraction, offsetDistance); |
| } |
| public double projectionFactor(Coordinate p) { |
| return segment.projectionFactor(p); |
| } |
| public double segmentFraction(Coordinate inputPt) { |
| return segment.segmentFraction(inputPt); |
| } |
| public Coordinate project(Coordinate p) { |
| return segment.project(p); |
| } |
| public LineSegment project(LineSegment seg) { |
| return segment.project(seg); |
| } |
| public Coordinate closestPoint(Coordinate p) { |
| return segment.closestPoint(p); |
| } |
| public Coordinate[] closestPoints(LineSegment line) { |
| return segment.closestPoints(line); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/linearref/MeasuredGeometry.java |
|---|
| New file |
| 0,0 → 1,46 |
| package org.hibernatespatial.jts.linearref; |
| import com.vividsolutions.jts.geom.Coordinate; |
| import com.vividsolutions.jts.geom.CoordinateSequence; |
| import com.vividsolutions.jts.geom.Geometry; |
| import com.vividsolutions.jts.geom.LineString; |
| import org.hibernatespatial.jts.geom.CoordinateDimension; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinate; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequence; |
| import java.lang.reflect.Method; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 29, 2010 |
| */ |
| public interface MeasuredGeometry { |
| public Geometry locateAlong(double measure); |
| public Geometry locateBetween(); |
| public double getMeasureAtCoordinate(Coordinate c, double tolerance); |
| /** |
| * Returns the <code>MeasuredCoordinate</code> at the specified measure. |
| * |
| * <p>In case of lineal <code>MeasuredGeometry</code>s, the coordinate is determined by interpolation on the linesegments |
| * of the curve, or (a curve in case of multi-curve geometries). |
| * </p> |
| * <p>When the measures are non-monotonic, the first interpolated coordinate will be returned.</p> |
| * @param measure |
| * @return |
| */ |
| public MeasuredCoordinate getCoordinateAtMeasure(double measure); |
| MeasuredCoordinateSequence[] getCoordinatesBetween(double begin, double end); |
| public double getMinMeasure(); |
| public double getMaxMeasure(); |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/linearref/MeasuredLineString.java |
|---|
| New file |
| 0,0 → 1,187 |
| package org.hibernatespatial.jts.linearref; |
| import com.vividsolutions.jts.geom.*; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinate; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateArraySequence; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequence; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequenceFactory; |
| import java.util.ArrayList; |
| import java.util.List; |
| /** |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Nov 29, 2010 |
| */ |
| public class MeasuredLineString implements MeasuredGeometry { |
| private final MeasuredCoordinateSequence coordinates; |
| private final GeometryFactory geometryFactory; |
| private final MeasuredCoordinateSequenceFactory coordinateSequenceFactory; |
| public MeasuredLineString(LineString lineString) { |
| if (lineString == null) { |
| throw new IllegalArgumentException("Non-null LineString required."); |
| } |
| this.geometryFactory = lineString.getFactory(); |
| if (geometryFactory.getCoordinateSequenceFactory() instanceof MeasuredCoordinateSequenceFactory){ |
| this.coordinateSequenceFactory = (MeasuredCoordinateSequenceFactory) geometryFactory.getCoordinateSequenceFactory(); |
| } else { |
| this.coordinateSequenceFactory = new MeasuredCoordinateSequenceFactory(); |
| } |
| CoordinateSequence sequence = lineString.getCoordinateSequence(); |
| if (!(sequence instanceof MeasuredCoordinateSequence)) { |
| coordinates = new MeasuredCoordinateArraySequence(sequence); |
| return; |
| } |
| this.coordinates = (MeasuredCoordinateSequence) sequence; |
| } |
| public Geometry locateAlong(double measure) { |
| MeasuredCoordinate measuredCoordinate = getCoordinateAtMeasure(measure); |
| MeasuredCoordinate[] mca = null; |
| if (measuredCoordinate != null) |
| mca = new MeasuredCoordinate[]{measuredCoordinate}; |
| MeasuredCoordinateSequence seq = this.coordinateSequenceFactory.create(mca); |
| return geometryFactory.createPoint(seq); |
| } |
| public Geometry locateBetween() { |
| return null; //To change body of implemented methods use File | Settings | File Templates. |
| } |
| public double getMeasureAtCoordinate(Coordinate c, double tolerance) { |
| MeasuredCoordinate measuredCoordinate = getClosestCoordinateAt(c, tolerance); |
| if (measuredCoordinate == null) |
| return Double.NaN; |
| return measuredCoordinate.getM(); |
| } |
| public MeasuredCoordinate getCoordinateAtMeasure(double measure) { |
| for (MeasuredLineSegment segment : new MeasuredLineSegments(this.coordinates)) { |
| if (segment.measureInSegment(measure)) { |
| return segment.getMeasuredCoordinate(measure); |
| } |
| } |
| return null; |
| } |
| public MeasuredCoordinateSequence[] getCoordinatesBetween(double begin, double end) { |
| if (begin == end) |
| return new MeasuredCoordinateSequence[]{new MeasuredCoordinateArraySequence(0)}; |
| List<MeasuredCoordinate> coordinates = new ArrayList<MeasuredCoordinate>(); |
| boolean segmentStartVertexAdded = false; |
| double previousSegmentDirection = 0; //measure direction (increasing/decreasing) of previous segment |
| for (MeasuredLineSegment segment : new MeasuredLineSegments(this.coordinates)) { |
| previousSegmentDirection = getMeasureDirectionAndCompare(previousSegmentDirection, segment); |
| //Stop iterating if the begin/end measures are smaller(larger) than the segment's measures if increasing (decreasing) |
| if (stopIterating(begin, end, previousSegmentDirection, segment)) |
| break; |
| double beginFraction = segment.segmentFraction(begin); |
| double endFraction = segment.segmentFraction(end); |
| if (beginFraction == endFraction) { //begin & end both to the left or right of current segment |
| continue; |
| } |
| addCoordinates(coordinates, segmentStartVertexAdded, segment, beginFraction, endFraction); |
| //start vertex of next segment already added? |
| segmentStartVertexAdded = (beginFraction == 1.0d || endFraction == 1.0d); |
| } |
| return new MeasuredCoordinateSequence[]{new MeasuredCoordinateArraySequence(coordinates.toArray(new MeasuredCoordinate[]{}))}; |
| } |
| private boolean stopIterating(double begin, double end, double previousSegmentDirection, MeasuredLineSegment segment) { |
| return (previousSegmentDirection > 0 && begin < segment.getStartM() && end < segment.getStartM()) || |
| (previousSegmentDirection < 0 && begin > segment.getStartM() && end > segment.getStartM()); |
| } |
| private double getMeasureDirectionAndCompare(double previousSegmentDirection, MeasuredLineSegment segment) { |
| double segmentDirection = getSegmentDirection(segment); |
| if (!segmentDirectionSameAsPreviousSegment(previousSegmentDirection, segmentDirection)) |
| throw new IllegalStateException("Measures needs to be monotonic increasing/decreasing for this method."); |
| if (segmentDirection != 0.0d) return segmentDirection; |
| return previousSegmentDirection; |
| } |
| private boolean segmentDirectionSameAsPreviousSegment(double previousSegmentDirection, double segmentDirection) { |
| return segmentDirection == 0 || previousSegmentDirection == 0 || segmentDirection == previousSegmentDirection; |
| } |
| /** |
| * Returns the segment direction: -1 when decreasing, +1 when increasing or 0 when constant. |
| */ |
| private double getSegmentDirection(MeasuredLineSegment segment) { |
| return Math.signum(segment.getEndM() - segment.getStartM()); |
| } |
| private void addCoordinates(List<MeasuredCoordinate> coordinates, boolean startVertexIncluded, MeasuredLineSegment segment, double beginFraction, double endFraction) { |
| if (beginFraction < endFraction) { |
| addCoordinate(coordinates, startVertexIncluded, segment, beginFraction); |
| addCoordinate(coordinates, startVertexIncluded, segment, endFraction); |
| } else { |
| addCoordinate(coordinates, startVertexIncluded, segment, endFraction); |
| addCoordinate(coordinates, startVertexIncluded, segment, beginFraction); |
| } |
| } |
| /** |
| * Add coordinate. If it is the start-vertex of the segment, only add if it has not already been added (indicated by startVertexIncluded). |
| */ |
| private void addCoordinate(List<MeasuredCoordinate> coordinates, boolean startVertexIncluded, MeasuredLineSegment segment, double fraction) { |
| if (!startVertexIncluded || fraction != 0.0d) |
| coordinates.add(segment.measuredPointAlong(fraction)); |
| } |
| public double getMinMeasure() { |
| double minX = Double.POSITIVE_INFINITY; |
| boolean hasMeasures = false; |
| for (int i = 0; i < this.coordinates.size(); i++) { |
| double m = this.coordinates.getOrdinate(i, CoordinateSequence.M); |
| if (Double.isNaN(m)) { |
| continue; |
| } |
| hasMeasures = true; |
| minX = Math.min(minX, m); |
| } |
| return hasMeasures ? minX : Double.NaN; |
| } |
| public double getMaxMeasure() { |
| double minX = Double.NEGATIVE_INFINITY; |
| boolean hasMeasures = false; |
| for (int i = 0; i < this.coordinates.size(); i++) { |
| double m = this.coordinates.getOrdinate(i, CoordinateSequence.M); |
| if (Double.isNaN(m)) { |
| continue; |
| } |
| hasMeasures = true; |
| minX = Math.max(minX, m); |
| } |
| return hasMeasures ? minX : Double.NaN; |
| } |
| protected MeasuredCoordinate getClosestCoordinateAt(Coordinate c, double tolerance) { |
| Coordinate currentClosest = null; |
| double currentMeasure = Double.NaN; |
| double currentMinimum = Double.POSITIVE_INFINITY; |
| for (MeasuredLineSegment segment : new MeasuredLineSegments(this.coordinates)) { |
| Coordinate closest = segment.closestPoint(c); |
| double distance = closest.distance(c); |
| if (distance < currentMinimum) { |
| currentMinimum = distance; |
| currentClosest = closest; |
| double factor = segment.projectionFactor(closest); |
| currentMeasure = segment.measureAlong(factor); |
| } |
| } |
| if (currentMinimum > tolerance || currentClosest == null) { |
| return null; |
| } |
| return new MeasuredCoordinate(currentClosest, currentMeasure); |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/jts/linearref/LineSegments.java |
|---|
| New file |
| 0,0 → 1,61 |
| package org.hibernatespatial.jts.linearref; |
| import com.vividsolutions.jts.geom.LineSegment; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinate; |
| import org.hibernatespatial.jts.geom.MeasuredCoordinateSequence; |
| import java.util.Iterator; |
| /** |
| * Allows fast iteration over the <code>LineSegment</code>s of a LineString. |
| * |
| * The <code>LineSegment</code> instance returned by the <code>Iterator</code> is re-used |
| * on each iteration. |
| * |
| * @author Karel Maesen, Geovise BVBA |
| * creation-date: Dec 1, 2010 |
| */ |
| class MeasuredLineSegments implements Iterable<MeasuredLineSegment> { |
| private final MeasuredCoordinateSequence coordinates; |
| MeasuredLineSegments(MeasuredCoordinateSequence coordinates) { |
| this.coordinates = coordinates; |
| if (this.coordinates == null || this.coordinates.size() < 2) |
| throw new IllegalArgumentException("Coordinate sequence needs to be at least of length 2."); |
| } |
| public MeasuredLineSegmentIterator iterator() { |
| return new MeasuredLineSegmentIterator(coordinates); |
| } |
| private static class MeasuredLineSegmentIterator implements Iterator<MeasuredLineSegment> { |
| private final MeasuredCoordinateSequence coordinates; |
| private final MeasuredLineSegment currentSegment; |
| private final MeasuredCoordinate p0 = new MeasuredCoordinate(); |
| private final MeasuredCoordinate p1 = new MeasuredCoordinate(); |
| private int index = 0; |
| public MeasuredLineSegmentIterator(MeasuredCoordinateSequence coordinates) { |
| this.currentSegment = new MeasuredLineSegment(p0, p1); |
| this.coordinates = coordinates; |
| } |
| public boolean hasNext() { |
| return (index < coordinates.size() - 1 ); |
| } |
| public MeasuredLineSegment next() { |
| this.coordinates.getMeasuredCoordinate(this.index++, p0); |
| this.coordinates.getMeasuredCoordinate(this.index, p1); |
| return this.currentSegment; |
| } |
| public void remove() { |
| throw new UnsupportedOperationException("Remove operation not supported."); |
| } |
| } |
| } |
| /branches/jts_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialDialect.java |
|---|
| New file |
| 0,0 → 1,114 |
| /* |
| * $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; |
| /** |
| * Describes the features of a spatially enabled dialect. |
| * |
| * @author Karel Maesen |
| */ |
| public interface SpatialDialect { |
| /** |
| * Returns the SQL fragment for the SQL WHERE-clause when parsing |
| * <code>org.hibernatespatial.criterion.SpatialRelateExpression</code>s |
| * into prepared statements. |
| * <p/> |
| * If useFilter is specified, then a two-stage spatial query model is |
| * assumed (first stage using only spatial index; second stage performing |
| * exact comparisons between geometries). The returned SQL-fragement in that |
| * case should contains two input parameters. The first for setting the |
| * filter geometry, the second for the testsuite-suite geometry. |
| * |
| * @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>org.walkonweb.spatial.SpatialRelation</code>). |
| * @param useFilter If true, the SpatialRelateExpression uses two-stage query |
| * model |
| * @return - SQL fragment for use in the SQL WHERE-clause. |
| */ |
| public String getSpatialRelateSQL(String columnName, int spatialRelation, |
| boolean useFilter); |
| /** |
| * 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 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/> |
| * Postgis (up to version ??) supports explicit filtering. Oracle and MySQL |
| * don't. |
| * |
| * @return * |
| */ |
| @Deprecated |
| public boolean isTwoPhaseFiltering(); |
| /** |
| * 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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometryFactory.java |
|---|
| New file |
| 0,0 → 1,106 |
| /** |
| * $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 org.hibernatespatial.mgeom.MCoordinate; |
| /** |
| * Extension of the GeometryFactory for constructing Geometries with Measure |
| * support. |
| * |
| * @see com.vividsolutions.jts.geom.GeometryFactory |
| */ |
| @Deprecated |
| 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_measured_geometry/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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinate.java |
|---|
| New file |
| 0,0 → 1,274 |
| /** |
| * $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 |
| */ |
| @Deprecated |
| 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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/EventLocator.java |
|---|
| New file |
| 0,0 → 1,80 |
| /* |
| * $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; |
| @Deprecated |
| 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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinateSequenceFactory.java |
|---|
| New file |
| 0,0 → 1,88 |
| /** |
| * $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; |
| import org.hibernatespatial.mgeom.MCoordinate; |
| /** |
| * Creates MeasuredCoordinateSequenceFactory internally represented as an array of |
| * {@link MCoordinate}s. |
| */ |
| @Deprecated |
| 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 MeasuredCoordinateSequenceFactory |
| */ |
| 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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MultiMLineString.java |
|---|
| New file |
| 0,0 → 1,281 |
| /* |
| * $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.*; |
| import org.hibernatespatial.mgeom.MCoordinate; |
| @Deprecated |
| 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 getMeasureatCoordinate |
| 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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometryException.java |
|---|
| New file |
| 0,0 → 1,72 |
| /** |
| * $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 |
| * |
| * |
| */ |
| @Deprecated |
| 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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometry.java |
|---|
| New file |
| 0,0 → 1,188 |
| /** |
| * $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 |
| */ |
| @Deprecated |
| 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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MLineString.java |
|---|
| New file |
| 0,0 → 1,687 |
| /** |
| * $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 org.hibernatespatial.mgeom.MCoordinate; |
| import java.util.*; |
| /** |
| * 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 |
| */ |
| @Deprecated |
| 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#getMeasureatCoordinate(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. |
| * |
| * 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. |
| * |
| * 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) { |
| //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_measured_geometry/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinateSequence.java |
|---|
| New file |
| 0,0 → 1,233 |
| /** |
| * $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. |
| */ |
| @Deprecated |
| 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_measured_geometry/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 |