Subversion Repositories hibernate-spatial

Compare Revisions

Ignore whitespace Rev 241 → Rev 242

/branches/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/GeomEntity.hbm.xml
New file
0,0 → 1,42
<?xml version="1.0"?>
<!--
~ $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/
-->
 
<!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="int">
<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>
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/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 (!(c1 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/hibernate-3.6-integration/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 test 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/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/DataSourceUtils.java
New file
0,0 → 1,302
/*
* $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.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
 
/**
* <p>Unit test 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 String propertyFile;
private final SQLExpressionTemplate sqlExpressionTemplate;
 
private TestData testData;
private Properties properties;
private DataSource dataSource;
private static final String TEST_DATA_SET = "dataset";
 
/**
* 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 propertyFile properties file for the database properties
* @param sqlExpressionTemplate SQLExpressionTemplate object that generates SQL statements for this database
*/
public DataSourceUtils(String propertyFile, SQLExpressionTemplate sqlExpressionTemplate) {
this.propertyFile = propertyFile;
this.sqlExpressionTemplate = sqlExpressionTemplate;
readProperties();
createBasicDataSource();
loadTestObjects();
}
 
private void readProperties() {
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 = new Properties();
properties.load(is);
} catch (IOException e) {
throw (new RuntimeException(e));
} finally {
if (is != null) try {
is.close();
} catch (IOException e) {
//nothing to do
}
}
}
 
private void createBasicDataSource() {
String url = properties.getProperty("jdbcUrl");
String user = properties.getProperty("dbUsername");
String pwd = properties.getProperty("dbPassword");
String driverName = properties.getProperty("driver");
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName(driverName);
bds.setUrl(url);
bds.setUsername(user);
bds.setPassword(pwd);
dataSource = bds;
}
 
/**
* loads the test objects
* <p/>
*/
private void loadTestObjects() {
testData = TestData.fromFile(properties.getProperty(TEST_DATA_SET));
}
 
/**
* Return the test data set
*/
public TestData getTestData() {
return this.testData;
}
 
/**
* 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 createConnection() throws SQLException {
Connection cn = getDataSource().getConnection();
cn.setAutoCommit(false);
return cn;
}
 
/**
* Delete all test 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
}
}
}
 
/**
* Insert all test data in the database
*
* @throws SQLException
*/
public void insertTestData() throws SQLException {
insertTestData(testData);
}
 
public void insertTestData(TestData testData) throws SQLException {
deleteTestData();
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
}
}
}
 
/**
* 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.
}
}
 
/**
* Return the geometries of the test 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 test object's geometry.
* <p/>
* <p>This method reads the WKT of the test 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) {
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/hibernate-3.6-integration/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/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/cfg/HSConfigurationTest.java
New file
0,0 → 1,58
package org.hibernatespatial.test.cfg;
 
import org.hibernate.cfg.Configuration;
import org.hibernatespatial.HBSpatialExtension;
import org.hibernatespatial.cfg.HSConfiguration;
import org.junit.Test;
 
import java.io.File;
 
import static org.junit.Assert.assertEquals;
 
public class HSConfigurationTest {
 
private static final String hibernate_config_location = "/Users/maesenka/workspaces/hibernate-spatial/hibernate-spatial-mysql/src/test/java/hibernate.cfg.xml";
 
private static final String hs_config_location = "/Users/maesenka/workspaces/hibernate-spatial/hibernate-spatial/src/test/java/hibernate-spatial.cfg.xml";
 
@Test
public void testConfigure() {
HSConfiguration config = new HSConfiguration();
Configuration hibConfig = new Configuration();
hibConfig.configure(new File(hibernate_config_location));
config.configure(hibConfig);
assertEquals("org.hibernatespatial.mysql.MySQLSpatialDialect", config
.getDefaultDialect());
 
config.configure();
testResults(config);
 
}
 
@Test
public void testConfigureFile() {
HSConfiguration config = new HSConfiguration();
config.configure(new File(hs_config_location));
testResults(config);
}
 
@Test
public void testConfigureFailure() {
HSConfiguration config = new HSConfiguration();
config.configure("non-existing-file");
}
 
@Test
public void testHBSpatExtConfigure() {
HSConfiguration config = new HSConfiguration();
config.configure();
HBSpatialExtension.setConfiguration(config);
}
 
private void testResults(HSConfiguration config) {
assertEquals("org.hibernatespatial.postgis.PostgisDialect", config
.getDefaultDialect());
assertEquals("FIXED", config.getPrecisionModel());
assertEquals("5", config.getPrecisionModelScale());
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/AbstractExpectationsFactory.java
New file
0,0 → 1,698
/*
* $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 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
* @see TestSpatialFunctions
*/
public abstract class AbstractExpectationsFactory {
 
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(String propertiesFile, SQLExpressionTemplate sqlExpressionTemplate) {
this.dataSourceUtils = new DataSourceUtils(propertiesFile, sqlExpressionTemplate);
 
}
 
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 test 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 test 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 test 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 test 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 test geometries
*
* @return map of identifier, SRID
* @throws SQLException
*/
public Map<Integer, Integer> getSrid() throws SQLException {
return retrieveExpected(createNativeSridStatement(), INTEGER);
}
 
/**
* Returns whether the test geometries are simple
*
* @return map of identifier and whether test geometry is simple
* @throws SQLException
*/
public Map<Integer, Boolean> getIsSimple() throws SQLException {
return retrieveExpected(createNativeIsSimpleStatement(), BOOLEAN);
}
 
/**
* Returns whether the test geometries are empty
*
* @return map of identifier and whether test geometry is empty
* @throws SQLException
*/
public Map<Integer, Boolean> getIsEmpty() throws SQLException {
return retrieveExpected(createNativeIsEmptyStatement(), BOOLEAN);
}
 
/**
* Returns the expected boundaries of all test 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 test 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 test 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 test 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.createConnection();
}
 
/**
* 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 test polygon (filter, ...)
*
* @return a test 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);
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/hibernate-3.6-integration/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 test 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/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/TestMLineStringGetCoordinatesBetween.java
New file
0,0 → 1,512
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.PrecisionModel;
import org.hibernatespatial.mgeom.*;
import org.junit.Before;
import org.junit.Test;
 
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;
 
public class TestMLineStringGetCoordinatesBetween {
MLineString incrLine;
MLineString decLine;
MLineString emptyLine;
MLineString nonMonotoneLine;
MLineString partiallyConstantIncreasing;
MLineString partiallyConstantDecreasing;
 
 
private PrecisionModel prec = new PrecisionModel(PrecisionModel.FIXED);
 
private MGeometryFactory mgeomFactory = new MGeometryFactory(
MCoordinateSequenceFactory.instance());
 
@Before
public void setUp() {
 
MCoordinate[] coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0)
};
incrLine = mgeomFactory.createMLineString(coordinates);
 
coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0)
};
decLine = mgeomFactory.createMLineString(coordinates);
 
coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(0.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 5.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 1.5)
};
nonMonotoneLine = mgeomFactory.createMLineString(coordinates);
 
coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0)
};
partiallyConstantIncreasing = mgeomFactory.createMLineString(coordinates);
 
coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0)
};
partiallyConstantDecreasing = mgeomFactory.createMLineString(coordinates);
 
 
}
 
@Test
public void test_measure_inside_monotone_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = incrLine.getCoordinatesBetween(0.5, 3.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(1.0, 3.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0), crds[2]);
 
result = incrLine.getCoordinatesBetween(0.0, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[4]);
 
result = incrLine.getCoordinatesBetween(0.5, 1.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(3.5, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.5), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(3.5, 3.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.7, 0.0, 3.7), crds[1]);
 
result = incrLine.getCoordinatesBetween(0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[1]);
 
result = incrLine.getCoordinatesBetween(-0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[1]);
 
result = incrLine.getCoordinatesBetween(3.5, 4.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[1]);
}
 
 
@Test
public void test_measure_inside_partially_constant_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = partiallyConstantIncreasing.getCoordinatesBetween(0.5, 2.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 2.5), crds[crds.length - 1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(1.0, 3.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0), crds[3]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(0.0, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(6, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[5]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(0.5, 1.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[crds.length - 1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(1.5, 2.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 2.5), crds[crds.length - 1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(3.5, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[crds.length - 1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(3.5, 3.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.7, 0.0, 3.7), crds[1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(-0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[1]);
 
result = partiallyConstantIncreasing.getCoordinatesBetween(3.5, 4.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[1]);
}
 
@Test
public void test_measures_monotone_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = decLine.getCoordinatesBetween(0.5, 3.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(1.0, 3.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[2]);
 
result = decLine.getCoordinatesBetween(0.0, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[4]);
 
result = decLine.getCoordinatesBetween(0.5, 1.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(3.5, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(3.5, 3.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.7, 0.0, 3.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[1]);
 
result = decLine.getCoordinatesBetween(0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[1]);
 
result = decLine.getCoordinatesBetween(-0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[1]);
 
result = decLine.getCoordinatesBetween(3.5, 4.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
}
 
 
@Test
public void test_measures_partially_constant_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = partiallyConstantDecreasing.getCoordinatesBetween(0.5, 3.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(6, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(1.0, 3.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[2]);
assertEquals(MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0), crds[3]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(0.0, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(6, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 3.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[5]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(0.5, 1.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(3, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(1.5, 2.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 2.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 2.0), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0), crds[2]);
assertEquals(MCoordinate.create2dWithMeasure(1.5, 0.0, 1.5), crds[3]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(3.5, 4.0);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[crds.length - 1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(3.5, 3.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.7, 0.0, 3.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(-0.5, 0.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.7, 0.0, 0.7), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[1]);
 
result = partiallyConstantDecreasing.getCoordinatesBetween(3.5, 4.7);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(2, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.5, 0.0, 3.5), crds[1]);
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 4.0), crds[0]);
}
 
@Test
public void test_measure_outside_monotone_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = incrLine.getCoordinatesBetween(-1.5, -0.5);
assertEquals(1, result.length);
assertEquals(0, result[0].size());
 
result = incrLine.getCoordinatesBetween(10.0, 20.0);
assertEquals(1, result.length);
assertEquals(0, result[0].size());
}
 
@Test
public void test_measure_outside_monotone_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = decLine.getCoordinatesBetween(-1.5, -0.5);
assertEquals(1, result.length);
assertEquals(0, result[0].size());
 
result = decLine.getCoordinatesBetween(10.0, 20.0);
assertEquals(1, result.length);
assertEquals(0, result[0].size());
}
 
@Test
public void test_measure_overlap_monotone_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = incrLine.getCoordinatesBetween(-0.5, 5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(0.5, 5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(-1.0, 2.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(2.5, 0.0, 2.5), crds[crds.length - 1]);
 
result = incrLine.getCoordinatesBetween(4.0, 5.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(1, crds.length);
 
}
 
@Test
public void test_measure_overlap_monotone_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = decLine.getCoordinatesBetween(-0.5, 5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(0.5, 5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
 
result = decLine.getCoordinatesBetween(-1.0, 2.5);
assertEquals(1, result.length);
crds = result[0].toCoordinateArray();
assertEquals(4, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(2.5, 0.0, 2.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0), crds[crds.length - 1]);
}
 
@Test
public void test_measure_inverse_monotone_increasing() throws MGeometryException {
CoordinateSequence[] result;
result = incrLine.getCoordinatesBetween(3.5, 0.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[crds.length - 1]);
}
 
@Test
public void test_measure_inverse_monotone_decreasing() throws MGeometryException {
CoordinateSequence[] result;
result = decLine.getCoordinatesBetween(3.5, 0.5);
assertEquals(1, result.length);
Coordinate[] crds = result[0].toCoordinateArray();
assertEquals(5, crds.length);
assertEquals(MCoordinate.create2dWithMeasure(3.5, 0.0, 3.5), crds[0]);
assertEquals(MCoordinate.create2dWithMeasure(0.5, 0.0, 0.5), crds[crds.length - 1]);
}
 
@Test
public void test_fail_on_non_monotone() throws MGeometryException {
try {
nonMonotoneLine.getCoordinatesBetween(0.5, 10.0);
fail("Needs to throw an IllegalArgumentException on non-monotone linestrings.");
} catch (MGeometryException e) {
assertEquals(e.getType(), MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/TestEventLocator.java
New file
0,0 → 1,120
/*
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.test.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.PrecisionModel;
import org.hibernatespatial.mgeom.*;
import org.junit.Before;
import org.junit.Test;
 
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
 
public class TestEventLocator {
 
private PrecisionModel prec = new PrecisionModel(PrecisionModel.FIXED);
 
private MGeometryFactory mgeomFactory = new MGeometryFactory(
MCoordinateSequenceFactory.instance());
 
private MultiMLineString incrML;
 
@Before
public void setUp() {
 
MCoordinate[] coordinates = new MCoordinate[]{
MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0),
MCoordinate.create2dWithMeasure(1.0, 0.0, 1.0),
MCoordinate.create2dWithMeasure(2.0, 0.0, 2.0),
MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0),
MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0)
};
MLineString line1 = mgeomFactory.createMLineString(coordinates);
 
MCoordinate[] coordinates2 = new MCoordinate[]{
MCoordinate.create2dWithMeasure(5.0, 0.0, 5.0),
MCoordinate.create2dWithMeasure(6.0, 0.0, 6.0),
MCoordinate.create2dWithMeasure(7.0, 0.0, 7.0),
};
MLineString line2 = mgeomFactory.createMLineString(coordinates2);
 
MCoordinate[] coordinates3 = new MCoordinate[]{
MCoordinate.create2dWithMeasure(9.0, 0.0, 9.0),
MCoordinate.create2dWithMeasure(10.0, 0.0, 10.0),
MCoordinate.create2dWithMeasure(11.0, 0.0, 11.0),
};
MLineString line3 = mgeomFactory.createMLineString(coordinates2);
 
incrML = mgeomFactory.createMultiMLineString(new MLineString[]{line1, line2});
 
}
 
@Test
public void test_event_starts_at_end_of_component() throws MGeometryException {
MultiMLineString result = EventLocator.getLinearGeometry(incrML, 4.0, 5.5);
assertNotNull(result);
assertEquals(1, result.getNumGeometries());
assertEquals(2, result.getCoordinates().length);
Coordinate[] coordinates = result.getCoordinates();
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 5.0), (MCoordinate) coordinates[0]);
assertEquals(MCoordinate.create2dWithMeasure(5.5, 0.0, 5.5), (MCoordinate) coordinates[1]);
 
}
 
@Test
public void test_event_ends_at_begin_of_component() throws MGeometryException {
MultiMLineString result = EventLocator.getLinearGeometry(incrML, 3.0, 5.0);
assertNotNull(result);
assertEquals(1, result.getNumGeometries());
assertEquals(2, result.getCoordinates().length);
Coordinate[] coordinates = result.getCoordinates();
assertEquals(MCoordinate.create2dWithMeasure(3.0, 0.0, 3.0), (MCoordinate) coordinates[0]);
assertEquals(MCoordinate.create2dWithMeasure(4.0, 0.0, 4.0), (MCoordinate) coordinates[1]);
}
 
 
@Test
public void test_event_ends_at_end_of_component() throws MGeometryException {
MultiMLineString result = EventLocator.getLinearGeometry(incrML, 4.5, 7.0);
assertNotNull(result);
assertEquals(1, result.getNumGeometries());
assertEquals(3, result.getCoordinates().length);
Coordinate[] coordinates = result.getCoordinates();
assertEquals(MCoordinate.create2dWithMeasure(5.0, 0.0, 5.0), (MCoordinate) coordinates[0]);
assertEquals(MCoordinate.create2dWithMeasure(6.0, 0.0, 6.0), (MCoordinate) coordinates[1]);
assertEquals(MCoordinate.create2dWithMeasure(7.0, 0.0, 7.0), (MCoordinate) coordinates[2]);
}
 
@Test
public void test_locator_result_has_same_srid_as_input_mgeometry() throws MGeometryException {
incrML.setSRID(123);
MultiMLineString result = EventLocator.getLinearGeometry(incrML, 4.5, 7.0);
assertEquals(123, result.getSRID());
}
 
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/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 test 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 test for boolean
* equalsExact(com.vividsolutions.jts.geom.Geometry, double)
*/
 
public void testEqualsExactGeometrydouble() {
// TODO Implement equalsExact().
}
 
/*
* Class under test for void
* MultiLineString(com.vividsolutions.jts.geom.LineString[],
* com.vividsolutions.jts.geom.PrecisionModel, int)
*/
 
public void testMultiLineStringLineStringArrayPrecisionModelint() {
// TODO Implement MultiLineString().
}
 
/*
* Class under test 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/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/mgeom/MLineStringTest.java
New file
0,0 → 1,736
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.test.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.CoordinateSequenceComparator;
import com.vividsolutions.jts.geom.PrecisionModel;
import junit.framework.TestCase;
import org.hibernatespatial.mgeom.*;
 
/**
* @author Karel Maesen
*/
public class MLineStringTest extends TestCase {
 
private PrecisionModel prec = new PrecisionModel(PrecisionModel.FIXED);
private MGeometryFactory mgeomFactory = new MGeometryFactory(
MCoordinateSequenceFactory.instance());
 
private MLineString controlledLine;
 
private MLineString arbitraryLine;
 
private MLineString nullLine;
 
private MLineString ringLine;
 
public static void main(String[] args) {
junit.textui.TestRunner.run(MLineStringTest.class);
}
 
/*
* @see TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
MCoordinate mc0 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
MCoordinate mc1 = MCoordinate.create2dWithMeasure(1.0, 0.0, 0.0);
MCoordinate mc2 = MCoordinate.create2dWithMeasure(1.0, 1.0, 0.0);
MCoordinate mc3 = MCoordinate.create2dWithMeasure(2.0, 1.0, 0.0);
 
MCoordinate[] mcoar = new MCoordinate[] { mc0, mc1, mc2, mc3 };
controlledLine = mgeomFactory.createMLineString(mcoar);
 
mc0 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
mc1 = MCoordinate.create2dWithMeasure(1.0, 0.0, 0.0);
mc2 = MCoordinate.create2dWithMeasure(1.0, 1.0, 0.0);
mc3 = MCoordinate.create2dWithMeasure(0.0, 1.0, 0.0);
MCoordinate mc4 = MCoordinate.create2dWithMeasure(0.0, 0.0, 0.0);
 
mcoar = new MCoordinate[] { mc0, mc1, mc2, mc3, mc4 };
ringLine = mgeomFactory.createMLineString(mcoar);
 
int l = (int) Math.round(Math.random() * 250.0);
l = Math.max(2, l);
System.out.println("Size of arbitraryline ==" + l);
mcoar = new MCoordinate[l];
for (int i = 0; i < mcoar.length; i++) {
double x = Math.random() * 100000.0;
double y = Math.random() * 100000.0;
double z = Double.NaN; // JTS doesn't support operations on the
// z-coordinate value
double m = Math.random() * 100000.0;
mcoar[i] = new MCoordinate(x, y, z, m);
}
arbitraryLine = mgeomFactory.createMLineString(mcoar);
 
mcoar = new MCoordinate[0];
nullLine = mgeomFactory.createMLineString(mcoar);
}
 
/*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
}
 
/**
* Constructor for MLineStringTest.
*
* @param name
*/
public MLineStringTest(String name) {
super(name);
}
 
//
// public void testMLineString() {
 
// }
 
/*
* Class under test 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;
}
// test 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 test 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));
// test reversing the ordered line
orderedLine.reverseMeasures();
assertTrue(orderedLine.isMonotone(false));
assertTrue(orderedLine.isMonotone(true));
// test 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));
// test 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));
// test reversing the line
reverseOrderedLine.reverseMeasures();
assertTrue(reverseOrderedLine.isMonotone(false));
assertTrue(reverseOrderedLine.isMonotone(true));
// test 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));
// test 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));
// test 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 test 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 test 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/hibernate-3.6-integration/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 {
 
private int id;
 
private String type;
 
private Geometry geom;
 
public int getId() {
return id;
}
 
public void setId(int 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/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/TestSpatialFunctions.java
New file
0,0 → 1,351
/*
* $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 org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernatespatial.GeometryUserType;
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 junit.framework.Assert.assertTrue;
import static org.junit.Assert.*;
 
/**
* @author Karel Maesen, Geovise BVBA
*/
public class TestSpatialFunctions {
 
private static Logger LOGGER = LoggerFactory.getLogger(TestSpatialFunctions.class);
 
private static SessionFactory factory;
private final AbstractExpectationsFactory expectationsFactory;
private final GeometryEquality geometryEquality;
 
public TestSpatialFunctions(AbstractExpectationsFactory expectationsFactory, GeometryEquality geometryEquality) {
this.expectationsFactory = expectationsFactory;
this.geometryEquality = geometryEquality;
}
 
public TestSpatialFunctions(AbstractExpectationsFactory expectationsFactory) {
this(expectationsFactory, new GeometryEquality());
}
 
public static void setUpBeforeClass() throws Exception {
 
// 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_dimension() throws SQLException {
Map<Integer, Integer> dbexpected = expectationsFactory.getDimension();
String hql = "SELECT id, dimension(geom) FROM GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
public void test_astext() throws SQLException {
Map<Integer, String> dbexpected = expectationsFactory.getAsText();
String hql = "SELECT id, astext(geom) from GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
public void test_asbinary() throws SQLException {
Map<Integer, byte[]> dbexpected = expectationsFactory.getAsBinary();
String hql = "SELECT id, asbinary(geom) from GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
 
public void test_geometrytype() throws SQLException {
Map<Integer, String> dbexpected = expectationsFactory.getGeometryType();
String hql = "SELECT id, geometrytype(geom) from GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
public void test_srid() throws SQLException {
Map<Integer, Integer> dbexpected = expectationsFactory.getSrid();
String hql = "SELECT id, srid(geom) from GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
public void test_issimple() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getIsSimple();
String hql = "SELECT id, issimple(geom) from GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
public void test_isempty() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getIsEmpty();
String hql = "SELECT id, isEmpty(geom) from GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
 
public void test_boundary() throws SQLException {
Map<Integer, Geometry> dbexpected = expectationsFactory.getBoundary();
String hql = "SELECT id, boundary(geom) from GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
 
public void test_envelope() throws SQLException {
Map<Integer, Geometry> dbexpected = expectationsFactory.getEnvelope();
String hql = "SELECT id, envelope(geom) from GeomEntity";
retrieveHQLResultsAndCompare(dbexpected, hql);
}
 
public void test_within() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getWithin(expectationsFactory.getTestPolygon());
String hql = "SELECT id, within(geom, :filter) from GeomEntity where within(geom, :filter) = true and srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
private Map<String, Object> createQueryParams(String filterParamName, Object value) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(filterParamName, value);
return params;
}
 
public void test_equals() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getEquals(expectationsFactory.getTestPolygon());
String hql = "SELECT id, equals(geom, :filter) from GeomEntity where equals(geom, :filter) = true and srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_crosses() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getCrosses(expectationsFactory.getTestPolygon());
String hql = "SELECT id, crosses(geom, :filter) from GeomEntity where crosses(geom, :filter) = true and srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
 
}
 
public void test_contains() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getContains(expectationsFactory.getTestPolygon());
String hql = "SELECT id, contains(geom, :filter) from GeomEntity where contains(geom, :filter) = true and srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
 
public void test_disjoint() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getDisjoint(expectationsFactory.getTestPolygon());
String hql = "SELECT id, disjoint(geom, :filter) from GeomEntity where disjoint(geom, :filter) = true and srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_intersects() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getIntersects(expectationsFactory.getTestPolygon());
String hql = "SELECT id, intersects(geom, :filter) from GeomEntity where intersects(geom, :filter) = true and srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_overlaps() throws SQLException {
Map<Integer, Boolean> dbexpected = expectationsFactory.getOverlaps(expectationsFactory.getTestPolygon());
String hql = "SELECT id, overlaps(geom, :filter) from GeomEntity where overlaps(geom, :filter) = true and srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_touches() throws SQLException {
String hql = "SELECT id, touches(geom, :filter) from GeomEntity where touches(geom, :filter) = true and srid(geom) = 4326";
Map<Integer, Boolean> dbexpected = expectationsFactory.getTouches(expectationsFactory.getTestPolygon());
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_relate() throws SQLException {
String matrix = "T*T***T**";
Map<Integer, Boolean> dbexpected = expectationsFactory.getRelate(expectationsFactory.getTestPolygon(), matrix);
String hql = "SELECT id, relate(geom, :filter, :matrix) from GeomEntity where relate(geom, :filter, :matrix) = true and srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
params.put("matrix", matrix);
retrieveHQLResultsAndCompare(dbexpected, hql, params);
 
matrix = "FF*FF****";
dbexpected = expectationsFactory.getRelate(expectationsFactory.getTestPolygon(), matrix);
params.put("matrix", matrix);
retrieveHQLResultsAndCompare(dbexpected, hql, params);
 
}
 
public void test_distance() throws SQLException {
Map<Integer, Double> dbexpected = expectationsFactory.getDistance(expectationsFactory.getTestPolygon());
String hql = "SELECT id, distance(geom, :filter) from GeomEntity where srid(geom) = 4326";
Map<String, Object> params = createQueryParams("filter", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_buffer() throws SQLException {
Map<Integer, Geometry> dbexpected = expectationsFactory.getBuffer(Double.valueOf(1.0));
String hql = "SELECT id, buffer(geom, :distance) from GeomEntity where srid(geom) = 4326";
Map<String, Object> params = createQueryParams("distance", Double.valueOf(1.0));
retrieveHQLResultsAndCompare(dbexpected, hql, params);
 
}
 
public void test_convexhull() throws SQLException {
Map<Integer, Geometry> dbexpected = expectationsFactory.getConvexHull(expectationsFactory.getTestPolygon());
String hql = "SELECT id, convexhull(geomunion(geom, :polygon)) from GeomEntity where srid(geom) = 4326";
Map<String, Object> params = createQueryParams("polygon", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
 
}
 
public void test_intersection() throws SQLException {
Map<Integer, Geometry> dbexpected = expectationsFactory.getIntersection(expectationsFactory.getTestPolygon());
String hql = "SELECT id, intersection(geom, :polygon) from GeomEntity where srid(geom) = 4326";
Map<String, Object> params = createQueryParams("polygon", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_difference() throws SQLException {
Map<Integer, Geometry> dbexpected = expectationsFactory.getDifference(expectationsFactory.getTestPolygon());
String hql = "SELECT id, difference(geom, :polygon) from GeomEntity where srid(geom) = 4326";
Map<String, Object> params = createQueryParams("polygon", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_symdifference() throws SQLException {
Map<Integer, Geometry> dbexpected = expectationsFactory.getSymDifference(expectationsFactory.getTestPolygon());
String hql = "SELECT id, symdifference(geom, :polygon) from GeomEntity where srid(geom) = 4326";
Map<String, Object> params = createQueryParams("polygon", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public void test_geomunion() throws SQLException {
Map<Integer, Geometry> dbexpected = expectationsFactory.getGeomUnion(expectationsFactory.getTestPolygon());
String hql = "SELECT id, geomunion(geom, :polygon) from GeomEntity where srid(geom) = 4326";
Map<String, Object> params = createQueryParams("polygon", expectationsFactory.getTestPolygon());
retrieveHQLResultsAndCompare(dbexpected, hql, params);
}
 
public <T> void retrieveHQLResultsAndCompare(Map<Integer, T> dbexpected, String hql) {
Map<Integer, T> hsreceived = new HashMap<Integer, T>();
doInSession(hql, hsreceived, null);
compare(dbexpected, hsreceived);
}
 
protected <T> void retrieveHQLResultsAndCompare(Map<Integer, T> dbexpected, String hql, Map<String, Object> params) {
Map<Integer, T> hsreceived = new HashMap<Integer, T>();
doInSession(hql, hsreceived, params);
compare(dbexpected, hsreceived);
}
 
protected <T> void compare(Map<Integer, T> expected, Map<Integer, T> received) {
for (Integer id : expected.keySet()) {
LOGGER.debug("Case :" + id);
LOGGER.debug("expected: " + expected.get(id));
LOGGER.debug("received: " + received.get(id));
compare(id, expected.get(id), received.get(id));
}
}
 
 
protected void compare(Integer id, Object expected, Object received) {
if (expected instanceof byte[]) {
assertArrayEquals("Failure on test for case " + id, (byte[]) expected, (byte[]) received);
 
} else if (expected instanceof Geometry) {
if (!(received instanceof Geometry))
fail("Expected a Geometry, but received an object of type " + received.getClass().getCanonicalName());
assertTrue("Failure on test for case " + id, geometryEquality.test((Geometry) expected, (Geometry) received));
 
} else {
if (expected instanceof Long) {
assertEquals("Failure on test for case " + id, ((Long) expected).intValue(), received);
} else {
assertEquals("Failure on test for case " + id, expected, received);
}
}
}
 
private <T> void doInSession(String hql, Map<Integer, T> result, Map<String, Object> params) {
Session session = null;
Transaction tx = null;
try {
session = factory.openSession();
tx = session.beginTransaction();
Query query = session.createQuery(hql);
setParameters(params, query);
addQueryResults(result, query);
} finally {
if (tx != null) tx.rollback();
if (session != null) session.close();
}
}
 
private <T> void addQueryResults(Map<Integer, T> result, Query query) {
List<Object[]> rows = (List<Object[]>) query.list();
for (Object[] row : rows) {
Integer id = (Integer) row[0];
T val = (T) row[1];
result.put(id, val);
}
}
 
private void setParameters(Map<String, Object> params, Query query) {
if (params == null) return;
for (String param : params.keySet()) {
Object value = params.get(param);
if (value instanceof Geometry) {
query.setParameter(param, value, GeometryUserType.TYPE);
} else {
query.setParameter(param, value);
}
}
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/pojo/reader/TestBasicFeatureReader.java
New file
0,0 → 1,58
package org.hibernatespatial.test.pojo.reader;
 
import org.dom4j.Document;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernatespatial.HBSpatialExtension;
import org.hibernatespatial.cfg.HSConfiguration;
import org.hibernatespatial.helper.FinderException;
import org.hibernatespatial.pojo.AutoMapper;
import org.hibernatespatial.readers.BasicFeatureReader;
import org.hibernatespatial.readers.Feature;
import org.hibernatespatial.readers.FeatureReader;
 
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
 
public class TestBasicFeatureReader {
 
private SessionFactory sessionFactory;
private AutoMapper pojoUtil;
 
public void setUpBeforeClass(HSConfiguration hsconfig, Connection conn) throws SQLException {
 
HBSpatialExtension.setConfiguration(hsconfig);
List<String> tables = new ArrayList<String>();
tables.add("geomtest");
Document mappingdocument;
try {
mappingdocument = AutoMapper.map(conn, null, null, tables);
} catch (Exception e) {
throw new RuntimeException(e);
}
 
Configuration config = new Configuration();
config.addXML(mappingdocument.asXML());
this.sessionFactory = config.configure().buildSessionFactory();
 
}
 
public void testReaderNoFilters(int expected) throws FinderException {
Class<?> clazz = AutoMapper.getClass(null, null, "geomtest");
FeatureReader reader = new BasicFeatureReader(clazz, this.sessionFactory, null, null);
int count = 0;
while (reader.hasNext()) {
Feature f = reader.next();
assertNotNull(f.getId());
count++;
}
assertEquals(expected, count);
reader.close();
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/pojo/TestPojoUtility.java
New file
0,0 → 1,59
package org.hibernatespatial.test.pojo;
 
import org.dom4j.Document;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernatespatial.HBSpatialExtension;
import org.hibernatespatial.cfg.HSConfiguration;
import org.hibernatespatial.pojo.AutoMapper;
 
import java.io.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
public class TestPojoUtility {
 
private SessionFactory sessionFactory;
private AutoMapper pojoUtil;
 
public void setUpBeforeClass(HSConfiguration hsconfig, Connection conn) throws SQLException {
 
HBSpatialExtension.setConfiguration(hsconfig);
List<String> tables = new ArrayList<String>();
tables.add("geomtest");
// tables.add("test2") ;
Document mappingdocument;
try {
mappingdocument = AutoMapper.map(conn, null, null, tables);
writeToFile(mappingdocument);
} catch (Exception e) {
throw new RuntimeException(e);
}
 
Configuration config = new Configuration();
config.addXML(mappingdocument.asXML());
this.sessionFactory = config.configure().buildSessionFactory();
 
}
 
private void writeToFile(Document mappingdocument) {
try {
File f = File.createTempFile("test-hs-automapper", ".xml");
FileWriter writer = new FileWriter(f);
mappingdocument.write(writer);
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
 
public SessionFactory getSessionFactory() {
return this.sessionFactory;
}
 
public AutoMapper getPOJOUtility() {
return this.pojoUtil;
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/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/hibernate-3.6-integration/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 test 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/hibernate-3.6-integration/hibernate-spatial/src/test/java/org/hibernatespatial/test/EWKTReader.java
New file
0,0 → 1,834
/*
* $Id$
*
* This file is an adapted version of the JTS WKTReader. It has
* been extended by Martin Steinwender to deal with Measured coordinates.
*
* Original copyright notice:
*
* The JTS Topology Suite is a collection of Java classes that
* implement the fundamental operations required to validate a given
* geo-spatial data set to a known topological specification.
*
* Copyright (C) 2001 Vivid Solutions
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
 
 
package org.hibernatespatial.test;
 
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.util.Assert;
import org.hibernatespatial.mgeom.MCoordinate;
import org.hibernatespatial.mgeom.MGeometryFactory;
import org.hibernatespatial.mgeom.MLineString;
 
import java.io.IOException;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
 
/**
* Converts a geometry in EWKT to a JTS-Geometry.
* <p/>
* <code>EWKTReader</code> supports
* extracting <code>Geometry</code> objects from either {@link java.io.Reader}s or
* {@link String}s. This allows it to function as a parser to read <code>Geometry</code>
* objects from text blocks embedded in other data formats (e.g. XML). <P>
* <p/>
* A <code>WKTReader</code> is parameterized by a <code>GeometryFactory</code>,
* to allow it to create <code>Geometry</code> objects of the appropriate
* implementation. In particular, the <code>GeometryFactory</code>
* determines the <code>PrecisionModel</code> and <code>SRID</code> that is
* used. <P>
* <p/>
* The <code>WKTReader</code> converts all input numbers to the precise
* internal representation.
* <p/>
* <h3>Notes:</h3>
* <ul>
* <li>The reader supports non-standard "LINEARRING" tags.
* <li>The reader uses Double.parseDouble to perform the conversion of ASCII
* numbers to floating point. This means it supports the Java
* syntax for floating point literals (including scientific notation).
* </ul>
* <p/>
* <h3>Syntax</h3>
* The following syntax specification describes the version of Well-Known Text
* supported by JTS.
* (The specification uses a syntax language similar to that used in
* the C and Java language specifications.)
* <p/>
* <p/>
* <blockquote><pre>
* <i>WKTGeometry:</i> one of<i>
* <p/>
* WKTPoint WKTLineString WKTLinearRing WKTPolygon
* WKTMultiPoint WKTMultiLineString WKTMultiPolygon
* WKTGeometryCollection</i>
* <p/>
* <i>WKTPoint:</i> <b>POINT ( </b><i>Coordinate</i> <b>)</b>
* <p/>
* <i>WKTLineString:</i> <b>LINESTRING</b> <i>CoordinateSequence</i>
* <p/>
* <i>WKTLinearRing:</i> <b>LINEARRING</b> <i>CoordinateSequence</i>
* <p/>
* <i>WKTPolygon:</i> <b>POLYGON</b> <i>CoordinateSequenceList</i>
* <p/>
* <i>WKTMultiPoint:</i> <b>MULTIPOINT</b> <i>CoordinateSequence</i>
* <p/>
* <i>WKTMultiLineString:</i> <b>MULTILINESTRING</b> <i>CoordinateSequenceList</i>
* <p/>
* <i>WKTMultiPolygon:</i>
* <b>MULTIPOLYGON (</b> <i>CoordinateSequenceList {</i> , <i>CoordinateSequenceList }</i> <b>)</b>
* <p/>
* <i>WKTGeometryCollection: </i>
* <b>GEOMETRYCOLLECTION (</b> <i>WKTGeometry {</i> , <i>WKTGeometry }</i> <b>)</b>
* <p/>
* <i>CoordinateSequenceList:</i>
* <b>(</b> <i>CoordinateSequence {</i> <b>,</b> <i>CoordinateSequence }</i> <b>)</b>
* <p/>
* <i>CoordinateSequence:</i>
* <b>(</b> <i>Coordinate {</i> , <i>Coordinate }</i> <b>)</b>
* <p/>
* <i>Coordinate:
* Number Number Number<sub>opt</sub></i>
* <p/>
* <i>Number:</i> A Java-style floating-point number
* <p/>
* </pre></blockquote>
*
* @see WKTWriter
*/
public class EWKTReader {
private static final String EMPTY = "EMPTY";
private static final String COMMA = ",";
private static final String L_PAREN = "(";
private static final String R_PAREN = ")";
private static final String EQUALS = "=";
private static final String SEMICOLON = ";";
 
private GeometryFactory geometryFactory;
private PrecisionModel precisionModel;
private StreamTokenizer tokenizer;
 
private int dimension = -1;
private Boolean hasM = null;
 
/**
* Creates a reader that creates objects using the default {@link GeometryFactory}.
*/
public EWKTReader() {
this(new MGeometryFactory());
}
 
/**
* Creates a reader that creates objects using the given
* {@link GeometryFactory}.
*
* @param geometryFactory the factory used to create <code>Geometry</code>s.
*/
public EWKTReader(GeometryFactory geometryFactory) {
this.geometryFactory = geometryFactory;
precisionModel = geometryFactory.getPrecisionModel();
}
 
/**
* Reads a Well-Known Text representation of a {@link com.vividsolutions.jts.geom.Geometry}
* from a {@link String}.
*
* @param wellKnownText one or more <Geometry Tagged Text>strings (see the OpenGIS
* Simple Features Specification) separated by whitespace
* @return a <code>Geometry</code> specified by <code>wellKnownText</code>
* @throws com.vividsolutions.jts.io.ParseException
* if a parsing problem occurs
*/
public Geometry read(String wellKnownText) throws ParseException {
StringReader reader = new StringReader(wellKnownText);
try {
return read(reader);
}
finally {
reader.close();
}
}
 
/**
* Reads a Well-Known Text representation of a {@link Geometry}
* from a {@link java.io.Reader}.
*
* @param reader a Reader which will return a <Geometry Tagged Text>
* string (see the OpenGIS Simple Features Specification)
* @return a <code>Geometry</code> read from <code>reader</code>
* @throws ParseException if a parsing problem occurs
*/
public Geometry read(Reader reader) throws ParseException {
 
try {
 
synchronized (this) {
if (this.tokenizer != null) {
throw new RuntimeException("EWKT-Reader is already in use.");
}
tokenizer = new StreamTokenizer(reader);
}
 
// set tokenizer to NOT parse numbers
tokenizer.resetSyntax();
tokenizer.wordChars('a', 'z');
tokenizer.wordChars('A', 'Z');
tokenizer.wordChars(128 + 32, 255);
tokenizer.wordChars('0', '9');
tokenizer.wordChars('-', '-');
tokenizer.wordChars('+', '+');
tokenizer.wordChars('.', '.');
tokenizer.whitespaceChars(0, ' ');
tokenizer.commentChar('#');
 
this.hasM = null;
this.dimension = -1;
 
return readGeometryTaggedText();
 
} catch (IOException e) {
throw new ParseException(e.toString());
} finally {
this.tokenizer = null;
}
}
 
/**
* Returns the next array of <code>Coordinate</code>s in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next element returned by the stream should be L_PAREN (the
* beginning of "(x1 y1, x2 y2, ..., xn yn)") or EMPTY.
* @return the next array of <code>Coordinate</code>s in the
* stream, or an empty array if EMPTY is the next element returned by
* the stream.
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private MCoordinate[] getCoordinates()
throws IOException, ParseException {
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return new MCoordinate[]{};
}
ArrayList coordinates = new ArrayList();
coordinates.add(getPreciseCoordinate());
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
coordinates.add(getPreciseCoordinate());
nextToken = getNextCloserOrComma();
}
return (MCoordinate[]) coordinates.toArray(new MCoordinate[coordinates.size()]);
}
 
/**
* gets the next Coordinate and checks dimension
*
* @return
* @throws IOException
* @throws ParseException
*/
private Coordinate getPreciseCoordinate()
throws IOException, ParseException {
MCoordinate coord = new MCoordinate();
coord.x = getNextNumber();
coord.y = getNextNumber();
 
Double thirdOrdinateValue = null;
Double fourthOrdinateValue = null;
 
if (this.dimension == 3) {
thirdOrdinateValue = getNextNumber();
} else if (this.dimension == 4) {
thirdOrdinateValue = getNextNumber();
fourthOrdinateValue = getNextNumber();
} else if (this.dimension < 0) {
if (isNumberNext()) thirdOrdinateValue = getNextNumber();
if (isNumberNext()) fourthOrdinateValue = getNextNumber();
 
if (fourthOrdinateValue != null) {
this.dimension = 4;
setHasM(true);
} else if (thirdOrdinateValue != null) {
this.dimension = 3;
setHasM(Boolean.TRUE.equals(this.hasM));
} else {
this.dimension = 2;
setHasM(false);
}
}
 
switch (this.dimension) {
case 2:
break;
case 3:
if (this.hasM) {
coord.m = thirdOrdinateValue;
} else {
coord.z = thirdOrdinateValue;
}
break;
case 4:
if (this.hasM) {
coord.z = thirdOrdinateValue;
coord.m = fourthOrdinateValue;
} else {
throw new ParseException("Unsupported geometry dimension.");
}
break;
default:
throw new ParseException("Unsupported geometry dimension.");
}
 
precisionModel.makePrecise(coord);
return coord;
}
 
 
private boolean isNumberNext() throws IOException {
int type = tokenizer.nextToken();
tokenizer.pushBack();
return type == StreamTokenizer.TT_WORD;
}
 
/**
* Parses the next number in the stream.
* Numbers with exponents are handled.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be a number.
* @return the next number in the stream
* @throws ParseException if the next token is not a valid number
* @throws IOException if an I/O error occurs
*/
private double getNextNumber() throws IOException,
ParseException {
int type = tokenizer.nextToken();
switch (type) {
case StreamTokenizer.TT_WORD: {
try {
return Double.parseDouble(tokenizer.sval);
}
catch (NumberFormatException ex) {
throw new ParseException("Invalid number: " + tokenizer.sval);
}
}
}
parseError("number");
return 0.0;
}
 
/**
* Returns the next EMPTY or L_PAREN in the stream as uppercase text.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be EMPTY or L_PAREN.
* @return the next EMPTY or L_PAREN in the stream as uppercase
* text.
* @throws ParseException if the next token is not EMPTY or L_PAREN
* @throws IOException if an I/O error occurs
*/
private String getNextEmptyOrOpener() throws IOException, ParseException {
String nextWord = getNextWord();
if (nextWord.equals(EMPTY) || nextWord.equals(L_PAREN)) {
return nextWord;
}
parseError(EMPTY + " or " + L_PAREN);
return null;
}
 
/**
* Returns the next R_PAREN or COMMA in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be R_PAREN or COMMA.
* @return the next R_PAREN or COMMA in the stream
* @throws ParseException if the next token is not R_PAREN or COMMA
* @throws IOException if an I/O error occurs
*/
private String getNextCloserOrComma() throws IOException, ParseException {
String nextWord = getNextWord();
if (nextWord.equals(COMMA) || nextWord.equals(R_PAREN)) {
return nextWord;
}
parseError(COMMA + " or " + R_PAREN);
return null;
}
 
/**
* Returns the next R_PAREN in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be R_PAREN.
* @return the next R_PAREN in the stream
* @throws ParseException if the next token is not R_PAREN
* @throws IOException if an I/O error occurs
*/
private String getNextCloser() throws IOException, ParseException {
String nextWord = getNextWord();
if (nextWord.equals(R_PAREN)) {
return nextWord;
}
parseError(R_PAREN);
return null;
}
 
/**
* Returns the next R_PAREN in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be R_PAREN.
* @return the next R_PAREN in the stream
* @throws ParseException if the next token is not R_PAREN
* @throws IOException if an I/O error occurs
*/
private int getSRID() throws IOException, ParseException {
if (!getNextWord().equals(EQUALS)) {
parseError(EQUALS);
return 0;
}
int srid = Integer.parseInt(getNextWord());
if (!getNextWord().equals(SEMICOLON)) {
parseError(SEMICOLON);
return 0;
}
return srid;
}
 
/**
* Returns the next word in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next token must be a word.
* @return the next word in the stream as uppercase text
* @throws ParseException if the next token is not a word
* @throws IOException if an I/O error occurs
*/
private String getNextWord() throws IOException, ParseException {
int type = tokenizer.nextToken();
switch (type) {
case StreamTokenizer.TT_WORD:
 
String word = tokenizer.sval;
if (word.equalsIgnoreCase(EMPTY))
return EMPTY;
return word;
 
case '(':
return L_PAREN;
case ')':
return R_PAREN;
case ',':
return COMMA;
case '=':
return EQUALS;
case ';':
return SEMICOLON;
}
parseError("word");
return null;
}
 
/**
* Throws a formatted ParseException for the current token.
*
* @param expected a description of what was expected
* @throws ParseException
* @throws com.vividsolutions.jts.util.AssertionFailedException
* if an invalid token is encountered
*/
private void parseError(String expected)
throws ParseException {
// throws Asserts for tokens that should never be seen
if (tokenizer.ttype == StreamTokenizer.TT_NUMBER)
Assert.shouldNeverReachHere("Unexpected NUMBER token");
if (tokenizer.ttype == StreamTokenizer.TT_EOL)
Assert.shouldNeverReachHere("Unexpected EOL token");
 
String tokenStr = tokenString();
throw new ParseException("Expected " + expected + " but found " + tokenStr);
}
 
/**
* Gets a description of the current token
*
* @return a description of the current token
*/
private String tokenString() {
switch (tokenizer.ttype) {
case StreamTokenizer.TT_NUMBER:
return "<NUMBER>";
case StreamTokenizer.TT_EOL:
return "End-of-Line";
case StreamTokenizer.TT_EOF:
return "End-of-Stream";
case StreamTokenizer.TT_WORD:
return "'" + tokenizer.sval + "'";
}
return "'" + (char) tokenizer.ttype + "'";
}
 
/**
* Creates a <code>Geometry</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;Geometry Tagged Text&gt;.
* @return a <code>Geometry</code> specified by the next token
* in the stream
* @throws ParseException if the coordinates used to create a <code>Polygon</code>
* shell and holes do not form closed linestrings, or if an unexpected
* token was encountered
* @throws IOException if an I/O error occurs
*/
private Geometry readGeometryTaggedText() throws IOException, ParseException {
 
String type = null;
Geometry geom;
 
int srid = geometryFactory.getSRID();
 
try {
String firstWord = getNextWord();
if ("SRID".equals(firstWord)) {
srid = getSRID();
type = getNextWord();
} else {
type = firstWord;
}
} catch (IOException e) {
return null;
} catch (ParseException e) {
return null;
}
 
if (type.equals("POINT")) {
geom = readPointText();
} else if (type.equals("POINTM")) {
setHasM(true);
geom = readPointText();
} else if (type.equalsIgnoreCase("LINESTRING")) {
geom = readLineStringText();
} else if (type.equalsIgnoreCase("LINESTRINGM")) {
setHasM(true);
geom = readLineStringText();
} else if (type.equalsIgnoreCase("LINEARRING")) {
geom = readLinearRingText();
} else if (type.equalsIgnoreCase("LINEARRINGM")) {
setHasM(true);
geom = readLinearRingText();
} else if (type.equalsIgnoreCase("POLYGON")) {
geom = readPolygonText();
} else if (type.equalsIgnoreCase("POLYGONM")) {
//setHasM(true);
//geom = readPolygonText();
throw new RuntimeException("PolygonM is not supported.");
} else if (type.equalsIgnoreCase("MULTIPOINT")) {
geom = readMultiPointText();
} else if (type.equalsIgnoreCase("MULTIPOINTM")) {
setHasM(true);
geom = readMultiPointText();
} else if (type.equalsIgnoreCase("MULTILINESTRING")) {
geom = readMultiLineStringText();
} else if (type.equalsIgnoreCase("MULTILINESTRINGM")) {
setHasM(true);
geom = readMultiLineStringText();
} else if (type.equalsIgnoreCase("MULTIPOLYGON")) {
geom = readMultiPolygonText();
} else if (type.equalsIgnoreCase("MULTIPOLYGONM")) {
//setHasM(true);
//geom = readMultiPolygonText();
throw new RuntimeException("MultiPolygonM is not supported.");
} else if (type.equalsIgnoreCase("GEOMETRYCOLLECTION")) {
geom = readGeometryCollectionText();
} else if (type.equalsIgnoreCase("GEOMETRYCOLLECTIONM")) {
setHasM(true);
geom = readGeometryCollectionText();
} else {
throw new ParseException("Unknown geometry type: " + type);
}
geom.setSRID(srid);
 
return geom;
}
 
/**
* m-values sicherstellen
*
* @throws ParseException
*/
private void setHasM(boolean hasM) throws ParseException {
if (this.hasM == null) {
this.hasM = hasM;
} else if (this.hasM != hasM) {
throw new ParseException("Inkonsistent use of m-values.");
}
}
 
/**
* Creates a <code>Point</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;Point Text&gt;.
* @return a <code>Point</code> specified by the next token in
* the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private Point readPointText() throws IOException, ParseException {
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return geometryFactory.createPoint((Coordinate) null);
}
Point point = geometryFactory.createPoint(getPreciseCoordinate());
getNextCloser();
return point;
}
 
/**
* Creates a <code>LineString</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;LineString Text&gt;.
* @return a <code>LineString</code> specified by the next
* token in the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private LineString readLineStringText() throws IOException, ParseException {
 
MCoordinate[] coords = getCoordinates();
if (this.hasM != null && this.hasM)
return ((MGeometryFactory) geometryFactory).createMLineString(coords);
else
return geometryFactory.createLineString(coords);
 
}
 
/**
* Creates a <code>LinearRing</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;LineString Text&gt;.
* @return a <code>LinearRing</code> specified by the next
* token in the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if the coordinates used to create the <code>LinearRing</code>
* do not form a closed linestring, or if an unexpected token was
* encountered
*/
private LinearRing readLinearRingText()
throws IOException, ParseException {
MCoordinate[] coords = getCoordinates();
if (this.hasM)
throw new RuntimeException("LinearRingM not supported.");
else
return geometryFactory.createLinearRing(coords);
}
 
/**
* Creates a <code>MultiPoint</code> using the next token in the stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;MultiPoint Text&gt;.
* @return a <code>MultiPoint</code> specified by the next
* token in the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private MultiPoint readMultiPointText() throws IOException, ParseException {
MCoordinate[] coords = getCoordinates();
Point[] pts = toPoints(coords);
return geometryFactory.createMultiPoint(pts);
}
 
/**
* Creates an array of <code>Point</code>s having the given <code>Coordinate</code>
* s.
*
* @param coordinates the <code>Coordinate</code>s with which to create the
* <code>Point</code>s
* @return <code>Point</code>s created using this <code>WKTReader</code>
* s <code>GeometryFactory</code>
*/
private Point[] toPoints(Coordinate[] coordinates) {
ArrayList points = new ArrayList();
for (int i = 0; i < coordinates.length; i++) {
points.add(geometryFactory.createPoint(coordinates[i]));
}
return (Point[]) points.toArray(new Point[]{});
}
 
/**
* Creates a <code>Polygon</code> using the next token in the stream.
*
* @param hasM
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;Polygon Text&gt;.
* @return a <code>Polygon</code> specified by the next token
* in the stream
* @throws ParseException if the coordinates used to create the <code>Polygon</code>
* shell and holes do not form closed linestrings, or if an unexpected
* token was encountered.
* @throws IOException if an I/O error occurs
*/
private Polygon readPolygonText() throws IOException, ParseException {
 
// PolygonM is not supported
setHasM(false);
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return geometryFactory.createPolygon(geometryFactory.createLinearRing(
new Coordinate[]{}), new LinearRing[]{});
}
ArrayList holes = new ArrayList();
LinearRing shell = readLinearRingText();
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
LinearRing hole = readLinearRingText();
holes.add(hole);
nextToken = getNextCloserOrComma();
}
LinearRing[] array = new LinearRing[holes.size()];
return geometryFactory.createPolygon(shell, (LinearRing[]) holes.toArray(array));
}
 
/**
* Creates a <code>MultiLineString</code> using the next token in the stream.
*
* @param hasM
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;MultiLineString Text&gt;.
* @return a <code>MultiLineString</code> specified by the
* next token in the stream
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private com.vividsolutions.jts.geom.MultiLineString readMultiLineStringText() throws IOException, ParseException {
 
ArrayList lineStrings = new ArrayList();
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
// No Coordinates for LineString
} else {
LineString lineString = readLineStringText();
lineStrings.add(lineString);
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
lineString = readLineStringText();
lineStrings.add(lineString);
nextToken = getNextCloserOrComma();
}
}
 
if (this.hasM != null && this.hasM == true) {
MLineString[] mlines = (MLineString[]) lineStrings.toArray(new MLineString[lineStrings.size()]);
return ((MGeometryFactory) geometryFactory).createMultiMLineString(mlines);
} else {
setHasM(false);
LineString[] lines = (LineString[]) lineStrings.toArray(new LineString[lineStrings.size()]);
return geometryFactory.createMultiLineString(lines);
}
}
 
/**
* Creates a <code>MultiPolygon</code> using the next token in the stream.
*
* @param hasM
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;MultiPolygon Text&gt;.
* @return a <code>MultiPolygon</code> specified by the next
* token in the stream, or if if the coordinates used to create the
* <code>Polygon</code> shells and holes do not form closed linestrings.
* @throws IOException if an I/O error occurs
* @throws ParseException if an unexpected token was encountered
*/
private MultiPolygon readMultiPolygonText()
throws IOException, ParseException {
 
// MultiPolygonM is not supported
setHasM(false);
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return geometryFactory.createMultiPolygon(new Polygon[]{});
}
ArrayList polygons = new ArrayList();
Polygon polygon = readPolygonText();
polygons.add(polygon);
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
polygon = readPolygonText();
polygons.add(polygon);
nextToken = getNextCloserOrComma();
}
Polygon[] array = new Polygon[polygons.size()];
return geometryFactory.createMultiPolygon((Polygon[]) polygons.toArray(array));
}
 
/**
* Creates a <code>GeometryCollection</code> using the next token in the
* stream.
*
* @param tokenizer tokenizer over a stream of text in Well-known Text
* format. The next tokens must form a &lt;GeometryCollection Text&gt;.
* @return a <code>GeometryCollection</code> specified by the
* next token in the stream
* @throws ParseException if the coordinates used to create a <code>Polygon</code>
* shell and holes do not form closed linestrings, or if an unexpected
* token was encountered
* @throws IOException if an I/O error occurs
*/
private GeometryCollection readGeometryCollectionText()
throws IOException, ParseException {
 
String nextToken = getNextEmptyOrOpener();
if (nextToken.equals(EMPTY)) {
return geometryFactory.createGeometryCollection(new Geometry[]{});
}
ArrayList geometries = new ArrayList();
Geometry geometry = readGeometryTaggedText();
geometries.add(geometry);
nextToken = getNextCloserOrComma();
while (nextToken.equals(COMMA)) {
geometry = readGeometryTaggedText();
geometries.add(geometry);
nextToken = getNextCloserOrComma();
}
Geometry[] array = new Geometry[geometries.size()];
return geometryFactory.createGeometryCollection((Geometry[]) geometries.toArray(array));
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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);
// test 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/hibernate-3.6-integration/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/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/HBSpatialExtension.java
New file
0,0 → 1,239
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
 
/**
* This is the bootstrap class that is used to get an
* <code>SpatialDialect</code>.
*
* It also provides a default <code>SpatialDialect</code>.
* <code>GeometryUserType</code>s that do not have a <code>dialect</code>
* parameter use this default.
*
* 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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/criterion/SpatialRelateExpression.java
New file
0,0 → 1,133
/**
* $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 com.vividsolutions.jts.geom.Geometry;
 
/**
* An implementation of the <code>Criterion</code> interface that implements
* spatial queries: queries to the effect that a geometry property has a
* specific spatial relation to a test geometry
*
* @author Karel Maesen
*/
public class SpatialRelateExpression implements Criterion {
 
/**
* The geometry property
*/
private String propertyName = null;
 
/**
* The test geometry
*/
private Geometry value = null;
 
/**
* 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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/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/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialDialect.java
New file
0,0 → 1,104
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-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 test 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 test object and the results of
* the first phase.
* <p/>
* Postgis (up to version ??) supports explicit filtering. Oracle and MySQL
* don't.
*
* @return
*/
public boolean isTwoPhaseFiltering();
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometryFactory.java
New file
0,0 → 1,104
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.*;
 
/**
* Extension of the GeometryFactory for constructing Geometries with Measure
* support.
*
* @see com.vividsolutions.jts.geom.GeometryFactory
*/
public class MGeometryFactory extends GeometryFactory {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
public MGeometryFactory(PrecisionModel precisionModel, int SRID,
MCoordinateSequenceFactory coordinateSequenceFactory) {
super(precisionModel, SRID, coordinateSequenceFactory);
}
 
public MGeometryFactory(MCoordinateSequenceFactory coordinateSequenceFactory) {
super(coordinateSequenceFactory);
}
 
public MGeometryFactory(PrecisionModel precisionModel) {
this(precisionModel, 0, MCoordinateSequenceFactory.instance());
}
 
public MGeometryFactory(PrecisionModel precisionModel, int SRID) {
this(precisionModel, SRID, MCoordinateSequenceFactory.instance());
}
 
public MGeometryFactory() {
this(new PrecisionModel(), 0);
}
 
/**
* Constructs a MLineString using the given Coordinates; a null or empty
* array will create an empty MLineString.
*
* @param coordinates
* array of MCoordinate defining this geometry's vertices
* @see #createLineString(com.vividsolutions.jts.geom.Coordinate[])
* @return An instance of MLineString containing the coordinates
*/
public MLineString createMLineString(MCoordinate[] coordinates) {
return createMLineString(coordinates != null ? getCoordinateSequenceFactory()
.create(coordinates)
: null);
}
 
public MultiMLineString createMultiMLineString(MLineString[] mlines,
double mGap) {
return new MultiMLineString(mlines, mGap, this);
}
 
public MultiMLineString createMultiMLineString(MLineString[] mlines) {
return new MultiMLineString(mlines, 0.0d, this);
}
 
/**
* Creates a MLineString using the given CoordinateSequence; a null or empty
* CoordinateSequence will create an empty MLineString.
*
* @param coordinates
* a CoordinateSequence possibly empty, or null
* @return An MLineString instance based on the <code>coordinates</code>
* @see #createLineString(com.vividsolutions.jts.geom.CoordinateSequence)
*/
public MLineString createMLineString(CoordinateSequence coordinates) {
return new MLineString(coordinates, this);
}
 
}
/branches/hibernate-3.6-integration/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 test 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/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinate.java
New file
0,0 → 1,273
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
 
/**
* This coordinate class supports 4D coordinates, where the first 3 measures
* (x,y,z) are coordinates in a 3 dimensional space (cartesian for example), and
* the fourth is a measure value used for linear referencing. Note that the
* measure value is independent of whether the (x,y,z) values are used. For
* example, the z value can not be used while the measure value is used. <p/>
* While this class extends the Coordinate class, it can be used seamlessly as a
* substitute in the event that the Measure value is not used. In these cases
* the Measure value shall simply be Double.NaN
*
* @see com.vividsolutions.jts.geom.Coordinate
*/
public class MCoordinate extends Coordinate {
/**
*
*/
private static final long serialVersionUID = 1L;
 
public double m;
 
/**
* Default constructor
*/
public MCoordinate() {
super();
this.m = Double.NaN;
}
 
public MCoordinate(double x, double y, double z, double m) {
super(x, y, z);
this.m = m;
}
 
public MCoordinate(double x, double y) {
super(x, y);
m = Double.NaN;
}
 
public MCoordinate(Coordinate coord) {
super(coord);
if (coord instanceof MCoordinate)
m = ((MCoordinate) coord).m;
else
m = Double.NaN;
}
 
public MCoordinate(MCoordinate coord) {
super(coord);
m = coord.m;
}
 
/**
* TODO: I'd like to see this method added to the base Coordinate class
* Returns the ordinate value specified in this Coordinate instance. The
* index of the desired ordinates are specified in the CoordinateSequence
* class; hence CoodinateSequence.X returns the x ordinate,
* CoodinateSequence.Y the y ordinate, CoodinateSequence.Z the z ordinate,
* and CoodinateSequence.M the m ordinate. Note that the dimension may not
* imply the desired ordinate in the case where one is using a 2 dimensional
* geometry with a measure value. Therefore, these constants are highly
* recommended.
*
* @param ordinateIndex
* the desired ordinate index.
* @return the value of stored in the ordinate index. Incorrect or unused
* indexes shall return Double.NaN
*/
public double getOrdinate(int ordinateIndex) {
switch (ordinateIndex) {
case CoordinateSequence.X:
return this.x;
case CoordinateSequence.Y:
return this.y;
case CoordinateSequence.Z:
return this.z;
case CoordinateSequence.M:
return this.m;
}
return Double.NaN;
}
 
/**
* TODO: I'd like to see this method added to the base Coordinate class Sets
* the value for a given ordinate. This should be specified using the
* CoordinateSequence ordinate index constants.
*
* @param ordinateIndex
* the desired ordinate index.
* @param value
* the new ordinate value
* @throws IllegalArgumentException
* if the ordinateIndex value is incorrect
* @see #getOrdinate(int)
*/
public void setOrdinate(int ordinateIndex, double value) {
switch (ordinateIndex) {
case CoordinateSequence.X:
this.x = value;
break;
case CoordinateSequence.Y:
this.y = value;
break;
case CoordinateSequence.Z:
this.z = value;
break;
case CoordinateSequence.M:
this.m = value;
break;
default:
throw new IllegalArgumentException("invalid ordinateIndex");
}
}
 
public boolean equals2DWithMeasure(Coordinate other) {
boolean result = this.equals2D(other);
if (result) {
MCoordinate mc = convertCoordinate(other);
result = (Double.compare(this.m, mc.m) == 0);
}
return result;
}
 
public boolean equals3DWithMeasure(Coordinate other) {
boolean result = this.equals3D(other);
if (result) {
MCoordinate mc = convertCoordinate(other);
result = (Double.compare(this.m, mc.m) == 0);
}
return result;
}
 
/*
* Default equality is now equality in 2D-plane. This is required to remain
* consistent with JTS.
*
* TODO:check whether this method is still needed.
*
* (non-Javadoc)
*
* @see com.vividsolutions.jts.geom.Coordinate#equals(java.lang.Object)
*/
public boolean equals(Object other) {
if (other instanceof Coordinate) {
return equals2D((Coordinate) other);
} else {
return false;
}
}
 
public String toString() {
return "(" + x + "," + y + "," + z + "," + " m=" + m + ")";
}
 
/**
* Converts a standard Coordinate instance to an MCoordinate instance. If
* coordinate is already an instance of an MCoordinate, then it is simply
* returned. In cases where it is converted, the measure value of the
* coordinate is initialized to Double.NaN.
*
* @param coordinate
* The coordinate to be converted
* @return an instance of MCoordinate corresponding to the
* <code>coordinate</code> parameter
*/
public static MCoordinate convertCoordinate(Coordinate coordinate) {
if (coordinate == null)
return null;
if (coordinate instanceof MCoordinate)
return (MCoordinate) coordinate;
return new MCoordinate(coordinate);
}
 
/**
* A convenience method for creating a MCoordinate instance where there are
* only 2 coordinates and an lrs measure value. The z value of the
* coordinate shall be set to Double.NaN
*
* @param x
* the x coordinate value
* @param y
* the y coordinate value
* @param m
* the lrs measure value
* @return The constructed MCoordinate value
*/
public static MCoordinate create2dWithMeasure(double x, double y, double m) {
return new MCoordinate(x, y, Double.NaN, m);
}
 
/**
* A convenience method for creating a MCoordinate instance where there are
* only 2 coordinates and an lrs measure value. The z and m value of the
* coordinate shall be set to Double.NaN
*
* @param x
* the x coordinate value
* @param y
* the y coordinate value
* @return The constructed MCoordinate value
*/
public static MCoordinate create2d(double x, double y) {
return new MCoordinate(x, y, Double.NaN, Double.NaN);
}
 
/**
* A convenience method for creating a MCoordinate instance where there are
* 3 coordinates and an lrs measure value.
*
* @param x
* the x coordinate value
* @param y
* the y coordinate value
* @param z
* the z coordinate value
* @param m
* the lrs measure value
* @return The constructed MCoordinate value
*/
public static MCoordinate create3dWithMeasure(double x, double y, double z,
double m) {
return new MCoordinate(x, y, z, m);
}
 
/**
* A convenience method for creating a MCoordinate instance where there are
* 3 coordinates but no lrs measure value. The m value of the coordinate
* shall be set to Double.NaN
*
* @param x
* the x coordinate value
* @param y
* the y coordinate value
* @param z
* the z coordinate value
* @return The constructed MCoordinate value
*/
public static MCoordinate create3d(double x, double y, double z) {
return new MCoordinate(x, y, z, Double.NaN);
}
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/EventLocator.java
New file
0,0 → 1,79
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
 
import java.util.ArrayList;
import java.util.List;
 
public class EventLocator {
 
/**
* Returns the point on the specified MGeometry where its measure equals the specified position.
*
* @return a Point Geometry
* @throws MGeometryException
*/
public static Point getPointGeometry(MGeometry lrs, double position)
throws MGeometryException {
if (lrs == null) {
throw new MGeometryException("Non-null MGeometry parameter is required.");
}
Coordinate c = lrs.getCoordinateAtM(position);
Point pnt = lrs.getFactory().createPoint(c);
copySRID(lrs.asGeometry(), pnt);
return pnt;
}
 
public static MultiMLineString getLinearGeometry(MGeometry lrs,
double begin, double end) throws MGeometryException {
 
if (lrs == null) {
throw new MGeometryException("Non-null MGeometry parameter is required.");
}
MGeometryFactory factory = (MGeometryFactory) lrs.getFactory();
CoordinateSequence[] cs = lrs.getCoordinatesBetween(begin, end);
List<MLineString> linestrings = new ArrayList<MLineString>(cs.length);
for (int i = 0; i < cs.length; i++) {
MLineString ml;
if (cs[i].size() >= 2) {
ml = factory.createMLineString(cs[i]);
linestrings.add(ml);
}
}
MultiMLineString result = factory.createMultiMLineString(linestrings.toArray(new MLineString[linestrings.size()]));
copySRID(lrs.asGeometry(), result.asGeometry());
return result;
}
 
public static void copySRID(Geometry source, Geometry target) {
target.setSRID(source.getSRID());
}
 
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinateSequenceFactory.java
New file
0,0 → 1,86
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import java.io.Serializable;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
 
/**
* Creates MCoordinateSequenceFactory internally represented as an array of
* {@link MCoordinate}s.
*/
public class MCoordinateSequenceFactory implements CoordinateSequenceFactory,
Serializable {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static MCoordinateSequenceFactory instance = new MCoordinateSequenceFactory();
 
private MCoordinateSequenceFactory() {
}
 
/**
* Returns the singleton instance of MCoordinateSequenceFactory
*/
public static MCoordinateSequenceFactory instance() {
return instance;
}
 
/**
* Returns an MCoordinateSequence based on the given array -- the array is
* used directly if it is an instance of MCoordinate[]; otherwise it is
* copied.
*/
public CoordinateSequence create(Coordinate[] coordinates) {
return coordinates instanceof MCoordinate[] ? new MCoordinateSequence(
(MCoordinate[]) coordinates) : new MCoordinateSequence(
coordinates);
}
 
public CoordinateSequence create(CoordinateSequence coordSeq) {
return new MCoordinateSequence(coordSeq);
}
 
/**
* Creates a MCoordinateSequence instance initialized to the size parameter.
* Note that the dimension argument is ignored.
*
* @see com.vividsolutions.jts.geom.CoordinateSequenceFactory#create(int,int)
*/
public CoordinateSequence create(int size, int dimension) {
return new MCoordinateSequence(size);
}
 
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MultiMLineString.java
New file
0,0 → 1,279
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.*;
 
public class MultiMLineString extends MultiLineString implements MGeometry {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private final double mGap; // difference in m between end of one part and
 
private boolean monotone = false;
 
private boolean strictMonotone = false;
 
/**
* @param MlineStrings the <code>MLineString</code>s for this
* <code>MultiMLineString</code>, or <code>null</code> or an
* empty array to create the empty geometry. Elements may be
* empty <code>LineString</code>s, but not <code>null</code>s.
*/
public MultiMLineString(MLineString[] MlineStrings, double mGap,
GeometryFactory factory) {
super(MlineStrings, factory);
this.mGap = mGap;
determineMonotone();
}
 
/**
* TODO Improve this, and add more unit tests
*/
private void determineMonotone() {
this.monotone = true;
this.strictMonotone = true;
if (this.isEmpty()) {
return;
}
int mdir = MGeometry.CONSTANT;
for (int i = 0; i < this.geometries.length; i++) {
MLineString ml = (MLineString) this.geometries[0];
if (!ml.isEmpty()) {
mdir = ml.getMeasureDirection();
break;
}
}
for (int i = 0; i < this.geometries.length; i++) {
MLineString ml = (MLineString) this.geometries[i];
if (ml.isEmpty()) continue;
// check whether mlinestrings are all pointing in same direction,
// and
// are monotone
if (!ml.isMonotone(false)
|| (ml.getMeasureDirection() != mdir && !(ml
.getMeasureDirection() == MGeometry.CONSTANT))) {
this.monotone = false;
break;
}
 
if (!ml.isMonotone(true) || (ml.getMeasureDirection() != mdir)) {
this.strictMonotone = false;
break;
}
 
// check whether the geometry measures do not overlap or
// are inconsistent with previous parts
if (i > 0) {
MLineString mlp = (MLineString) this.geometries[i - 1];
if (mdir == MGeometry.INCREASING) {
if (mlp.getMaxM() > ml.getMinM()) {
monotone = false;
} else if (mlp.getMaxM() >= ml.getMinM()) {
strictMonotone = false;
}
} else {
if (mlp.getMinM() < ml.getMaxM()) {
monotone = false;
} else if (mlp.getMinM() <= ml.getMaxM()) {
strictMonotone = false;
}
}
 
}
 
}
if (!monotone) {
this.strictMonotone = false;
}
 
}
 
protected void geometryChangedAction() {
determineMonotone();
}
 
public String getGeometryType() {
return "MultiMLineString";
}
 
public double getMGap() {
return this.mGap;
}
 
public double getMatCoordinate(Coordinate co, double tolerance)
throws MGeometryException {
 
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
 
double mval = Double.NaN;
double dist = Double.POSITIVE_INFINITY;
 
com.vividsolutions.jts.geom.Point p = this.getFactory().createPoint(co);
 
// find points within tolerance for getMatCoordinate
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
// go to next MLineString if the input point is beyond tolerance
if (ml.distance(p) > tolerance)
continue;
 
MCoordinate mc = ml.getClosestPoint(co, tolerance);
if (mc != null) {
double d = mc.distance(co);
if (d <= tolerance && d < dist) {
dist = d;
mval = mc.m;
}
}
}
return mval;
}
 
public Object clone() {
MultiLineString ml = (MultiLineString) super.clone();
return ml;
}
 
public void measureOnLength(boolean keepBeginMeasure) {
double startM = 0.0;
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
if (i == 0) {
ml.measureOnLength(keepBeginMeasure);
} else {
ml.measureOnLength(false);
}
if (startM != 0.0) {
ml.shiftMeasure(startM);
}
startM += ml.getLength() + mGap;
}
this.geometryChanged();
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#getCoordinateAtM(double)
*/
 
public Coordinate getCoordinateAtM(double m) throws MGeometryException {
 
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
 
Coordinate c = null;
for (int i = 0; i < this.getNumGeometries(); i++) {
MGeometry mg = (MGeometry) this.getGeometryN(i);
c = mg.getCoordinateAtM(m);
if (c != null) {
return c;
}
}
return null;
}
 
public CoordinateSequence[] getCoordinatesBetween(double begin, double end)
throws MGeometryException {
 
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE,
"Operation requires geometry with monotonic measures");
}
 
if (this.isEmpty())
return null;
 
java.util.ArrayList<CoordinateSequence> ar = new java.util.ArrayList<CoordinateSequence>();
 
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
for (CoordinateSequence cs : ml.getCoordinatesBetween(begin, end)) {
if (cs.size() > 0) {
ar.add(cs);
}
}
}
return ar.toArray(new CoordinateSequence[ar.size()]);
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#getMinM()
*/
 
public double getMinM() {
double minM = Double.POSITIVE_INFINITY;
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
double d = ml.getMinM();
if (d < minM)
minM = d;
}
return minM;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#getMaxM()
*/
 
public double getMaxM() {
double maxM = Double.NEGATIVE_INFINITY;
for (int i = 0; i < this.getNumGeometries(); i++) {
MLineString ml = (MLineString) this.getGeometryN(i);
double d = ml.getMaxM();
if (d > maxM)
maxM = d;
}
return maxM;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#isMonotone()
*/
 
public boolean isMonotone(boolean strictMonotone) {
return strictMonotone ? this.strictMonotone : monotone;
}
 
public Geometry asGeometry() {
return this;
}
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometryException.java
New file
0,0 → 1,71
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
/**
* @author Karel Maesen
*
*
*/
public class MGeometryException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
public final static int OPERATION_REQUIRES_MONOTONE = 1;
 
public final static int UNIONM_ON_DISJOINT_MLINESTRINGS = 2;
 
public final static int GENERAL_MGEOMETRY_EXCEPTION = 0;
 
// type of exception
private final int type;
 
public MGeometryException(String s) {
super(s);
type = 0;
}
 
public MGeometryException(int type) {
super();
this.type = type;
}
 
public MGeometryException(int type, String msg) {
super(msg);
this.type = type;
}
 
public int getType() {
return type;
}
 
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MGeometry.java
New file
0,0 → 1,187
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
 
import java.io.Serializable;
 
/**
* Defines geometries that carry measures in their CoordinateSequence.
*
* @author Karel Maesen
*/
 
public interface MGeometry extends Cloneable, Serializable {
 
/**
* Measures are increasing in the direction of the MGeometry
*/
public final static int INCREASING = 1;
 
/**
* Measures are constant across the Geometry
*/
public final static int CONSTANT = 0;
 
/**
* Measures are decreasing in the direction of the MGeometry
*/
public final static int DECREASING = -1;
 
/**
* Measures are not monotone along the Geometry
*/
public final static int NON_MONOTONE = -3;
 
/**
* Returns the measure value at the Coordinate
*
* @param c
* the Coordinate for which the measure value is sought
* @param tolerance
* distance to the MGeometry within which Coordinate c has to lie
* @return the measure value if Coordinate c is within tolerance of the
* Geometry, else Double.NaN
* <p>
* When the geometry is a ring or is self-intersecting more
* coordinates may be determined by one coordinate. In that case,
* the lowest measure is returned.
* @throws MGeometryException
* when this MGeometry is not monotone
*/
public double getMatCoordinate(Coordinate c, double tolerance)
throws MGeometryException;
 
/**
* Builds measures along the Geometry based on the length from the beginning
* (first coordinate) of the Geometry.
*
* @param keepBeginMeasure -
* if true, the measure of the first coordinate is maintained and
* used as start value, unless this measure is Double.NaN
*/
public void measureOnLength(boolean keepBeginMeasure);
 
/**
* Returns the Coordinate along the Geometry at the measure value
*
* @param m
* measure value
* @return the Coordinate if m is on the MGeometry otherwise null
* @throws MGeometryException
* when MGeometry is not monotone
*/
public Coordinate getCoordinateAtM(double m) throws MGeometryException;
 
/**
* Returns the coordinatesequence(s) containing all coordinates between the
* begin and end measures.
*
* @param begin
* begin measure
* @param end
* end measure
* @return an array containing all coordinatesequences in order between
* begin and end. Each CoordinateSequence covers a contiguous
* stretch of the MGeometry.
* @throws MGeometryException
* when this MGeometry is not monotone
*/
public CoordinateSequence[] getCoordinatesBetween(double begin, double end)
throws MGeometryException;
 
/**
* Returns the GeometryFactory of the MGeometry
*
* @return the GeometryFactory of this MGeometry
*/
public GeometryFactory getFactory();
 
/**
* Returns the minimum M-value of the MGeometry
*
* @return the minimum M-value
*/
public double getMinM();
 
/**
* Returns the maximum M-value of the MGeometry
*
* @return the maximum M-value
*/
public double getMaxM();
 
/**
* Determine whether the LRS measures (not the x,y,z coordinates) in the
* Coordinate sequence of the geometry is Monotone. Monotone implies that
* all measures in a sequence of coordinates are consecutively increasing,
* decreasing or equal according to the definition of the implementing
* geometry. Monotonicity is a pre-condition for most operations on
* MGeometries. The following are examples on Monotone measure sequences on
* a line string:
* <ul>
* <li> [0,1,2,3,4] - Monotone Increasing
* <li> [4,3,2,1] - Monotone Decreasing
* <li> [0,1,1,2,3] - Non-strict Monotone Increasing
* <li> [5,3,3,0] - Non-strict Monotone Decreasing
* </ul>
*
* @return true if the coordinates in the CoordinateSequence of the geometry
* are monotone.
*/
public boolean isMonotone(boolean strict);
 
// /**
// * Strict Monotone is similar to Monotone, with the added constraint that
// all measure coordinates
// * in the CoordinateSequence are ONLY consecutively increasing or
// decreasing. No consecutive
// * duplicate measures are allowed.
// *
// * @return true if the coordinates in the CoordinateSequence of the
// geometry are strictly monotone; that is, consitently
// * increasing or decreasing with no duplicate measures.
// * @see #isMonotone()
// */
// public boolean isStrictMonotone();
 
/**
* Returns this <code>MGeometry</code> as a <code>Geometry</code>.
*
* Modifying the returned <code>Geometry</code> will result in internal state changes.
*
* @return this object as a Geometry.
*/
public Geometry asGeometry();
 
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MLineString.java
New file
0,0 → 1,685
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.*;
 
import java.util.*;
 
/**
* An implementation of the LineString class with the addition that the
* containing CoordinateSequence can carry measure. Note that this is not a
* strict requirement of the class, and can interact with non-measure geometries
* for JTS topological comparisons regardless.
*
* @author Karel Maesen
*/
public class MLineString extends LineString implements MGeometry {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private boolean monotone = false;
 
private boolean strictMonotone = false;
 
public MLineString(CoordinateSequence points, GeometryFactory factory) {
super(points, factory);
determineMonotone();
}
 
public Object clone() {
LineString ls = (LineString) super.clone();
return new MLineString(ls.getCoordinateSequence(), this.getFactory());
}
 
/**
* Calculates whether the measures in the CoordinateSequence are monotone
* and strict monotone. The strict parameter indicates whether the
* determination should apply the definition of "strict monotonicity" or
* non-strict.
*/
private void determineMonotone() {
this.monotone = true;
this.strictMonotone = true;
if (!this.isEmpty()) {
double m[] = this.getMeasures();
// short circuit if the first value is NaN
if (Double.isNaN(m[0])) {
this.monotone = false;
this.strictMonotone = false;
} else {
int result = 0;
int prevResult = 0;
for (int i = 1; i < m.length && this.monotone; i++) {
result = Double.compare(m[i - 1], m[i]);
this.monotone = !(result * prevResult < 0 || Double
.isNaN(m[i]));
this.strictMonotone &= this.monotone && result != 0;
prevResult = result;
}
}
}
// if not monotone, then certainly not strictly monotone
assert (!(this.strictMonotone && !this.monotone));
}
 
protected void geometryChangedAction() {
determineMonotone();
}
 
/**
* @param co
* input coordinate in the neighbourhood of the MLineString
* @param tolerance
* max. distance that co may be from this MLineString
* @return an MCoordinate on this MLineString with appropriate M-value
*/
public MCoordinate getClosestPoint(Coordinate co, double tolerance)
throws MGeometryException {
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
 
if (!this.isEmpty()) {
LineSegment seg = new LineSegment();
Coordinate[] coAr = this.getCoordinates();
seg.p0 = coAr[0];
double d = 0.0;
double projfact = 0.0;
double minDist = Double.POSITIVE_INFINITY;
MCoordinate mincp = null;
for (int i = 1; i < coAr.length; i++) {
seg.p1 = coAr[i];
Coordinate cp = seg.closestPoint(co);
d = cp.distance(co);
if (d <= tolerance && d <= minDist) {
MCoordinate testcp = new MCoordinate(cp);
projfact = seg.projectionFactor(cp);
testcp.m = ((MCoordinate) coAr[i - 1]).m
+ projfact
* (((MCoordinate) coAr[i]).m - ((MCoordinate) coAr[i - 1]).m);
if (d < minDist || testcp.m < mincp.m) {
mincp = testcp;
minDist = d;
}
}
seg.p0 = seg.p1;
}
if (minDist > tolerance) {
return null;
} else {
return mincp;
}
} else {
return null;
}
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry#getCoordinateAtM(double)
*/
public Coordinate getCoordinateAtM(double m) throws MGeometryException {
if (!this.isMonotone(false)) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE);
}
if (this.isEmpty()) {
return null;
} else {
double mval[] = this.getMeasures();
double lb = getMinM();
double up = getMaxM();
 
if (m < lb || m > up) {
return null;
} else {
// determine linesegment that contains m;
for (int i = 1; i < mval.length; i++) {
if ((mval[i - 1] <= m && m <= mval[i])
|| (mval[i] <= m && m <= mval[i - 1])) {
MCoordinate p0 = (MCoordinate) this
.getCoordinateN(i - 1);
MCoordinate p1 = (MCoordinate) this.getCoordinateN(i);
// r indicates how far in this segment the M-values lies
double r = (m - mval[i - 1]) / (mval[i] - mval[i - 1]);
double dx = r * (p1.x - p0.x);
double dy = r * (p1.y - p0.y);
double dz = r * (p1.z - p0.z);
MCoordinate nc = new MCoordinate(p0.x + dx, p0.y + dy,
p0.z + dz, m);
return nc;
}
}
}
}
return null;
}
 
/*
* (non-Javadoc)
*
* @see com.vividsolutions.jts.geom.Geometry#getGeometryType()
*/
public String getGeometryType() {
return "MLineString";
}
 
/*
* (non-Javadoc)
*
* @see com.vividsolutions.jts.geom.Geometry#getMatCoordinate(com.vividsolutions.jts.geom.Coordinate,
* double)
*/
public double getMatCoordinate(Coordinate c, double tolerance)
throws MGeometryException {
MCoordinate mco = this.getClosestPoint(c, tolerance);
if (mco == null) {
return Double.NaN;
} else {
return (mco.m);
}
}
 
/**
* get the measure of the specified coordinate
*
* @param n
* index of the coordinate
* @return The measure of the coordinate. If the coordinate does not exists
* it returns Double.NaN
*/
public double getMatN(int n) {
return ((MCoordinate) (this.getCoordinates()[n])).m;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernatespatial.mgeom.MGeometry##MGeometry#getMaxM()
*/
public double getMaxM() {
if (this.isEmpty()) {
return Double.NaN;
} else {
double[] measures = this.getMeasures();
 
if (this.getMeasureDirection() == MGeometry.INCREASING) {
return measures[measures.length - 1];
} else if (this.getMeasureDirection() == MGeometry.DECREASING
|| this.getMeasureDirection() == MGeometry.CONSTANT) {
return measures[0];
} else {
double ma = Double.NEGATIVE_INFINITY;
for (int i = 0; i < measures.length; i++) {
if (ma < measures[i]) {
ma = measures[i];
}
}
return ma;
}
}
}
 
 
/**
* Copies the coordinates of the specified array that fall between fromM and toM to a CoordinateSubSequence.
*
* 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/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/mgeom/MCoordinateSequence.java
New file
0,0 → 1,232
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.mgeom;
 
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
 
import java.io.Serializable;
 
/**
* Implements the CoordinateSequence interface. In this implementation,
* Coordinates returned by #toArray and #get are live -- parties that change
* them are actually changing the MCoordinateSequence's underlying data.
*/
public class MCoordinateSequence implements CoordinateSequence, Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
 
private MCoordinate[] coordinates;
 
public static MCoordinate[] copy(Coordinate[] coordinates) {
MCoordinate[] copy = new MCoordinate[coordinates.length];
for (int i = 0; i < coordinates.length; i++) {
copy[i] = new MCoordinate(coordinates[i]);
}
return copy;
}
 
public static MCoordinate[] copy(CoordinateSequence coordSeq) {
MCoordinate[] copy = new MCoordinate[coordSeq.size()];
for (int i = 0; i < coordSeq.size(); i++) {
copy[i] = new MCoordinate(coordSeq.getCoordinate(i));
}
return copy;
}
 
/**
* Copy constructor -- simply aliases the input array, for better
* performance.
*
* @param coordinates
*/
public MCoordinateSequence(MCoordinate[] coordinates) {
this.coordinates = coordinates;
}
 
/**
* Constructor that makes a copy of an array of Coordinates. Always makes a
* copy of the input array, since the actual class of the Coordinates in the
* input array may be different from MCoordinate.
*
* @param copyCoords
*/
public MCoordinateSequence(Coordinate[] copyCoords) {
coordinates = copy(copyCoords);
}
 
/**
* Constructor that makes a copy of a CoordinateSequence.
*
* @param coordSeq
*/
public MCoordinateSequence(CoordinateSequence coordSeq) {
coordinates = copy(coordSeq);
}
 
/**
* Constructs a sequence of a given size, populated with new
* {@link MCoordinate}s.
*
* @param size
* the size of the sequence to create
*/
public MCoordinateSequence(int size) {
coordinates = new MCoordinate[size];
for (int i = 0; i < size; i++) {
coordinates[i] = new MCoordinate();
}
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getDimension()
*/
public int getDimension() {
return 4;
}
 
public Coordinate getCoordinate(int i) {
return coordinates[i];
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getCoordinateCopy(int)
*/
public Coordinate getCoordinateCopy(int index) {
return new Coordinate(coordinates[index]);
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getCoordinate(int,
* com.vividsolutions.jts.geom.Coordinate)
*/
public void getCoordinate(int index, Coordinate coord) {
coord.x = coordinates[index].x;
coord.y = coordinates[index].y;
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getX(int)
*/
public double getX(int index) {
return coordinates[index].x;
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getY(int)
*/
public double getY(int index) {
return coordinates[index].y;
}
 
/**
* @return the measure value of the coordinate in the index
*/
public double getM(int index) {
return coordinates[index].m;
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#getOrdinate(int,int)
*/
public double getOrdinate(int index, int ordinateIndex) {
switch (ordinateIndex) {
case CoordinateSequence.X:
return coordinates[index].x;
case CoordinateSequence.Y:
return coordinates[index].y;
case CoordinateSequence.Z:
return coordinates[index].z;
case CoordinateSequence.M:
return coordinates[index].m;
}
return Double.NaN;
}
 
/**
* @see com.vividsolutions.jts.geom.CoordinateSequence#setOrdinate(int,int,double)
*/
public void setOrdinate(int index, int ordinateIndex, double value) {
switch (ordinateIndex) {
case CoordinateSequence.X:
coordinates[index].x = value;
break;
case CoordinateSequence.Y:
coordinates[index].y = value;
break;
case CoordinateSequence.Z:
coordinates[index].z = value;
break;
case CoordinateSequence.M:
coordinates[index].m = value;
break;
default:
throw new IllegalArgumentException("invalid ordinateIndex");
}
}
 
public Object clone() {
MCoordinate[] cloneCoordinates = new MCoordinate[size()];
for (int i = 0; i < coordinates.length; i++) {
cloneCoordinates[i] = (MCoordinate) coordinates[i].clone();
}
 
return new MCoordinateSequence(cloneCoordinates);
}
 
public int size() {
return coordinates.length;
}
 
public Coordinate[] toCoordinateArray() {
return coordinates;
}
 
public Envelope expandEnvelope(Envelope env) {
for (int i = 0; i < coordinates.length; i++) {
env.expandToInclude(coordinates[i]);
}
return env;
}
 
public String toString() {
StringBuffer strBuf = new StringBuffer();
strBuf.append("MCoordinateSequence [");
for (int i = 0; i < coordinates.length; i++) {
if (i > 0)
strBuf.append(", ");
strBuf.append(coordinates[i]);
}
strBuf.append("]");
return strBuf.toString();
}
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/AbstractDBGeometryType.java
New file
0,0 → 1,214
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
 
import org.hibernate.HibernateException;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
import org.hibernatespatial.cfg.GeometryFactoryHelper;
import org.hibernatespatial.mgeom.MGeometryFactory;
 
import com.vividsolutions.jts.geom.Geometry;
 
/**
* This type is a abstract base type for implementing database specific user
* types for geometry types.
*
* @author Karel Maesen
*/
public abstract class AbstractDBGeometryType implements UserType,
ParameterizedType, Serializable {
private MGeometryFactory geomFactory = null;
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#assemble(java.io.Serializable,
* java.lang.Object)
*/
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object value) throws HibernateException {
return value;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
*/
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#equals(java.lang.Object,
* java.lang.Object)
*/
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (x == null || y == null)
return false;
return ((Geometry) x).equalsExact((Geometry) y);
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
*/
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#isMutable()
*/
public boolean isMutable() {
return false;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,
* java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
Object geomObj = rs.getObject(names[0]);
return convert2JTS(geomObj);
}
 
/**
* Converts the native database geometry object to a JTS Geometry object.
*
* Concrete subclasses should override this method.
*
* @param geomObj
* native database geometry object
* @return JTS Geometry
*/
public abstract Geometry convert2JTS(Object geomObj);
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
* java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, sqlTypes()[0]);
} else {
Geometry jtsGeom = (Geometry) value;
Object dbGeom = conv2DBGeometry(jtsGeom, st.getConnection());
st.setObject(index, dbGeom);
}
}
 
/**
* Converts a JTS geometry object to a native database geometry object.
*
* Concrete subclasses should override this method.
*
* @param jtsGeom
* JTS Geometry
* @return native database geometry object
*/
public abstract Object conv2DBGeometry(Geometry jtsGeom,
Connection connection);
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#replace(java.lang.Object,
* java.lang.Object, java.lang.Object)
*/
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#returnedClass()
*/
public Class returnedClass() {
return Geometry.class;
}
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.UserType#sqlTypes()
*
* This should be overriden by concrete subclasses
*/
public abstract int[] sqlTypes();
 
/*
* (non-Javadoc)
*
* @see org.hibernate.usertype.ParameterizedType#setParameterValues(java.util.Properties)
*/
public void setParameterValues(Properties parameters) {
if (parameters != null){
this.geomFactory = GeometryFactoryHelper.createGeometryFactory(parameters);
}
}
public MGeometryFactory getGeometryFactory(){
return (this.geomFactory == null) ? HBSpatialExtension.getDefaultGeomFactory() : this.geomFactory;
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/AttributeInfo.java
New file
0,0 → 1,121
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import javassist.CtClass;
 
import org.hibernatespatial.GeometryUserType;
 
/**
* @author Karel Maesen
*
*
*/
public class AttributeInfo {
 
private String columnName;
 
private String fieldName;
 
private String hibernateType;
private CtClass ctClass;
 
private boolean isIdentifier;
 
public boolean isGeometry() {
return this.hibernateType.equalsIgnoreCase(GeometryUserType.class
.getCanonicalName());
}
 
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((columnName == null) ? 0 : columnName.hashCode());
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AttributeInfo other = (AttributeInfo) obj;
if (columnName == null) {
if (other.columnName != null)
return false;
} else if (!columnName.equals(other.columnName))
return false;
return true;
}
 
public CtClass getCtClass() {
return ctClass;
}
 
public void setCtClass(CtClass ctType) {
this.ctClass = ctType;
}
 
public String getColumnName() {
return columnName;
}
 
public void setColumnName(String columnName) {
this.columnName = columnName;
}
 
public String getFieldName() {
return fieldName;
}
 
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
 
public String getHibernateType() {
return hibernateType;
}
 
public void setHibernateType(String hibernateType) {
this.hibernateType = hibernateType;
}
 
public boolean isIdentifier() {
return isIdentifier;
}
 
public void setIdentifier(boolean isIdentifier) {
this.isIdentifier = isIdentifier;
}
 
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/FeatureMapper.java
New file
0,0 → 1,149
package org.hibernatespatial.pojo;
 
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
 
public class FeatureMapper {
 
private final NamingStrategy naming;
private final TypeMapper typeMapper;
 
public FeatureMapper(NamingStrategy naming, TypeMapper typeMapper) {
this.naming = naming;
this.typeMapper = typeMapper;
}
 
public ClassInfo createClassInfo(String catalog, String schema, String tableName, DatabaseMetaData dmd) throws TableNotFoundException, MissingIdentifierException {
String className = naming.createClassName(tableName);
ClassInfo cInfo = new ClassInfo(tableName, className);
readColums(catalog, schema, tableName, dmd, cInfo);
determineIdentifier(catalog, schema, tableName, dmd, cInfo);
return cInfo;
}
 
private void determineIdentifier(String catalog, String schema, String tableName, DatabaseMetaData dmd, ClassInfo cInfo) throws MissingIdentifierException {
String pkn = null;
pkn = determinePrimaryKey(catalog, schema, tableName, dmd);
if (pkn == null) {
pkn = findUniqueIndex(catalog, schema, tableName, dmd);
}
if (pkn == null) throw new MissingIdentifierException(tableName);
setAsIdentifier(cInfo, pkn);
return;
 
}
 
private String findUniqueIndex(String catalog, String schema, String tableName, DatabaseMetaData dmd) {
Map<String, String> indexes = new HashMap<String,String>();
Set<String> rejectedIndexes = new HashSet<String>();
readUniqueIndexes(catalog, schema, tableName, dmd, indexes, rejectedIndexes);
for (String candidate : indexes.keySet()){
if (!rejectedIndexes.contains(candidate)) return indexes.get(candidate);
}
return null;
}
 
private void readUniqueIndexes(String catalog, String schema, String tableName, DatabaseMetaData dmd, Map<String, String> indexes, Set<String> rejectedIndexes) {
ResultSet rs = null;
try {
rs = dmd.getIndexInfo(catalog, schema, tableName, true, false);
while(rs.next()){
String colName = rs.getString("COLUMN_NAME");
String indexName = rs.getString("INDEX_NAME");
if (indexName == null){
indexName = colName;
}
if (indexes.get(indexName) != null){
rejectedIndexes.add(indexName);
} else {
indexes.put(indexName, colName);
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
rs.close();
} catch (SQLException e) {
//do nothing
}
}
}
 
private String determinePrimaryKey(String catalog, String schema, String tableName, DatabaseMetaData dmd) {
String pkn = null;
ResultSet rs = null;
try {
rs = dmd.getPrimaryKeys(catalog, schema, tableName);
if(!rs.next()) return null;
pkn = rs.getString("COLUMN_NAME");
//check whether the primary key is non-composite
if (rs.next()) return null;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
rs.close();
} catch (SQLException e) {
//do nothing
}
}
return pkn;
}
 
private void readColums(String catalog, String schema, String tableName, DatabaseMetaData dmd, ClassInfo cInfo) throws TableNotFoundException {
ResultSet rs = null;
boolean empty = true;
try {
rs = dmd.getColumns(catalog, schema, tableName, null);
while (rs.next()) {
empty = false;
String colName = rs.getString("COLUMN_NAME");
String dbType = rs.getString("TYPE_NAME");
int javaType = rs.getInt("DATA_TYPE");
addAttribute(cInfo, colName, dbType, javaType);
}
} catch (SQLException ex) {
throw new RuntimeException(ex);
} finally {
try {
rs.close();
} catch (SQLException e) {
// do nothing
}
}
if (empty) {
throw new TableNotFoundException(tableName);
}
}
 
private void setAsIdentifier(ClassInfo cInfo, String pkn) {
for (AttributeInfo ai : cInfo.getAttributes()) {
if (ai.getColumnName().equals(pkn)) {
ai.setIdentifier(true);
break;
}
}
}
 
private void addAttribute(ClassInfo cInfo, String colName, String dbType, int javaType) {
String hibernateType = null;
try {
hibernateType = typeMapper.getHibernateType(dbType, javaType);
} catch (TypeNotFoundException e) {
 
}
AttributeInfo ai = new AttributeInfo();
ai.setColumnName(colName);
ai.setFieldName(naming.createPropertyName(colName));
ai.setHibernateType(hibernateType);
ai.setCtClass(typeMapper.getCtClass(dbType, javaType));
cInfo.addAttribute(ai);
}
 
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/ClassInfo.java
New file
0,0 → 1,125
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import java.util.ArrayList;
import java.util.List;
 
public class ClassInfo {
 
private final String className;
 
private final String tableName;
 
private final List<AttributeInfo> attributes = new ArrayList<AttributeInfo>();
 
public ClassInfo(String tableName, String className) {
this.className = className;
this.tableName = tableName;
}
 
public AttributeInfo getIdAttribute() throws MissingIdentifierException {
for (AttributeInfo ai : getAttributes()) {
if (ai.isIdentifier()) {
return ai;
}
}
throw new MissingIdentifierException();
}
 
public AttributeInfo getGeomAttribute() throws GeometryNotFoundException {
for (AttributeInfo ai : getAttributes()) {
if (ai.isGeometry()) {
return ai;
}
}
throw new GeometryNotFoundException();
}
 
public List<AttributeInfo> getAttributes() {
return attributes;
}
 
public String getClassName() {
return className;
}
 
public String getTableName() {
return tableName;
}
 
public void addAttribute(AttributeInfo ai) {
this.attributes.add(ai);
}
 
public void removeAttribute(AttributeInfo ai) {
this.attributes.remove(ai);
}
 
public void clearAttributes() {
this.attributes.clear();
}
 
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result
+ ((attributes == null) ? 0 : attributes.hashCode());
result = PRIME * result
+ ((className == null) ? 0 : className.hashCode());
result = PRIME * result
+ ((tableName == null) ? 0 : tableName.hashCode());
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final ClassInfo other = (ClassInfo) obj;
if (attributes == null) {
if (other.attributes != null)
return false;
} else if (!attributes.equals(other.attributes))
return false;
if (className == null) {
if (other.className != null)
return false;
} else if (!className.equals(other.className))
return false;
if (tableName == null) {
if (other.tableName != null)
return false;
} else if (!tableName.equals(other.tableName))
return false;
return true;
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/TableNotFoundException.java
New file
0,0 → 1,58
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* This Exception is thrown when the POJO Utility cannot locate a primary key.
*
* @author Karel Maesen, Geovise BVBA
*
*/
public class TableNotFoundException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static final String basemsg = "Table not found";
 
public TableNotFoundException() {
super(basemsg);
}
 
public TableNotFoundException(String msg) {
super(basemsg + ": " + msg);
}
 
public TableNotFoundException(Throwable cause) {
super(cause);
}
 
public TableNotFoundException(String msg, Throwable cause) {
super(basemsg + ": " + msg, cause);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/MappingsGenerator.java
New file
0,0 → 1,107
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
 
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
 
/**
* This class creates a Hibernate mapping file for a list of tables.
*
* @author Karel Maesen, Geovise BVBA (http://www.geovise.com/)
*/
public class MappingsGenerator {
 
private Document mappingDoc;
 
private String packageName;
 
public MappingsGenerator(String packageName) {
this.packageName = packageName;
}
 
public void write(Writer writer) throws IOException {
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(writer, format);
xmlWriter.write(this.mappingDoc);
xmlWriter.close();
}
 
public Document getMappingsDoc() {
return this.mappingDoc;
}
 
public void load(Collection<ClassInfo> mappedClasses, String schema)
throws MissingIdentifierException {
 
this.mappingDoc = DocumentHelper.createDocument();
this.mappingDoc.addDocType("hibernate-mapping",
"-//Hibernate/Hibernate Mapping DTD 3.0//EN",
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd");
Element root = this.mappingDoc.addElement("hibernate-mapping");
root.addAttribute("package", this.packageName);
if (schema != null){
root.addAttribute("schema", schema);
}
for (ClassInfo classInfo: mappedClasses) {
addTableElement(root, classInfo);
}
}
 
private void addTableElement(Element root, ClassInfo classInfo)
throws MissingIdentifierException {
Element tableEl = root.addElement("class");
tableEl.addAttribute("name", classInfo.getClassName());
tableEl.addAttribute("table", classInfo.getTableName());
AttributeInfo idAttr = classInfo.getIdAttribute();
addColElement(tableEl, idAttr);
for (AttributeInfo ai : classInfo.getAttributes()) {
if (!ai.isIdentifier()) {
addColElement(tableEl, ai);
}
}
 
}
 
private void addColElement(Element tableEl, AttributeInfo ai) {
Element colEl = null;
if (ai.isIdentifier()) {
colEl = tableEl.addElement("id");
} else {
colEl = tableEl.addElement("property");
}
colEl.addAttribute("name", ai.getFieldName());
colEl.addAttribute("column", ai.getColumnName());
colEl.addAttribute("type", ai.getHibernateType());
return;
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/SimpleNamingStrategy.java
New file
0,0 → 1,93
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* This is the default implementation for a <code>NamingStrategy</code>.
*
* @author Karel Maesen, Geovise BVBA (http://www.geovise.com/)
*/
public class SimpleNamingStrategy implements NamingStrategy {
 
public String createClassName(String base) {
String cleaned = toJavaName(base);
cleaned = cleaned.toLowerCase();
return capitalize(cleaned);
}
 
public String createGetterName(String fieldName) {
return "get" + capitalize(fieldName);
}
 
public String createPropertyName(String base) {
String cleaned = toJavaName(base);
cleaned = cleaned.toLowerCase();
return cleaned;
}
 
public String createSetterName(String fieldName) {
return "set" + capitalize(fieldName);
 
}
 
/**
*
* Turns the name into a valid, simplified Java Identifier.
*
* @param name
* @return
*/
private String toJavaName(String name) {
StringBuilder stb = new StringBuilder();
char[] namechars = name.toCharArray();
if (!Character.isJavaIdentifierStart(namechars[0])) {
stb.append("__");
} else {
stb.append(namechars[0]);
}
for (int i = 1; i < namechars.length; i++) {
if (!Character.isJavaIdentifierPart(namechars[i])) {
stb.append("__");
} else {
stb.append(namechars[i]);
}
}
 
return stb.toString();
}
 
private String capitalize(String s) {
char[] ca = s.toCharArray();
ca[0] = Character.toUpperCase(ca[0]);
return new String(ca);
}
 
@SuppressWarnings("unused")
private String uncapitalize(final String s) {
final char[] ca = s.toCharArray();
ca[0] = Character.toLowerCase(ca[0]);
return new String(ca);
}
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/TypeMapper.java
New file
0,0 → 1,185
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import org.hibernatespatial.GeometryUserType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
 
/**
* The <code>TypeMapper</code> maps a pair consisting of java.sql.Type, and a
* database type name to a CtClass (a representation of a java type used by the
* javassist class building tools) and to a Hibernate type (used when creating a
* mapping file).
*
* @author Karel Maesen, Geovise BVBA (http://www.geovise.com/)
*/
public class TypeMapper {
 
protected final static Logger logger = LoggerFactory.getLogger(TypeMapper.class);
 
private final static String GEOMETRY_USER_TYPE = GeometryUserType.class
.getCanonicalName();
 
private List<TMEntry> entries = new ArrayList<TMEntry>();
 
private String dbGeomType = "";
 
private CtClass ctGeom;
 
// TODO -- create entires for all constants defined in java.sql.Types
public TypeMapper(String dbGeomType) {
 
// first set the type to use for the geometry
this.dbGeomType = dbGeomType;
 
ClassPool pool = ClassPool.getDefault();
// ensure that we can load the JTS classes.
pool.insertClassPath(new ClassClassPath(this.getClass()));
 
CtClass ctString;
CtClass ctDate;
CtClass ctInteger;
CtClass ctBoolean;
CtClass ctFloat;
CtClass ctDouble;
CtClass ctLong;
CtClass ctShort;
CtClass ctBigDecimal;
CtClass ctByte;
CtClass ctBinary;
try {
ctString = pool.get("java.lang.String");
ctDate = pool.get("java.util.Date");
ctGeom = pool.get("com.vividsolutions.jts.geom.Geometry");
ctInteger = pool.get("java.lang.Integer");
ctBoolean = pool.get("java.lang.Boolean");
ctDouble = pool.get("java.lang.Double");
ctLong = pool.get("java.lang.Long");
ctShort = pool.get("java.lang.Short");
ctFloat = pool.get("java.lang.Float");
ctBigDecimal = pool.get("java.math.BigDecimal");
ctByte = pool.get("java.lang.Byte");
ctBinary = pool.get("byte[]");
} catch (NotFoundException e) {
throw new RuntimeException(e);
}
 
 
entries.add(new TMEntry(Types.BIGINT, "integer", ctInteger));
entries.add(new TMEntry(Types.SMALLINT, "short", ctShort));
entries.add(new TMEntry(Types.TINYINT, "byte", ctByte));
entries.add(new TMEntry(Types.BOOLEAN, "boolean", ctBoolean));
entries.add(new TMEntry(Types.BIT, "boolean", ctBoolean));
entries.add(new TMEntry(Types.CHAR, "string", ctString));
entries.add(new TMEntry(Types.DATE, "date", ctDate));
entries.add(new TMEntry(Types.TIMESTAMP, "timestamp", ctDate));
entries.add(new TMEntry(Types.TIME, "time", ctDate));
entries.add(new TMEntry(Types.DECIMAL, "big_decimal", ctBigDecimal));
entries.add(new TMEntry(Types.DOUBLE, "double", ctDouble));
entries.add(new TMEntry(Types.NUMERIC, "big_decimal", ctBigDecimal));
entries.add(new TMEntry(Types.FLOAT, "float", ctFloat));
entries.add(new TMEntry(Types.INTEGER, "integer", ctInteger));
entries.add(new TMEntry(Types.BIGINT, "long", ctLong));
entries.add(new TMEntry(Types.VARCHAR, "string", ctString));
entries.add(new TMEntry(Types.BINARY, "binary", ctBinary));
entries.add(new TMEntry(Types.CLOB, "text", ctString));
}
 
public CtClass getCtClass(String dbType, int sqlType) {
if (dbType.equalsIgnoreCase(this.dbGeomType)) {
return this.ctGeom;
}
for (TMEntry entry : entries) {
if (entry.javaType == sqlType) {
return entry.ctClass;
}
}
return null;
}
 
public String getHibernateType(String dbType, int sqlType) throws TypeNotFoundException {
if (dbType.equalsIgnoreCase(this.dbGeomType)) {
return GEOMETRY_USER_TYPE;
}
for (TMEntry entry : entries) {
if (entry.javaType == sqlType) {
return entry.hibernateTypeName;
}
}
throw new TypeNotFoundException(dbType);
 
}
 
public int[] getMappedSQLTypes() {
int l = this.entries.size();
int[] types = new int[l];
for (int i = 0; i < this.entries.size(); i++) {
types[i] = this.entries.get(i).javaType;
}
return types;
}
 
public void addTypeMapping(int sqlType, String hibernateType,
CtClass ctClass) {
this.entries.add(new TMEntry(sqlType, hibernateType, ctClass));
}
 
public void removeTypeMapping(int sqlType) {
TMEntry tm = null;
for (TMEntry t : this.entries) {
if (t.javaType == sqlType) {
tm = t;
break;
}
}
if (tm != null) {
this.entries.remove(tm);
}
}
 
private static class TMEntry {
protected int javaType = 0;
 
protected String hibernateTypeName = "";
 
protected CtClass ctClass;
 
protected TMEntry(int jt, String ht, CtClass jc) {
this.javaType = jt;
this.hibernateTypeName = ht;
this.ctClass = jc;
}
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/GeometryNotFoundException.java
New file
0,0 → 1,59
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* This Exception is thrown when the POJO Utility cannot locate a
* Geometry-valued attribute.
*
* @author Karel Maesen, Geovise BVBA
*
*/
public class GeometryNotFoundException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static final String basemsg = "No Geometry found.";
 
public GeometryNotFoundException() {
super(basemsg);
}
 
public GeometryNotFoundException(String msg) {
super(basemsg + ":" + msg);
}
 
public GeometryNotFoundException(Throwable cause) {
super(cause);
}
 
public GeometryNotFoundException(String msg, Throwable cause) {
super(basemsg + ":" + msg, cause);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/FeatureClassGenerator.java
New file
0,0 → 1,65
package org.hibernatespatial.pojo;
 
import java.security.ProtectionDomain;
 
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
 
public class FeatureClassGenerator {
 
private final String packageName;
private final NamingStrategy naming;
private final static ClassPool pool = ClassPool.getDefault();
 
public FeatureClassGenerator(String packageName, NamingStrategy naming) {
this.packageName = packageName;
this.naming = naming;
}
 
public Class<?> generate(ClassInfo classInfo) {
 
try {
String classname = packageName + "." + classInfo.getClassName();
CtClass pojo = pool.makeClass(classname);
for (AttributeInfo ai : classInfo.getAttributes()) {
CtField field = createField(ai, pojo);
CtMethod getter = createGetterMethod(field);
CtMethod setter = createSetterMethod(field);
pojo.addField(field);
pojo.addMethod(getter);
pojo.addMethod(setter);
}
ProtectionDomain pd = pojo.getClass().getProtectionDomain();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> clazz = pojo.toClass(cl, pd);
pojo.detach();
return clazz;
} catch (CannotCompileException e){
e.printStackTrace(); //TODO -- provide proper logging
throw new RuntimeException("Problem generating class for table " + classInfo.getTableName(), e);
}
}
 
private CtMethod createGetterMethod(CtField field) throws CannotCompileException {
String fn = field.getName();
return CtNewMethod.getter(this.naming.createGetterName(fn), field);
}
 
private CtMethod createSetterMethod(CtField field)
throws CannotCompileException {
String fn = field.getName();
return CtNewMethod.setter(naming.createSetterName(fn), field);
}
 
private CtField createField(AttributeInfo ai, CtClass declaring)
throws CannotCompileException {
CtField f = new CtField(ai.getCtClass(), ai.getFieldName(), declaring);
return f;
}
 
}
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/MissingIdentifierException.java
New file
0,0 → 1,58
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* This Exception is thrown when the POJO Utility cannot locate a primary key.
*
* @author Karel Maesen, Geovise BVBA
*
*/
public class MissingIdentifierException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static final String basemsg = "No suitable identifier found in table";
 
public MissingIdentifierException() {
super(basemsg);
}
 
public MissingIdentifierException(String msg) {
super(basemsg + ":" + msg);
}
 
public MissingIdentifierException(Throwable cause) {
super(cause);
}
 
public MissingIdentifierException(String msg, Throwable cause) {
super(basemsg + ":" + msg, cause);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/NamingStrategy.java
New file
0,0 → 1,70
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
/**
* A <code>NamingStrategy</code> determines how to derive suitable class and
* member names corresponding to database tables and columns.
*
* @author Karel Maesen, Geovise BVBA (http://www.geovise.com/)
*/
public interface NamingStrategy {
 
/**
* Create a valid name for a member variable based on the specified input
* name.
*
* @param base
* the input name.
* @return a valid java identifier for a member variable.
*/
public String createPropertyName(String base);
 
/**
* Create a valid name for a setter for the property
*
* @param propertyName
* @return valid java identifier for a property setter
*/
public String createSetterName(String propertyName);
 
/**
* Create a valid name for a getter for the property
*
* @param propertyName
* @return valid java identifier for a property getter
*/
public String createGetterName(String propertyName);
 
/**
* Create a valid name for a Java class based on the specified input name.
*
* @param base
* the input name.
* @return a valid java identifier for a class.
*/
public String createClassName(String base);
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/AutoMapper.java
New file
0,0 → 1,280
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2008 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial.pojo;
 
import org.dom4j.Document;
import org.hibernatespatial.HBSpatialExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.*;
 
/**
* @author Karel Maesen, Geovise BVBA
*/
public class AutoMapper {
 
protected final static Logger logger = LoggerFactory.getLogger(AutoMapper.class);
 
protected final static String PACKAGE_NAME = "org.hibernatespatial.features.generated";
 
private static Map<TableName, Class<?>> tableClassMap = new HashMap<TableName, Class<?>>();
 
private static Map<TableName, ClassInfo> tableClassInfoMap = new HashMap<TableName, ClassInfo>();
 
private static NamingStrategy naming = new SimpleNamingStrategy();
 
/**
* Returns the Hibernate mapping document for the specified tables
* <p/>
* <p>To create the mapping, a <code>Connection</code> object must be
* provided to provide access to the specified tables.
* This connection will not be closed on return.</p>
*
* @param conn JDBC <code>Connection</code> used during mapping
* @param catalog database catalog
* @param schema database schema
* @param tableNames list of table names
* @return the XML mapping document that maps the tables specified by the catalog, schema and tablenames arguments.
* @throws SQLException
*/
public static synchronized Document map(Connection conn, String catalog, String schema, Collection<String> tableNames) throws SQLException {
TypeMapper typeMapper = new TypeMapper(HBSpatialExtension.getDefaultSpatialDialect().getDbGeometryTypeName());
DatabaseMetaData dmd = conn.getMetaData();
FeatureMapper fMapper = new FeatureMapper(naming, typeMapper);
FeatureClassGenerator fGenerator = new FeatureClassGenerator(PACKAGE_NAME, naming);
 
for (String tableName : tableNames) {
TableName table = new TableName(catalog, schema, tableName);
if (tableClassInfoMap.get(table) != null) {
logger.info("Class info for table " + tableName + " in catalog/schema " + catalog + "/" + schema + " has already been mapped.");
continue;
}
logger.info("Generating class info for table " + tableName + " in catalog/schema " + catalog + "/" + schema);
ClassInfo cInfo;
try {
cInfo = fMapper.createClassInfo(catalog, schema, tableName, dmd);
logger.info("Generating class " + cInfo.getClassName() + " for table " + tableName);
Class<?> clazz = fGenerator.generate(cInfo);
tableClassMap.put(table, clazz);
tableClassInfoMap.put(table, cInfo);
 
} catch (TableNotFoundException e) {
logger.warn(e.getMessage());
} catch (MissingIdentifierException e) {
logger.warn(e.getMessage());
}
}
logger.info("Generating Hibernate Mapping file");
MappingsGenerator mappingGenerator = new MappingsGenerator(PACKAGE_NAME);
try {
mappingGenerator.load(tableClassInfoMap.values(), schema);
} catch (MissingIdentifierException e) {
throw new RuntimeException(e);
}
return mappingGenerator.getMappingsDoc();
}
 
/**
* Returns the <code>Class</code> object to which the specified table is mapped
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @return class to which the table specified by the arguments is mapped
*/
public static Class<?> getClass(String catalog, String schema, String tableName) {
TableName tbn = new TableName(catalog, schema, tableName);
return tableClassMap.get(tbn);
}
 
/**
* Returns the tables mapped by this automapper.
*
* @return a List of mapped tables. Each table is represented by a String array with the first
* component the catalog, the second the schema, and the third the table name.
*/
public static List<String[]> getMappedTables() {
List<String[]> list = new ArrayList<String[]>();
for (TableName tbn : tableClassMap.keySet()) {
String[] sa = new String[3];
sa[0] = tbn.catalog;
sa[1] = tbn.schema;
sa[2] = tbn.tableName;
list.add(sa);
}
return list;
}
 
/**
* Returns the attribute names of the class to with the specified table is mapped
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @return list of attribute (field) names of the class that corresponds with the table identified by the arguments
*/
public static List<String> getAttributes(String catalog, String schema, String tableName) {
List<AttributeInfo> attributes = getAttributeInfos(catalog, schema, tableName);
List<String> result = new ArrayList<String>();
for (AttributeInfo attributeInfo : attributes) {
result.add(attributeInfo.getFieldName());
}
return result;
}
 
private static List<AttributeInfo> getAttributeInfos(String catalog, String schema, String tableName) {
TableName tbn = new TableName(catalog, schema, tableName);
ClassInfo cInfo = tableClassInfoMap.get(tbn);
if (cInfo == null) return new ArrayList<AttributeInfo>();
return cInfo.getAttributes();
}
 
/**
* Returns the Identifier attribute
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @return the attribute name which functions as a unique identifier for the objects corresponding
* to rows in the specified table
* @throws MissingIdentifierException when no Identifier property is available
*/
public static String getIdAttribute(String catalog, String schema, String tableName) throws MissingIdentifierException {
TableName tbn = new TableName(catalog, schema, tableName);
ClassInfo cInfo = tableClassInfoMap.get(tbn);
return cInfo.getIdAttribute().getFieldName();
}
 
/**
* Returns the (default) <code>Geometry</code>-valued attribute
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @return the name of the <code>Geometry</code>-valued attribute
* @throws GeometryNotFoundException when no <code>Geometry</code>-valued property is available
*/
public static String getGeometryAttribute(String catalog, String schema, String tableName) throws GeometryNotFoundException {
TableName tbn = new TableName(catalog, schema, tableName);
ClassInfo cInfo = tableClassInfoMap.get(tbn);
return cInfo.getGeomAttribute().getFieldName();
}
 
/**
* Returns the name of the setter-method for the attribute
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @param attribute name of the attribute of the class to which this class is mapped
* @return the name of the setter-method of the attribute specified by the arguments
*/
public static String getAttributeSetterName(String catalog, String schema, String tableName, String attribute) {
getAttributeInfo(catalog, schema, tableName, attribute);
return naming.createSetterName(attribute);
}
 
/**
* Returns the name of the getter-method for the attribute
*
* @param catalog catalog of the table
* @param schema schema of the table
* @param tableName name of the table
* @param attribute name of the attribute of the class to which this class is mapped
* @return the name of the getter-method of the attribute specified by the arguments
* */
public static String getAttributeGetterName(String catalog, String schema, String tableName, String attribute) {
getAttributeInfo(catalog, schema, tableName, attribute);
return naming.createGetterName(attribute);
}
 
private static AttributeInfo getAttributeInfo(String catalog, String schema, String tableName, String attribute) {
if (attribute == null) throw new IllegalArgumentException("Null attribute received.");
for (AttributeInfo candidate : getAttributeInfos(catalog, schema, tableName)) {
if (candidate.getFieldName().equals(attribute)) {
return candidate;
}
}
throw new IllegalArgumentException(String.format("%s is not an attribute of the class to which table %s is mapped.", attribute, tableName));
}
 
private static class TableName {
String catalog;
String schema;
String tableName;
 
private TableName(String catalog, String schema, String tableName) {
this.catalog = catalog;
this.schema = schema;
this.tableName = tableName;
}
 
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((catalog == null) ? 0 : catalog.hashCode());
result = prime * result
+ ((schema == null) ? 0 : schema.hashCode());
result = prime * result
+ ((tableName == null) ? 0 : tableName.hashCode());
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof TableName))
return false;
TableName other = (TableName) obj;
if (catalog == null) {
if (other.catalog != null)
return false;
} else if (!catalog.equals(other.catalog))
return false;
if (schema == null) {
if (other.schema != null)
return false;
} else if (!schema.equals(other.schema))
return false;
if (tableName == null) {
if (other.tableName != null)
return false;
} else if (!tableName.equals(other.tableName))
return false;
return true;
}
 
 
}
}
Property changes:
Added: svn:keywords
+ Id
Added: svn:mergeinfo
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/pojo/TypeNotFoundException.java
New file
0,0 → 1,60
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
 
package org.hibernatespatial.pojo;
 
/**
* This Exception is thrown when the POJO Utility cannot locate a primary key.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: Jun 24, 2010
*/
public class TypeNotFoundException extends Exception {
 
/**
*
*/
private static final long serialVersionUID = 1L;
 
private static final String basemsg = "Type not found";
 
public TypeNotFoundException() {
super(basemsg);
}
 
public TypeNotFoundException(String msg) {
super(basemsg + ":" + msg);
}
 
public TypeNotFoundException(Throwable cause) {
super(cause);
}
 
public TypeNotFoundException(String msg, Throwable cause) {
super(basemsg + ":" + msg, cause);
}
 
}
 
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/SpatialRelation.java
New file
0,0 → 1,57
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
/**
* These spatial relations are all defined in "OpenGIS Simple Feature
* Specification for SQL, Rev. 1.1" of the Open Geospatial Consortium (OGC).
*
* @author Karel Maesen
*/
public interface SpatialRelation {
 
public static int EQUALS = 0;
 
public static int DISJOINT = 1;
 
public static int TOUCHES = 2;
 
public static int CROSSES = 3;
 
public static int WITHIN = 4;
 
public static int OVERLAPS = 5;
 
public static int CONTAINS = 6;
 
public static int INTERSECTS = 7;
 
public static int FILTER = 8;
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/GeometryUserType.java
New file
0,0 → 1,231
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
import org.hibernate.HibernateException;
import org.hibernate.type.CustomType;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
 
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
 
/**
* This class ensures that Hibernate can work with
* the JTS <code>Geometry</code> type.
* <p/>
* To properly convert <code>Geometry</code> objects to database specific
* wrapper objects, acces is needed to a spatially enabled database dialect.
* This dialect can be specified as a parameter to the type. If no parameter is
* supplied, the default Dialect will be used (set in HBSpatialExtension).
*
* @author Karel Maesen
*/
public class GeometryUserType implements UserType, ParameterizedType, Serializable {
 
private SpatialDialect spatialDialect = null;
 
private UserType delegate = null;
 
public static String DIALECT_PARAM_NAME = "dialect";
 
public final static CustomType TYPE = new CustomType(new GeometryUserType(), null);
 
private void configure(Properties properties) {
if (properties == null || properties.getProperty(DIALECT_PARAM_NAME) == null) {
spatialDialect = HBSpatialExtension.getDefaultSpatialDialect();
} else {
spatialDialect = HBSpatialExtension.createSpatialDialect(properties
.getProperty(DIALECT_PARAM_NAME));
}
if (spatialDialect == null) {
throw new HibernateSpatialException(
"No spatial Dialect could be created");
}
delegate = spatialDialect.getGeometryUserType();
if (delegate instanceof ParameterizedType) {
((ParameterizedType) delegate).setParameterValues(properties);
}
}
 
/**
* @param arg0
* @param arg1
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#assemble(java.io.Serializable,
* java.lang.Object)
*/
public Object assemble(Serializable arg0, Object arg1)
throws HibernateException {
return delegate.assemble(arg0, arg1);
}
 
/**
* @param arg0
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object arg0) throws HibernateException {
return delegate.deepCopy(arg0);
}
 
/**
* @param arg0
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
*/
public Serializable disassemble(Object arg0) throws HibernateException {
return delegate.disassemble(arg0);
}
 
/**
* @param arg0
* @param arg1
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#equals(java.lang.Object,
* java.lang.Object)
*/
public boolean equals(Object arg0, Object arg1) throws HibernateException {
return delegate.equals(arg0, arg1);
}
 
/**
* @param obj
* @return
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
return delegate.equals(obj);
}
 
/**
* @return
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return delegate.hashCode();
}
 
/**
* @param arg0
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
*/
public int hashCode(Object arg0) throws HibernateException {
return delegate.hashCode(arg0);
}
 
/**
* @return
* @see org.hibernate.usertype.UserType#isMutable()
*/
public boolean isMutable() {
return delegate.isMutable();
}
 
/**
* @param arg0
* @param arg1
* @param arg2
* @return
* @throws HibernateException
* @throws SQLException
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,
* java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet arg0, String[] arg1, Object arg2)
throws HibernateException, SQLException {
return delegate.nullSafeGet(arg0, arg1, arg2);
}
 
/**
* @param arg0
* @param arg1
* @param arg2
* @throws HibernateException
* @throws SQLException
* @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
* java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement arg0, Object arg1, int arg2)
throws HibernateException, SQLException {
delegate.nullSafeSet(arg0, arg1, arg2);
}
 
/**
* @param arg0
* @param arg1
* @param arg2
* @return
* @throws HibernateException
* @see org.hibernate.usertype.UserType#replace(java.lang.Object,
* java.lang.Object, java.lang.Object)
*/
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
return delegate.replace(arg0, arg1, arg2);
}
 
/**
* @return
* @see org.hibernate.usertype.UserType#returnedClass()
*/
public Class returnedClass() {
return delegate.returnedClass();
}
 
/**
* @return
* @see org.hibernate.usertype.UserType#sqlTypes()
*/
public int[] sqlTypes() {
return delegate.sqlTypes();
}
 
/**
* @return
* @see java.lang.Object#toString()
*/
public String toString() {
return delegate.toString();
}
 
public void setParameterValues(Properties properties) {
configure(properties);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/main/java/org/hibernatespatial/HibernateSpatialException.java
New file
0,0 → 1,55
/**
* $Id$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernatespatial;
 
/**
* Exception for Hibernate Spatial
*
* @author Karel Maesen
*/
public class HibernateSpatialException extends RuntimeException {
 
/**
* generated serialVersionUID
*/
private static final long serialVersionUID = -2153256823661407568L;
 
public HibernateSpatialException(String msg) {
super(msg);
}
 
public HibernateSpatialException(Throwable cause) {
super(cause);
}
 
public HibernateSpatialException(String msg, Throwable cause) {
super(msg, cause);
}
 
}
Property changes:
Added: svn:keywords
+ Id
/branches/hibernate-3.6-integration/hibernate-spatial/src/site/site.xml
New file
0,0 → 1,73
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ $Id:$
~
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for geographic data.
~
~ Copyright © 2007-2010 Geovise BVBA
~
~ This library is free software; you can redistribute it and/or
~ modify it under the terms of the GNU Lesser General Public
~ License as published by the Free Software Foundation; either
~ version 2.1 of the License, or (at your option) any later version.
~
~ This library is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this library; if not, write to the Free Software
~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
~
~ For more information, visit: http://www.hibernatespatial.org/
-->
 
<project name="Hibernate Spatial">
 
<bannerLeft>
<name>Hibernate Spatial</name>
<href>http://www.hibernatespatial.org/</href>
</bannerLeft>
 
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-default-skin</artifactId>
</skin>
 
<publishDate format="yyyy MMM dd"/>
 
<body>
 
<menu name="Overview" inherit="top">
<item name="Introduction" href="index.html"/>
<item name="Usage" href="usage.html"/>
<item name="Road Map" href="roadmap.html"/>
</menu>
<menu name="Getting Hibernate Spatial" inherit="top">
<item name="Releases" href="download.html"/>
<item name="Sources" href="source-repository.html"/>
<item name="License" href="license.html"/>
<item name="Source code insight"
href="insight.html"/>
</menu>
<menu name="Documentation" inherit="top">
<item name="Tutorial" href="tutorial.html"/>
<item name="Maven Quick Start" href="mavenquick.html"/>
<item name="Configuring providers" href="providers.html"/>
<item name="Getting Help" href="gettinghelp.html"/>
<item name="JavaDocs" href="apidocs/index.html"/>
</menu>
 
 
<menu name="Providers" inherit="top">
<item name="Oracle10g" href="hibernate-spatial-oracle"/>
<item name="Postgresql" href="hibernate-spatial-postgis"/>
<item name="Microsft SQL Server" href="hibernate-spatial-sqlserver"/>
<item name="MySQL" href="hibernate-spatial-mysql"/>
<item name="GeoDB (H2)" href="hibernate-spatial-h2-geodb" />
</menu>
 
</body>
</project>
/branches/hibernate-3.6-integration/hibernate-spatial/src/site/resources/css/site.css
New file
0,0 → 1,4
.source {
overflow: auto;
}
 
/branches/hibernate-3.6-integration/hibernate-spatial/src/site/xdoc/mavenquick.xml
New file
0,0 → 1,82
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ $Id:$
~
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for geographic data.
~
~ Copyright © 2007-2010 Geovise BVBA
~
~ This library is free software; you can redistribute it and/or
~ modify it under the terms of the GNU Lesser General Public
~ License as published by the Free Software Foundation; either
~ version 2.1 of the License, or (at your option) any later version.
~
~ This library is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this library; if not, write to the Free Software
~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
~
~ For more information, visit: http://www.hibernatespatial.org/
-->
 
<document>
<properties>
<author>Karel Maesen</author>
<title>Maven Quick Start</title>
</properties>
 
<body>
<section name="Maven Quick Start">
<p>If you use maven for your project, it's very easy to start using Hibernate Spatial.</p>
<p>First, add the Hibernate Spatial and GeoTools repositories to you pom.xml
</p>
<source>
<![CDATA[
...
<repositories>
<repository>
<id>OSGEO GeoTools repo</id>
<url>http://download.osgeo.org/webdav/geotools</url>
</repository>
<repository>
<id>Hibernate Spatial repo</id>
<url>http://www.hibernatespatial.org/repository</url>
</repository>
</repositories>
...
]]>
</source>
<p>Secondly, add the Hibernate Spatial Provider as a dependency. E.g., when using Postgis/Postgresql, add
the
hibernate-spatial-postgis artifact. Other possibilities are: hibernate-spatial-oracle, or
hibernate-spatial-mysql
</p>
 
<source>
<![CDATA[
...
<dependencies>
...
<dependency>
<groupId>org.hibernatespatial</groupId>
<artifactId>hibernate-spatial-postgis</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
...
]]>
</source>
 
<p>Maven will now transitively resolve the dependencies to JTS, Hibernate and Hibernate Spatial (core
module). Now you're good to go.
</p>
</section>
</body>
</document>
/branches/hibernate-3.6-integration/hibernate-spatial/src/site/xdoc/roadmap.xml
New file
0,0 → 1,14
<?xml version="1.0" encoding="UTF-8"?>
<document>
<properties>
<author>Karel Maesen</author>
<title>Road Map</title>
</properties>
 
<body>
<iframe
style="width: 100%; height: 800px"
src="http://www.hibernatespatial.org/jira/browse/HIBSPA?report=com.atlassian.jira.plugin.system.project:roadmap-panel">
</iframe>
</body>
</document>
/branches/hibernate-3.6-integration/hibernate-spatial/src/site/xdoc/tutorial.xml
New file
0,0 → 1,1037
<?xml version="1.0" encoding="UTF-8"?>
 
<document>
<properties>
<author>Karel Maesen</author>
<title>Tutorial</title>
</properties>
 
<body>
 
<section name="Introduction">
<p>
This tutorial gives a quick overview of how to get
Hibernate Spatial working. We will develop a simple
application that stores, and retrieves some
simple data objects. The data objects are "special" in
that they have a property of type Geometry.
</p>
<p>
This tutorial assumes
that you are familiar with Hibernate, and the basic
concepts of working with geographic data. It is also based on the
<a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html">
Hibernate Tutorial</a>and uses the same example. If you
haven't read the Hibernate Tutorial, and are new to Hibernate, then
<strong>please read it before proceeding here</strong>.
</p>
<p>
<p>
The Hibernate Tutorial uses the HSQLDB in-memory
database to keep things simple. Since Hibernate
Spatial doesn't (yet) support HSQLDB, we have no
such luck. We require a postgis database. For
information on how to create a postgis database, you should consult
<a href="http://postgis.refractions.net/docs/">the postgis documentation</a>.
</p>
</p>
</section>
 
<section name="Creating a Spatially-Enabled EventManager">
<p>
We will create a small application to store and retrieve events we want to attend. (This is
the same use case as in the Hibernate Tutorial).
</p>
<subsection name="Setup">
<p>
We first need to set up our development environment. We will use the
<a href="http://maven.org/">Maven</a>
build tool in this tutorial (as this is also used in the Hibernate Tutorial).
</p>
<p>Maven can generate the basic structure of our simple application using the<code>mvn
archetype:generate</code>.
For this example, we specify type 15 (the default) and set
<code>groupId</code>
to<code>org.hibernatespatial.tutorials</code>,
<code>artifactId</code>
to
<code>event-tutorial</code>
and
<code>package</code>
to<code>event</code>.
</p>
<source>
mvn archetype:generate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [archetype:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] Preparing archetype:generate
[INFO] No goals needed for project - skipping
[INFO] Setting property: classpath.resource.loader.class =>
'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] [archetype:generate {execution: default-cli}]
Choose archetype:
1: internal -> appfuse-basic-jsf (AppFuse archetype for creating a web application with Hibernate,
Spring and JSF)
2: internal -> appfuse-basic-spring (AppFuse archetype for creating a web application with
Hibernate, Spring and Spring MVC)
3: internal -> appfuse-basic-struts (AppFuse archetype for creating a web application with
Hibernate, Spring and Struts 2)
4: internal -> appfuse-basic-tapestry (AppFuse archetype for creating a web application with
Hibernate, Spring and Tapestry 4)
5: internal -> appfuse-core (AppFuse archetype for creating a jar application with Hibernate and
Spring and XFire)
6: internal -> appfuse-modular-jsf (AppFuse archetype for creating a modular application with
Hibernate, Spring and JSF)
7: internal -> appfuse-modular-spring (AppFuse archetype for creating a modular application with
Hibernate, Spring and Spring MVC)
8: internal -> appfuse-modular-struts (AppFuse archetype for creating a modular application with
Hibernate, Spring and Struts 2)
9: internal -> appfuse-modular-tapestry (AppFuse archetype for creating a modular application with
Hibernate, Spring and Tapestry 4)
10: internal -> maven-archetype-j2ee-simple (A s