HHH-6511 - Fixes Postgis, Mysql, SQL Server and GeoDB dialects for geolatte/jts integration.

This commit is contained in:
Karel Maesen 2013-04-08 18:26:36 +02:00 committed by Steve Ebersole
parent 0d5dfa64cd
commit 290c8354b3
72 changed files with 569 additions and 6600 deletions

View File

@ -0,0 +1,81 @@
import groovy.sql.Sql
import groovy.xml.MarkupBuilder
import org.geolatte.geom.ByteBuffer
@GrabConfig(systemClassLoader=true)
@Grab(group='com.microsoft', module='sqljdbc', version='2.0')
@Grab(group='org.geolatte', module='geolatte-geom',version='0.12-SNAPSHOT')
//path to the generated TestData XML file
def OUT_FILE = "/tmp/out.xml"
//input test data set
String testdata = new File('test-data-set.xml').text
def records = new XmlSlurper().parseText(testdata)
def wkts = records.Element.wkt
def wkt_srids= wkts.collect{ wkt -> wkt.text() =~ /SRID=(.*);(.*)/ }
.findAll { it.matches() }
.collect {m -> [ m[0][1], m[0][2] ] } //select only matching srid and wkt regions
//add the empty elements
wkt_srids.add( [0, 'POINT EMPTY'])
wkt_srids.add( [0, 'LINESTRING EMPTY'])
wkt_srids.add( [0, 'GEOMETRYCOLLECTION EMPTY'])
wkt_srids.add( [0, 'POLYGON EMPTY'])
wkt_srids.add( [0, 'MULTIPOINT EMPTY'])
//wkt_srids.each{ println( it ) }
sql = Sql.newInstance('jdbc:sqlserver://sqlserver.geovise.com:1433;databaseName=HBS',
'hbs', 'hbs', 'com.microsoft.sqlserver.jdbc.SQLServerDriver')
def writer = new FileWriter( new File(OUT_FILE) )
def xmlOut = new MarkupBuilder(writer)
xmlOut.TestCases() {
def i = 1
wkt_srids.each { el ->
TestCase {
id( i++ )
ewkt( el[1] )
srid( el[0])
db_representation(to_native(el[1], el[0]))
// db_wkt(to_wkt(el[1], el[0]))
// db_wkb(to_wkb(el[1], el[0]))
}
}
}
def to_native(wkt, srid) {
row = sql.firstRow("select Geometry::STGeomFromText('" + wkt + "', ${srid}) ")
buffer = ByteBuffer.from(row[0])
buffer.toString()
}
def to_wkt(wkt, srid) {
row = sql.firstRow("select Geometry::STGeomFromText('" + wkt + "', ${srid}).STAsText() ")
row[0]
}
def to_wkb(wkt, srid) {
row = sql.firstRow("select Geometry::STGeomFromText('" + wkt + "', ${srid}).STAsBinary() ")
buffer = ByteBuffer.from(row[0])
buffer.toString()
}

View File

@ -7,7 +7,7 @@ import org.hibernate.type.AbstractSingleColumnStandardBasicType;
* @author Karel Maesen, Geovise BVBA * @author Karel Maesen, Geovise BVBA
* creation-date: 10/12/12 * creation-date: 10/12/12
*/ */
public class GeolatteGeometryType extends AbstractSingleColumnStandardBasicType<Geometry> { public class GeolatteGeometryType extends AbstractSingleColumnStandardBasicType<Geometry> implements Spatial {
public static final GeolatteGeometryType INSTANCE = new GeolatteGeometryType(); public static final GeolatteGeometryType INSTANCE = new GeolatteGeometryType();

View File

@ -29,7 +29,7 @@ import org.hibernate.type.AbstractSingleColumnStandardBasicType;
* *
* @author Karel Maesen * @author Karel Maesen
*/ */
public class JTSGeometryType extends AbstractSingleColumnStandardBasicType<Geometry> { public class JTSGeometryType extends AbstractSingleColumnStandardBasicType<Geometry> implements Spatial {
public static final JTSGeometryType INSTANCE = new JTSGeometryType(); public static final JTSGeometryType INSTANCE = new JTSGeometryType();

View File

@ -0,0 +1,11 @@
package org.hibernate.spatial;
/**
* A marker interface for spatial (geometric/geographic) types.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 4/18/13
*/
public interface Spatial {
}

View File

@ -24,7 +24,6 @@ package org.hibernate.spatial.criterion;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery; import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Criterion;
@ -57,11 +56,10 @@ public class DWithinExpression implements Criterion {
} }
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] { return new TypedValue[] {
criteriaQuery.getTypedValue( criteria, propertyName, geometry ), criteriaQuery.getTypedValue( criteria, propertyName, geometry ),
new TypedValue( StandardBasicTypes.DOUBLE, Double.valueOf( distance ), EntityMode.POJO ) new TypedValue( StandardBasicTypes.DOUBLE, distance )
}; };
} }
} }

View File

@ -22,7 +22,6 @@
package org.hibernate.spatial.criterion; package org.hibernate.spatial.criterion;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery; import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Criterion;
@ -53,7 +52,7 @@ public class HavingSridExpression implements Criterion {
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] { return new TypedValue[] {
new TypedValue( StandardBasicTypes.INTEGER, Integer.valueOf( srid ), EntityMode.POJO ) new TypedValue( StandardBasicTypes.INTEGER, srid )
}; };
} }

View File

@ -26,9 +26,8 @@ import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import org.hibernate.spatial.jts.JTS;
import org.hibernate.spatial.jts.mgeom.MGeometryFactory;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicBinder; import org.hibernate.type.descriptor.sql.BasicBinder;
@ -40,6 +39,8 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
*/ */
public abstract class AbstractGeometryValueBinder<X> extends BasicBinder<X> { public abstract class AbstractGeometryValueBinder<X> extends BasicBinder<X> {
private static GeometryFactory geometryFactory = new GeometryFactory();
public AbstractGeometryValueBinder(JavaTypeDescriptor<X> javaDescriptor, SqlTypeDescriptor sqlDescriptor) { public AbstractGeometryValueBinder(JavaTypeDescriptor<X> javaDescriptor, SqlTypeDescriptor sqlDescriptor) {
super( javaDescriptor, sqlDescriptor ); super( javaDescriptor, sqlDescriptor );
} }
@ -50,8 +51,8 @@ public abstract class AbstractGeometryValueBinder<X> extends BasicBinder<X> {
st.setObject( index, dbGeom ); st.setObject( index, dbGeom );
} }
protected MGeometryFactory getGeometryFactory() { protected GeometryFactory getGeometryFactory() {
return JTS.getDefaultGeometryFactory(); return geometryFactory;
} }
protected abstract Object toNative(Geometry jtsGeom, Connection connection); protected abstract Object toNative(Geometry jtsGeom, Connection connection);

View File

@ -21,30 +21,34 @@
package org.hibernate.spatial.dialect; package org.hibernate.spatial.dialect;
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.spatial.GeometrySqlTypeDescriptor;
import org.hibernate.spatial.jts.JTS;
import org.hibernate.spatial.jts.mgeom.MGeometryFactory;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicExtractor;
import java.sql.CallableStatement; import java.sql.CallableStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import org.hibernate.spatial.GeometrySqlTypeDescriptor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicExtractor;
/** /**
* @author Karel Maesen, Geovise BVBA * @author Karel Maesen, Geovise BVBA
* creation-date: 1/19/12 * creation-date: 1/19/12
*/ */
public abstract class AbstractGeometryValueExtractor<X> extends BasicExtractor<X> { public abstract class AbstractGeometryValueExtractor<X> extends BasicExtractor<X> {
// later this will need to be configurable. So define this only once for both
// extractor and binder.
private static GeometryFactory geometryFactory = new GeometryFactory();
public AbstractGeometryValueExtractor(JavaTypeDescriptor<X> javaDescriptor, GeometrySqlTypeDescriptor typeDescriptor) { public AbstractGeometryValueExtractor(JavaTypeDescriptor<X> javaDescriptor, GeometrySqlTypeDescriptor typeDescriptor) {
super( javaDescriptor, typeDescriptor ); super( javaDescriptor, typeDescriptor );
} }
protected MGeometryFactory getGeometryFactory() { protected GeometryFactory getGeometryFactory() {
return JTS.getDefaultGeometryFactory(); return geometryFactory;
} }
@Override @Override

View File

@ -25,7 +25,6 @@ import org.hibernate.HibernateException;
import org.hibernate.dialect.H2Dialect; import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.spatial.GeometrySqlTypeDescriptor; import org.hibernate.spatial.GeometrySqlTypeDescriptor;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.SpatialDialect; import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation; import org.hibernate.spatial.SpatialRelation;
@ -118,8 +117,7 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
); );
registerFunction( registerFunction(
"envelope", new StandardSQLFunction( "envelope", new StandardSQLFunction(
"ST_Envelope", "ST_Envelope"
JTSGeometryType.INSTANCE
) )
); );
registerFunction( registerFunction(
@ -212,8 +210,7 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
); );
registerFunction( registerFunction(
"buffer", new StandardSQLFunction( "buffer", new StandardSQLFunction(
"ST_Buffer", "ST_Buffer"
JTSGeometryType.INSTANCE
) )
); );
// NOT YET AVAILABLE IN GEODB // NOT YET AVAILABLE IN GEODB

View File

@ -5,7 +5,6 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
/** /**
@ -36,8 +35,7 @@ class MySQLSpatialFunctions implements Iterable<Map.Entry<String, StandardSQLFun
); );
functionsToRegister.put( functionsToRegister.put(
"envelope", new StandardSQLFunction( "envelope", new StandardSQLFunction(
"envelope", "envelope"
JTSGeometryType.INSTANCE
) )
); );
functionsToRegister.put( functionsToRegister.put(
@ -64,12 +62,11 @@ class MySQLSpatialFunctions implements Iterable<Map.Entry<String, StandardSQLFun
StandardBasicTypes.BOOLEAN StandardBasicTypes.BOOLEAN
) )
); );
functionsToRegister.put( // functionsToRegister.put(
"boundary", new StandardSQLFunction( // "boundary", new StandardSQLFunction(
"boundary", // "boundary"
JTSGeometryType.INSTANCE // )
) // );
);
// Register functions for spatial relation constructs // Register functions for spatial relation constructs
functionsToRegister.put( functionsToRegister.put(
@ -120,54 +117,50 @@ class MySQLSpatialFunctions implements Iterable<Map.Entry<String, StandardSQLFun
StandardBasicTypes.BOOLEAN StandardBasicTypes.BOOLEAN
) )
); );
functionsToRegister.put( // functionsToRegister.put(
"relate", new StandardSQLFunction( // "relate", new StandardSQLFunction(
"relate", // "relate",
StandardBasicTypes.BOOLEAN // StandardBasicTypes.BOOLEAN
) // )
); // );
//
// register the spatial analysis functions // // register the spatial analysis functions
functionsToRegister.put( // functionsToRegister.put(
"distance", new StandardSQLFunction( // "distance", new StandardSQLFunction(
"distance", // "distance",
StandardBasicTypes.DOUBLE // StandardBasicTypes.DOUBLE
) // )
); // );
functionsToRegister.put( // functionsToRegister.put(
"buffer", new StandardSQLFunction( // "buffer", new StandardSQLFunction(
"buffer", // "buffer"
JTSGeometryType.INSTANCE // )
) // );
); // functionsToRegister.put(
functionsToRegister.put( // "convexhull", new StandardSQLFunction(
"convexhull", new StandardSQLFunction( // "convexhull"
"convexhull", // )
JTSGeometryType.INSTANCE // );
) // functionsToRegister.put(
); // "difference", new StandardSQLFunction(
functionsToRegister.put( // "difference"
"difference", new StandardSQLFunction( // )
"difference", // );
JTSGeometryType.INSTANCE // functionsToRegister.put(
) // "intersection", new StandardSQLFunction(
); // "intersection"
functionsToRegister.put( // )
"intersection", new StandardSQLFunction( // );
"intersection", JTSGeometryType.INSTANCE // functionsToRegister.put(
) // "symdifference", new StandardSQLFunction(
); // "symdifference"
functionsToRegister.put( // )
"symdifference", new StandardSQLFunction( // );
"symdifference", JTSGeometryType.INSTANCE // functionsToRegister.put(
) // "geomunion", new StandardSQLFunction(
); // "union"
functionsToRegister.put( // )
"geomunion", new StandardSQLFunction( // );
"union",
JTSGeometryType.INSTANCE
)
);
} }
@Override @Override

View File

@ -35,9 +35,9 @@ import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.spatial.GeometrySqlTypeDescriptor; import org.hibernate.spatial.GeometrySqlTypeDescriptor;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.Log; import org.hibernate.spatial.Log;
import org.hibernate.spatial.LogFactory; import org.hibernate.spatial.LogFactory;
import org.hibernate.spatial.Spatial;
import org.hibernate.spatial.SpatialAnalysis; import org.hibernate.spatial.SpatialAnalysis;
import org.hibernate.spatial.SpatialDialect; import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
@ -57,114 +57,10 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
SpatialDialect, Serializable { SpatialDialect, Serializable {
/**
* Implementation of the OGC astext function for HQL.
*/
private class AsTextFunction extends StandardSQLFunction {
private AsTextFunction() {
super( "astext", StandardBasicTypes.STRING );
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
if ( args.isEmpty() ) {
throw new IllegalArgumentException(
"First Argument in arglist must be object "
+ "to which method is applied"
);
}
buf.append( "TO_CHAR(SDO_UTIL.TO_WKTGEOMETRY(" ).append( args.get( 0 ) )
.append( "))" );
return buf.toString();
}
}
/**
* HQL Spatial relation function.
*/
private class SpatialRelateFunction extends StandardSQLFunction {
private final int relation;
private SpatialRelateFunction(final String name, final int relation) {
super(
name, isOGCStrict() ? StandardBasicTypes.BOOLEAN
: new SDOBooleanType()
);
this.relation = relation;
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
if ( args.size() < 2 ) {
throw new QueryException(
"Spatial relate functions require at least two arguments"
);
}
String srf;
return isOGCStrict() ?
getOGCSpatialRelateSQL(
(String) args.get( 0 ),
(String) args.get( 1 ), this.relation
) :
getNativeSpatialRelateSQL(
(String) args.get( 0 ),
(String) args.get( 1 ), this.relation
);
}
}
private class SpatialAnalysisFunction extends StandardSQLFunction {
private final int analysis;
private SpatialAnalysisFunction(String name, Type returnType,
int analysis) {
super( name, returnType );
this.analysis = analysis;
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return isOGCStrict() ? getSpatialAnalysisSQL(
args, this.analysis,
false
) : getNativeSpatialAnalysisSQL( args, analysis );
}
}
private class SpatialAggregationFunction extends StandardSQLFunction {
private final int aggregation;
private SpatialAggregationFunction(String name, Type returnType,
boolean isProjection, int aggregation) {
super( name, returnType );
this.aggregation = aggregation;
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return getNativeSpatialAggregateSQL(
(String) args.get( 0 ),
this.aggregation
);
}
}
public final static String SHORT_NAME = "oraclespatial"; public final static String SHORT_NAME = "oraclespatial";
private final static String CONNECTION_FINDER_PROPERTY = "CONNECTION-FINDER"; private final static String CONNECTION_FINDER_PROPERTY = "CONNECTION-FINDER";
private final static Log LOG = LogFactory.make(); private final static Log LOG = LogFactory.make();
private String OGC_STRICT = "OGC_STRICT"; private String OGC_STRICT = "OGC_STRICT";
private Map<String, Boolean> features = new HashMap<String, Boolean>(); private Map<String, Boolean> features = new HashMap<String, Boolean>();
public OracleSpatial10gDialect() { public OracleSpatial10gDialect() {
@ -188,204 +84,81 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
// section 2.1.1.1 // section 2.1.1.1
registerFunction( "dimension", new GetDimensionFunction() ); registerFunction( "dimension", new GetDimensionFunction() );
registerFunction( "geometrytype", new GetGeometryTypeFunction() ); registerFunction( "geometrytype", new GetGeometryTypeFunction() );
registerFunction( registerFunction( "srid", new SDOObjectProperty( "SDO_SRID", StandardBasicTypes.INTEGER ) );
"srid", new SDOObjectProperty( registerFunction( "envelope", new StandardSQLFunction( "SDO_GEOM.SDO_MBR" ) );
"SDO_SRID",
StandardBasicTypes.INTEGER
)
);
registerFunction(
"envelope",
new StandardSQLFunction( "SDO_GEOM.SDO_MBR", JTSGeometryType.INSTANCE )
);
registerFunction( "astext", new AsTextFunction() ); registerFunction( "astext", new AsTextFunction() );
registerFunction( "asbinary", new StandardSQLFunction( "SDO_UTIL.TO_WKBGEOMETRY", StandardBasicTypes.BINARY ) );
registerFunction( registerFunction(
"asbinary", new StandardSQLFunction( "isempty",
"SDO_UTIL.TO_WKBGEOMETRY", StandardBasicTypes.BINARY new WrappedOGCFunction( "OGC_ISEMPTY", StandardBasicTypes.BOOLEAN, new boolean[] { true } )
)
); );
registerFunction( registerFunction(
"isempty", new WrappedOGCFunction( "issimple",
"OGC_ISEMPTY", new WrappedOGCFunction( "OGC_ISSIMPLE", StandardBasicTypes.BOOLEAN, new boolean[] { true } )
StandardBasicTypes.BOOLEAN, new boolean[] { true }
)
);
registerFunction(
"issimple", new WrappedOGCFunction(
"OGC_ISSIMPLE",
StandardBasicTypes.BOOLEAN, new boolean[] { true }
)
);
registerFunction(
"boundary", new WrappedOGCFunction(
"OGC_BOUNDARY",
JTSGeometryType.INSTANCE,
new boolean[] { true }
)
); );
registerFunction( "boundary", new WrappedOGCFunction( "OGC_BOUNDARY", new boolean[] { true } ) );
// registerFunction("area", new AreaFunction()); // registerFunction("area", new AreaFunction());
// Register functions for spatial relation constructs // Register functions for spatial relation constructs
// section 2.1.1.2 // section 2.1.1.2
registerFunction( "overlaps", new SpatialRelateFunction( "overlaps", SpatialRelation.OVERLAPS ) );
registerFunction( "intersects", new SpatialRelateFunction( "intersects", SpatialRelation.INTERSECTS ) );
registerFunction( "contains", new SpatialRelateFunction( "contains", SpatialRelation.CONTAINS ) );
registerFunction( "crosses", new SpatialRelateFunction( "crosses", SpatialRelation.CROSSES ) );
registerFunction( "disjoint", new SpatialRelateFunction( "disjoint", SpatialRelation.DISJOINT ) );
registerFunction( "equals", new SpatialRelateFunction( "equals", SpatialRelation.EQUALS ) );
registerFunction( "touches", new SpatialRelateFunction( "touches", SpatialRelation.TOUCHES ) );
registerFunction( "within", new SpatialRelateFunction( "within", SpatialRelation.WITHIN ) );
registerFunction( registerFunction(
"overlaps", new SpatialRelateFunction( "relate",
"overlaps", new WrappedOGCFunction( "OGC_RELATE", StandardBasicTypes.BOOLEAN, new boolean[] { true, true, false } )
SpatialRelation.OVERLAPS
)
);
registerFunction(
"intersects", new SpatialRelateFunction(
"intersects",
SpatialRelation.INTERSECTS
)
);
registerFunction(
"contains", new SpatialRelateFunction(
"contains",
SpatialRelation.CONTAINS
)
);
registerFunction(
"crosses", new SpatialRelateFunction(
"crosses",
SpatialRelation.CROSSES
)
);
registerFunction(
"disjoint", new SpatialRelateFunction(
"disjoint",
SpatialRelation.DISJOINT
)
);
registerFunction(
"equals", new SpatialRelateFunction(
"equals",
SpatialRelation.EQUALS
)
);
registerFunction(
"touches", new SpatialRelateFunction(
"touches",
SpatialRelation.TOUCHES
)
);
registerFunction(
"within", new SpatialRelateFunction(
"within",
SpatialRelation.WITHIN
)
);
registerFunction(
"relate", new WrappedOGCFunction(
"OGC_RELATE",
StandardBasicTypes.BOOLEAN, new boolean[] { true, true, false }
)
); );
// Register spatial analysis functions. // Register spatial analysis functions.
// Section 2.1.1.3 // Section 2.1.1.3
registerFunction( registerFunction(
"distance", new SpatialAnalysisFunction(
"distance", "distance",
StandardBasicTypes.DOUBLE, SpatialAnalysis.DISTANCE new SpatialAnalysisFunction( "distance", StandardBasicTypes.DOUBLE, SpatialAnalysis.DISTANCE )
)
); );
registerFunction( "buffer", new SpatialAnalysisFunction( "buffer", SpatialAnalysis.BUFFER ) );
registerFunction( "convexhull", new SpatialAnalysisFunction( "convexhull", SpatialAnalysis.CONVEXHULL ) );
registerFunction( "difference", new SpatialAnalysisFunction( "difference", SpatialAnalysis.DIFFERENCE ) );
registerFunction( "intersection", new SpatialAnalysisFunction( "intersection", SpatialAnalysis.INTERSECTION ) );
registerFunction( registerFunction(
"buffer", new SpatialAnalysisFunction( "symdifference",
"buffer", new SpatialAnalysisFunction( "symdifference", SpatialAnalysis.SYMDIFFERENCE )
JTSGeometryType.INSTANCE,
SpatialAnalysis.BUFFER
)
);
registerFunction(
"convexhull", new SpatialAnalysisFunction(
"convexhull", JTSGeometryType.INSTANCE,
SpatialAnalysis.CONVEXHULL
)
);
registerFunction(
"difference", new SpatialAnalysisFunction(
"difference", JTSGeometryType.INSTANCE,
SpatialAnalysis.DIFFERENCE
)
);
registerFunction(
"intersection", new SpatialAnalysisFunction(
"intersection", JTSGeometryType.INSTANCE,
SpatialAnalysis.INTERSECTION
)
);
registerFunction(
"symdifference", new SpatialAnalysisFunction(
"symdifference", JTSGeometryType.INSTANCE,
SpatialAnalysis.SYMDIFFERENCE
)
);
registerFunction(
"geomunion", new SpatialAnalysisFunction(
"union",
JTSGeometryType.INSTANCE,
SpatialAnalysis.UNION
)
); );
registerFunction( "geomunion", new SpatialAnalysisFunction( "union", SpatialAnalysis.UNION ) );
// we rename OGC union to geomunion because union is a reserved SQL // we rename OGC union to geomunion because union is a reserved SQL
// keyword. (See also postgis documentation). // keyword. (See also postgis documentation).
// portable spatial aggregate functions // portable spatial aggregate functions
registerFunction( registerFunction( "extent", new SpatialAggregationFunction("extent", false, OracleSpatialAggregate.EXTENT) );
"extent", new SpatialAggregationFunction(
"extent",
JTSGeometryType.INSTANCE, false,
OracleSpatialAggregate.EXTENT
)
);
//other common functions //other common functions
registerFunction( registerFunction( "transform", new StandardSQLFunction("SDO_CS.TRANSFORM"));
"transform", new StandardSQLFunction(
"SDO_CS.TRANSFORM",
JTSGeometryType.INSTANCE
)
);
// Oracle specific Aggregate functions // Oracle specific Aggregate functions
registerFunction( registerFunction(
"centroid", new SpatialAggregationFunction( "centroid",
"extent", new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.CENTROID )
JTSGeometryType.INSTANCE, false,
OracleSpatialAggregate.CENTROID
)
); );
registerFunction( registerFunction(
"concat_lines", new SpatialAggregationFunction( "concat_lines",
"extent", JTSGeometryType.INSTANCE, false, new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.CONCAT_LINES )
OracleSpatialAggregate.CONCAT_LINES
)
); );
registerFunction( registerFunction(
"aggr_convexhull", new SpatialAggregationFunction( "aggr_convexhull",
"extent", JTSGeometryType.INSTANCE, false, new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.CONVEXHULL )
OracleSpatialAggregate.CONVEXHULL
)
); );
registerFunction( registerFunction(
"aggr_union", new SpatialAggregationFunction( "aggr_union",
"extent", new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.UNION )
JTSGeometryType.INSTANCE, false,
OracleSpatialAggregate.UNION
)
); );
registerFunction( registerFunction(
"lrs_concat", new SpatialAggregationFunction( "lrs_concat",
"lrsconcat", JTSGeometryType.INSTANCE, new SpatialAggregationFunction( "lrsconcat", false, OracleSpatialAggregate.LRS_CONCAT )
false, OracleSpatialAggregate.LRS_CONCAT
)
); );
} }
@ -670,7 +443,6 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
return ( (Boolean) this.features.get( OGC_STRICT ) ).booleanValue(); return ( (Boolean) this.features.get( OGC_STRICT ) ).booleanValue();
} }
private void configure() { private void configure() {
ClassLoader loader = Thread.currentThread().getContextClassLoader(); ClassLoader loader = Thread.currentThread().getContextClassLoader();
String propfileLoc = getClass().getCanonicalName() + ".properties"; String propfileLoc = getClass().getCanonicalName() + ".properties";
@ -731,7 +503,6 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
} }
} }
public boolean isTwoPhaseFiltering() { public boolean isTwoPhaseFiltering() {
return false; return false;
} }
@ -744,5 +515,110 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
return ( getFunctions().get( function.toString() ) != null ); return ( getFunctions().get( function.toString() ) != null );
} }
/**
* Implementation of the OGC astext function for HQL.
*/
private class AsTextFunction extends StandardSQLFunction {
private AsTextFunction() {
super( "astext", StandardBasicTypes.STRING );
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
if ( args.isEmpty() ) {
throw new IllegalArgumentException(
"First Argument in arglist must be object "
+ "to which method is applied"
);
}
buf.append( "TO_CHAR(SDO_UTIL.TO_WKTGEOMETRY(" ).append( args.get( 0 ) )
.append( "))" );
return buf.toString();
}
}
/**
* HQL Spatial relation function.
*/
private class SpatialRelateFunction extends StandardSQLFunction {
private final int relation;
private SpatialRelateFunction(final String name, final int relation) {
super(
name, isOGCStrict() ? StandardBasicTypes.BOOLEAN
: new SDOBooleanType()
);
this.relation = relation;
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
if ( args.size() < 2 ) {
throw new QueryException(
"Spatial relate functions require at least two arguments"
);
}
String srf;
return isOGCStrict() ?
getOGCSpatialRelateSQL(
(String) args.get( 0 ),
(String) args.get( 1 ), this.relation
) :
getNativeSpatialRelateSQL(
(String) args.get( 0 ),
(String) args.get( 1 ), this.relation
);
}
}
private class SpatialAnalysisFunction extends StandardSQLFunction {
private final int analysis;
private SpatialAnalysisFunction(String name, Type returnType, int analysis) {
super( name, returnType );
if (Spatial.class.isAssignableFrom( returnType.getClass() )) {
throw new IllegalArgumentException("This constructor is only valid for functions returning non-spatial values.");
}
this.analysis = analysis;
}
private SpatialAnalysisFunction(String name, int analysis) {
this( name, null, analysis );
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return isOGCStrict() ? getSpatialAnalysisSQL(
args, this.analysis,
false
) : getNativeSpatialAnalysisSQL( args, analysis );
}
}
private class SpatialAggregationFunction extends StandardSQLFunction {
private final int aggregation;
private SpatialAggregationFunction(String name, boolean isProjection, int aggregation) {
super( name );
this.aggregation = aggregation;
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return getNativeSpatialAggregateSQL(
(String) args.get( 0 ),
this.aggregation
);
}
}
} }

View File

@ -40,7 +40,6 @@ import org.hibernate.HibernateException;
import org.hibernate.spatial.Log; import org.hibernate.spatial.Log;
import org.hibernate.spatial.LogFactory; import org.hibernate.spatial.LogFactory;
import org.hibernate.spatial.helper.FinderException; import org.hibernate.spatial.helper.FinderException;
import org.hibernate.spatial.jts.mgeom.MCoordinate;
import org.hibernate.type.descriptor.JdbcTypeNameMapper; import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
@ -341,6 +340,10 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
*/ */
private Double[] convertCoordinates(Coordinate[] coordinates, int dim, private Double[] convertCoordinates(Coordinate[] coordinates, int dim,
boolean isLrs) { boolean isLrs) {
if (isLrs)
throw new UnsupportedOperationException();
if ( dim > 4 ) { if ( dim > 4 ) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Dim parameter value cannot be greater than 4" "Dim parameter value cannot be greater than 4"
@ -348,18 +351,18 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
} }
Double[] converted = new Double[coordinates.length * dim]; Double[] converted = new Double[coordinates.length * dim];
for ( int i = 0; i < coordinates.length; i++ ) { for ( int i = 0; i < coordinates.length; i++ ) {
MCoordinate c = MCoordinate.convertCoordinate( coordinates[i] ); Coordinate c = coordinates[i];
// set the X and Y values // set the X and Y values
converted[i * dim] = toDouble( c.x ); converted[i * dim] = toDouble( c.x );
converted[i * dim + 1] = toDouble( c.y ); converted[i * dim + 1] = toDouble( c.y );
if ( dim == 3 ) { if ( dim == 3 ) {
converted[i * dim + 2] = isLrs ? toDouble( c.m ) : toDouble( c.z );
}
else if ( dim == 4 ) {
converted[i * dim + 2] = toDouble( c.z ); converted[i * dim + 2] = toDouble( c.z );
converted[i * dim + 3] = toDouble( c.m );
} }
// else if ( dim == 4 ) {
// converted[i * dim + 2] = toDouble( c.z );
// converted[i * dim + 3] = toDouble( c.m );
// }
} }
return converted; return converted;
} }
@ -392,7 +395,7 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
// This shall be cleaner if MCoordinate.getOrdinate(int ordinateIndex) // This shall be cleaner if MCoordinate.getOrdinate(int ordinateIndex)
// is moved to the // is moved to the
// Coordinate class // Coordinate class
MCoordinate c = MCoordinate.convertCoordinate( geom.getCoordinate() ); Coordinate c = geom.getCoordinate();
int d = 0; int d = 0;
if ( c != null ) { if ( c != null ) {
if ( !Double.isNaN( c.x ) ) { if ( !Double.isNaN( c.x ) ) {
@ -404,9 +407,9 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
if ( !Double.isNaN( c.z ) ) { if ( !Double.isNaN( c.z ) ) {
d++; d++;
} }
if ( !Double.isNaN( c.m ) ) { // if ( !Double.isNaN( c.m ) ) {
d++; // d++;
} // }
} }
return d; return d;
} }
@ -426,11 +429,11 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
* @return the lrs position for the SDOGeometry.SDOGType * @return the lrs position for the SDOGeometry.SDOGType
*/ */
private int getCoordinateLrsPosition(Geometry geom) { private int getCoordinateLrsPosition(Geometry geom) {
MCoordinate c = MCoordinate.convertCoordinate( geom.getCoordinate() ); Coordinate c = geom.getCoordinate();
int measurePos = 0; int measurePos = 0;
if ( c != null && !Double.isNaN( c.m ) ) { // if ( c != null && !Double.isNaN( c.m ) ) {
measurePos = ( Double.isNaN( c.z ) ) ? 3 : 4; // measurePos = ( Double.isNaN( c.z ) ) ? 3 : 4;
} // }
return measurePos; return measurePos;
} }

View File

@ -36,11 +36,8 @@ import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.Polygon;
import org.hibernate.HibernateException;
import org.hibernate.spatial.jts.Circle;
import org.hibernate.spatial.dialect.AbstractGeometryValueExtractor; import org.hibernate.spatial.dialect.AbstractGeometryValueExtractor;
import org.hibernate.spatial.jts.mgeom.MCoordinate; import org.hibernate.spatial.jts.Circle;
import org.hibernate.spatial.jts.mgeom.MLineString;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/** /**
@ -157,42 +154,41 @@ public class SDOGeometryValueExtractor<X> extends AbstractGeometryValueExtractor
} }
} }
LineString ls = lrs ? getGeometryFactory().createMLineString( cs )
: getGeometryFactory().createLineString( cs ); if (lrs)
return ls; throw new UnsupportedOperationException();
else
return getGeometryFactory().createLineString( cs );
} }
private MultiLineString convertSDOMultiLine(int dim, int lrsDim, private MultiLineString convertSDOMultiLine(int dim, int lrsDim,
SDOGeometry SDOGeom) { SDOGeometry SDOGeom) {
boolean lrs = SDOGeom.isLRSGeometry(); boolean lrs = SDOGeom.isLRSGeometry();
if (lrs) {
throw new UnsupportedOperationException();
}
ElemInfo info = SDOGeom.getInfo(); ElemInfo info = SDOGeom.getInfo();
LineString[] lines = lrs ? new MLineString[SDOGeom.getInfo().getSize()] LineString[] lines = new LineString[SDOGeom.getInfo().getSize()];
: new LineString[SDOGeom.getInfo().getSize()];
int i = 0; int i = 0;
while ( i < info.getSize() ) { while ( i < info.getSize() ) {
CoordinateSequence cs = null; CoordinateSequence cs = null;
if ( info.getElementType( i ).isCompound() ) { if ( info.getElementType( i ).isCompound() ) {
int numCompounds = info.getNumCompounds( i ); int numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) ); cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
LineString line = lrs ? getGeometryFactory().createMLineString( LineString line = getGeometryFactory().createLineString( cs );
cs
) : getGeometryFactory().createLineString( cs );
lines[i] = line; lines[i] = line;
i += 1 + numCompounds; i += 1 + numCompounds;
} }
else { else {
cs = add( cs, getElementCSeq( i, SDOGeom, false ) ); cs = add( cs, getElementCSeq( i, SDOGeom, false ) );
LineString line = lrs ? getGeometryFactory().createMLineString( LineString line = getGeometryFactory().createLineString( cs );
cs
) : getGeometryFactory().createLineString( cs );
lines[i] = line; lines[i] = line;
i++; i++;
} }
} }
MultiLineString mls = lrs ? getGeometryFactory() MultiLineString mls = getGeometryFactory().createMultiLineString( lines );
.createMultiMLineString( (MLineString[]) lines )
: getGeometryFactory().createMultiLineString( lines );
return mls; return mls;
} }
@ -405,11 +401,13 @@ public class SDOGeometryValueExtractor<X> extends AbstractGeometryValueExtractor
} }
else if ( dim == 3 ) { else if ( dim == 3 ) {
if ( SDOGeom.isLRSGeometry() ) { if ( SDOGeom.isLRSGeometry() ) {
coordinates[i] = MCoordinate.create2dWithMeasure(
oordinates[i * dim], // X throw new UnsupportedOperationException();
oordinates[i * dim + 1], // Y // coordinates[i] = MCoordinate.create2dWithMeasure(
oordinates[i * dim + lrsDim] // oordinates[i * dim], // X
); // M // oordinates[i * dim + 1], // Y
// oordinates[i * dim + lrsDim]
// ); // M
} }
else { else {
coordinates[i] = new Coordinate( coordinates[i] = new Coordinate(
@ -419,21 +417,21 @@ public class SDOGeometryValueExtractor<X> extends AbstractGeometryValueExtractor
); // Z ); // Z
} }
} }
else if ( dim == 4 ) { // else if ( dim == 4 ) {
// This must be an LRS Geometry // // This must be an LRS Geometry
if ( !SDOGeom.isLRSGeometry() ) { // if ( !SDOGeom.isLRSGeometry() ) {
throw new HibernateException( // throw new HibernateException(
"4 dimensional Geometries must be LRS geometry" // "4 dimensional Geometries must be LRS geometry"
); // );
} // }
coordinates[i] = MCoordinate.create3dWithMeasure( // coordinates[i] = MCoordinate.create3dWithMeasure(
oordinates[i // oordinates[i
* dim], // X // * dim], // X
oordinates[i * dim + 1], // Y // oordinates[i * dim + 1], // Y
oordinates[i * dim + zDim], // Z // oordinates[i * dim + zDim], // Z
oordinates[i * dim + lrsDim] // oordinates[i * dim + lrsDim]
); // M // ); // M
} // }
} }
return getGeometryFactory().getCoordinateSequenceFactory().create( return getGeometryFactory().getCoordinateSequenceFactory().create(
coordinates coordinates
@ -489,21 +487,22 @@ public class SDOGeometryValueExtractor<X> extends AbstractGeometryValueExtractor
// if this is an LRS geometry, fill the measure values into // if this is an LRS geometry, fill the measure values into
// the linearized array // the linearized array
if ( lrs ) { if ( lrs ) {
MCoordinate[] mcoord = new MCoordinate[coords.length]; throw new UnsupportedOperationException();
int lastIndex = coords.length - 1; // MCoordinate[] mcoord = new MCoordinate[coords.length];
mcoord[0] = MCoordinate.create2dWithMeasure( x1, y1, m1 ); // int lastIndex = coords.length - 1;
mcoord[lastIndex] = MCoordinate.create2dWithMeasure( x3, y3, m3 ); // mcoord[0] = MCoordinate.create2dWithMeasure( x1, y1, m1 );
// convert the middle coordinates to MCoordinate // mcoord[lastIndex] = MCoordinate.create2dWithMeasure( x3, y3, m3 );
for ( int i = 1; i < lastIndex; i++ ) { // // convert the middle coordinates to MCoordinate
mcoord[i] = MCoordinate.convertCoordinate( coords[i] ); // for ( int i = 1; i < lastIndex; i++ ) {
// if we happen to split on the middle measure, then // mcoord[i] = MCoordinate.convertCoordinate( coords[i] );
// assign it // // if we happen to split on the middle measure, then
if ( Double.compare( mcoord[i].x, x2 ) == 0 // // assign it
&& Double.compare( mcoord[i].y, y2 ) == 0 ) { // if ( Double.compare( mcoord[i].x, x2 ) == 0
mcoord[i].m = m2; // && Double.compare( mcoord[i].y, y2 ) == 0 ) {
} // mcoord[i].m = m2;
} // }
coords = mcoord; // }
// coords = mcoord;
} }
// if this is not the first arcsegment, the first linearized // if this is not the first arcsegment, the first linearized

View File

@ -23,10 +23,9 @@ package org.hibernate.spatial.dialect.oracle;
import java.util.List; import java.util.List;
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.spatial.Spatial;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
@ -35,8 +34,11 @@ import org.hibernate.type.Type;
*/ */
class WrappedOGCFunction extends StandardSQLFunction { class WrappedOGCFunction extends StandardSQLFunction {
private final boolean[] geomArrays; private final boolean[] geomArrays;
private final boolean isGeometryTyped;
/** /**
* Creates a functions that does not have a {@code Spatial} return type
*
* @param name function name * @param name function name
* @param type return type of the function * @param type return type of the function
* @param geomArrays indicates which argument places are occupied by * @param geomArrays indicates which argument places are occupied by
@ -45,13 +47,30 @@ class WrappedOGCFunction extends StandardSQLFunction {
WrappedOGCFunction(final String name, final Type type, WrappedOGCFunction(final String name, final Type type,
final boolean[] geomArrays) { final boolean[] geomArrays) {
super( name, type ); super( name, type );
if ( isSpatial( type ) ) {
throw new IllegalArgumentException(
"This constructor is only valid for functions returning non-spatial values."
);
}
this.geomArrays = geomArrays; this.geomArrays = geomArrays;
this.isGeometryTyped = false;
}
/**
* @param name function name
* @param geomArrays indicates which argument places are occupied by
* sdo_geometries
*/
WrappedOGCFunction(final String name, final boolean[] geomArrays) {
super( name );
this.geomArrays = geomArrays;
this.isGeometryTyped = true;
} }
public String render(Type firstArgumentType, final List args, public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) { final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer(); StringBuilder buf = new StringBuilder();
buf.append( "MDSYS." ).append( getName() ).append( "(" ); buf.append( "MDSYS." ).append( getName() ).append( "(" );
for ( int i = 0; i < args.size(); i++ ) { for ( int i = 0; i < args.size(); i++ ) {
if ( i > 0 ) { if ( i > 0 ) {
@ -68,8 +87,12 @@ class WrappedOGCFunction extends StandardSQLFunction {
} }
buf.append( ")" ); buf.append( ")" );
return ( getType().getReturnedClass() == Geometry.class ) ? buf return ( isGeometryTyped ) ? buf
.append( ".geom" ).toString() : buf.toString(); .append( ".geom" ).toString() : buf.toString();
} }
private boolean isSpatial(Type type) {
return Spatial.class.isAssignableFrom( type.getClass() );
}
} }

View File

@ -25,7 +25,6 @@ import org.hibernate.HibernateException;
import org.hibernate.dialect.PostgreSQL82Dialect; import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.spatial.GeometrySqlTypeDescriptor; import org.hibernate.spatial.GeometrySqlTypeDescriptor;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.SpatialAggregate; import org.hibernate.spatial.SpatialAggregate;
import org.hibernate.spatial.SpatialDialect; import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
@ -80,8 +79,7 @@ public class PostgisDialect extends PostgreSQL82Dialect implements SpatialDialec
); );
registerFunction( registerFunction(
"envelope", new StandardSQLFunction( "envelope", new StandardSQLFunction(
"st_envelope", "st_envelope"
JTSGeometryType.INSTANCE
) )
); );
registerFunction( registerFunction(
@ -110,8 +108,7 @@ public class PostgisDialect extends PostgreSQL82Dialect implements SpatialDialec
); );
registerFunction( registerFunction(
"boundary", new StandardSQLFunction( "boundary", new StandardSQLFunction(
"st_boundary", "st_boundary"
JTSGeometryType.INSTANCE
) )
); );
@ -180,43 +177,37 @@ public class PostgisDialect extends PostgreSQL82Dialect implements SpatialDialec
); );
registerFunction( registerFunction(
"buffer", new StandardSQLFunction( "buffer", new StandardSQLFunction(
"st_buffer", "st_buffer"
JTSGeometryType.INSTANCE
) )
); );
registerFunction( registerFunction(
"convexhull", new StandardSQLFunction( "convexhull", new StandardSQLFunction(
"st_convexhull", "st_convexhull"
JTSGeometryType.INSTANCE
) )
); );
registerFunction( registerFunction(
"difference", new StandardSQLFunction( "difference", new StandardSQLFunction(
"st_difference", "st_difference"
JTSGeometryType.INSTANCE
) )
); );
registerFunction( registerFunction(
"intersection", new StandardSQLFunction( "intersection", new StandardSQLFunction(
"st_intersection", new JTSGeometryType() "st_intersection")
)
); );
registerFunction( registerFunction(
"symdifference", "symdifference",
new StandardSQLFunction( "st_symdifference", JTSGeometryType.INSTANCE ) new StandardSQLFunction( "st_symdifference")
); );
registerFunction( registerFunction(
"geomunion", new StandardSQLFunction( "geomunion", new StandardSQLFunction(
"st_union", "st_union"
JTSGeometryType.INSTANCE
) )
); );
//register Spatial Aggregate function //register Spatial Aggregate function
registerFunction( registerFunction(
"extent", new StandardSQLFunction( "extent", new StandardSQLFunction(
"extent", "extent"
JTSGeometryType.INSTANCE
) )
); );
@ -229,8 +220,7 @@ public class PostgisDialect extends PostgreSQL82Dialect implements SpatialDialec
); );
registerFunction( registerFunction(
"transform", new StandardSQLFunction( "transform", new StandardSQLFunction(
"st_transform", "st_transform"
JTSGeometryType.INSTANCE
) )
); );
} }

View File

@ -22,7 +22,6 @@
package org.hibernate.spatial.dialect.postgis; package org.hibernate.spatial.dialect.postgis;
import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation; import org.hibernate.spatial.SpatialRelation;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
@ -66,8 +65,7 @@ public class PostgisNoSQLMM extends PostgisDialect {
); );
registerFunction( registerFunction(
"envelope", new StandardSQLFunction( "envelope", new StandardSQLFunction(
"envelope", "envelope"
new JTSGeometryType()
) )
); );
registerFunction( registerFunction(
@ -96,8 +94,7 @@ public class PostgisNoSQLMM extends PostgisDialect {
); );
registerFunction( registerFunction(
"boundary", new StandardSQLFunction( "boundary", new StandardSQLFunction(
"boundary", "boundary"
new JTSGeometryType()
) )
); );
@ -166,51 +163,45 @@ public class PostgisNoSQLMM extends PostgisDialect {
); );
registerFunction( registerFunction(
"buffer", new StandardSQLFunction( "buffer", new StandardSQLFunction(
"buffer", "buffer"
JTSGeometryType.INSTANCE
) )
); );
registerFunction( registerFunction(
"convexhull", new StandardSQLFunction( "convexhull", new StandardSQLFunction(
"convexhull", "convexhull"
JTSGeometryType.INSTANCE
) )
); );
registerFunction( registerFunction(
"difference", new StandardSQLFunction( "difference", new StandardSQLFunction(
"difference", "difference"
JTSGeometryType.INSTANCE
) )
); );
registerFunction( registerFunction(
"intersection", new StandardSQLFunction( "intersection", new StandardSQLFunction(
"intersection", new JTSGeometryType() "intersection"
) )
); );
registerFunction( registerFunction(
"symdifference", "symdifference",
new StandardSQLFunction( "symdifference", JTSGeometryType.INSTANCE ) new StandardSQLFunction( "symdifference")
); );
registerFunction( registerFunction(
"geomunion", new StandardSQLFunction( "geomunion", new StandardSQLFunction(
"geomunion", "geomunion"
JTSGeometryType.INSTANCE
) )
); );
//register Spatial Aggregate function //register Spatial Aggregate function
registerFunction( registerFunction(
"extent", new StandardSQLFunction( "extent", new StandardSQLFunction(
"extent", "extent"
JTSGeometryType.INSTANCE
) )
); );
//other common spatial functions //other common spatial functions
registerFunction( registerFunction(
"transform", new StandardSQLFunction( "transform", new StandardSQLFunction(
"transform", "transform"
JTSGeometryType.INSTANCE
) )
); );
} }

View File

@ -29,10 +29,10 @@ import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import org.geolatte.geom.Geometry; import org.geolatte.geom.Geometry;
import org.geolatte.geom.codec.sqlserver.Decoders;
import org.geolatte.geom.codec.sqlserver.Encoders;
import org.hibernate.spatial.GeometrySqlTypeDescriptor; import org.hibernate.spatial.GeometrySqlTypeDescriptor;
import org.hibernate.spatial.dialect.sqlserver.convertors.Decoders;
import org.hibernate.spatial.dialect.sqlserver.convertors.Encoders;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor; import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;

View File

@ -26,7 +26,6 @@ import org.hibernate.HibernateException;
import org.hibernate.dialect.SQLServer2008Dialect; import org.hibernate.dialect.SQLServer2008Dialect;
import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.spatial.GeometrySqlTypeDescriptor; import org.hibernate.spatial.GeometrySqlTypeDescriptor;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.SpatialDialect; import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation; import org.hibernate.spatial.SpatialRelation;
@ -60,13 +59,13 @@ public class SqlServer2008SpatialDialect extends SQLServer2008Dialect implements
registerFunction( "dimension", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "?1.STDimension()" ) ); registerFunction( "dimension", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "?1.STDimension()" ) );
registerFunction( "geometrytype", new SQLFunctionTemplate( StandardBasicTypes.STRING, "?1.STGeometryType()" ) ); registerFunction( "geometrytype", new SQLFunctionTemplate( StandardBasicTypes.STRING, "?1.STGeometryType()" ) );
registerFunction( "srid", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "?1.STSrid" ) ); registerFunction( "srid", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "?1.STSrid" ) );
registerFunction( "envelope", new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STEnvelope()" ) ); registerFunction( "envelope", new SqlServerMethod( "STEnvelope" ) );
registerFunction( "astext", new SQLFunctionTemplate( StandardBasicTypes.STRING, "?1.STAsText()" ) ); registerFunction( "astext", new SQLFunctionTemplate( StandardBasicTypes.STRING, "?1.STAsText()" ) );
registerFunction( "asbinary", new SQLFunctionTemplate( StandardBasicTypes.BINARY, "?1.STAsBinary()" ) ); registerFunction( "asbinary", new SQLFunctionTemplate( StandardBasicTypes.BINARY, "?1.STAsBinary()" ) );
registerFunction( "isempty", new SQLFunctionTemplate( StandardBasicTypes.BOOLEAN, "?1.STIsEmpty()" ) ); registerFunction( "isempty", new SQLFunctionTemplate( StandardBasicTypes.BOOLEAN, "?1.STIsEmpty()" ) );
registerFunction( "issimple", new SQLFunctionTemplate( StandardBasicTypes.BOOLEAN, "?1.STIsSimple()" ) ); registerFunction( "issimple", new SQLFunctionTemplate( StandardBasicTypes.BOOLEAN, "?1.STIsSimple()" ) );
registerFunction( "boundary", new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STBoundary()" ) ); registerFunction( "boundary", new SqlServerMethod( "STBoundary" ) );
// section 2.1.1.2 // section 2.1.1.2
// Register functions for spatial relation constructs // Register functions for spatial relation constructs
@ -83,18 +82,12 @@ public class SqlServer2008SpatialDialect extends SQLServer2008Dialect implements
// section 2.1.1.3 // section 2.1.1.3
// Register spatial analysis functions. // Register spatial analysis functions.
registerFunction( "distance", new SQLFunctionTemplate( StandardBasicTypes.DOUBLE, "?1.STDistance(?2)" ) ); registerFunction( "distance", new SQLFunctionTemplate( StandardBasicTypes.DOUBLE, "?1.STDistance(?2)" ) );
registerFunction( "buffer", new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STBuffer(?2)" ) ); registerFunction( "buffer", new SqlServerMethod( "STBuffer" ) );
registerFunction( "convexhull", new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STConvexHull()" ) ); registerFunction( "convexhull", new SqlServerMethod( "STConvexHull" ) );
registerFunction( "difference", new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STDifference(?2)" ) ); registerFunction( "difference", new SqlServerMethod( "STDifference" ) );
registerFunction( registerFunction( "intersection", new SqlServerMethod( "STIntersection" ) );
"intersection", registerFunction( "symdifference", new SqlServerMethod( "STSymDifference" ) );
new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STIntersection(?2)" ) registerFunction( "geomunion", new SqlServerMethod( "STUnion" ) );
);
registerFunction(
"symdifference",
new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STSymDifference(?2)" )
);
registerFunction( "geomunion", new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STUnion(?2)" ) );
// we rename OGC union to geomunion because union is a reserved SQL keyword. // we rename OGC union to geomunion because union is a reserved SQL keyword.
// (See also postgis documentation). // (See also postgis documentation).
@ -104,10 +97,9 @@ public class SqlServer2008SpatialDialect extends SQLServer2008Dialect implements
// section 2.1.9.1 methods on surfaces // section 2.1.9.1 methods on surfaces
registerFunction( "area", new SQLFunctionTemplate( StandardBasicTypes.DOUBLE, "?1.STArea()" ) ); registerFunction( "area", new SQLFunctionTemplate( StandardBasicTypes.DOUBLE, "?1.STArea()" ) );
registerFunction( "centroid", new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STCentroid()" ) ); registerFunction( "centroid", new SqlServerMethod( "STCentroid" ) );
registerFunction( registerFunction(
"pointonsurface", "pointonsurface", new SqlServerMethod( "STPointOnSurface" )
new SQLFunctionTemplate( JTSGeometryType.INSTANCE, "?1.STPointOnSurface()" )
); );
} }
@ -176,7 +168,6 @@ public class SqlServer2008SpatialDialect extends SQLServer2008Dialect implements
throw new UnsupportedOperationException( "SQL Server has no DWithin function." ); throw new UnsupportedOperationException( "SQL Server has no DWithin function." );
} }
public String getHavingSridSQL(String columnName) { public String getHavingSridSQL(String columnName) {
return columnName + ".STSrid = (?)"; return columnName + ".STSrid = (?)";
} }

View File

@ -0,0 +1,37 @@
package org.hibernate.spatial.dialect.sqlserver;
import java.util.List;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.Type;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 4/8/13
*/
public class SqlServerMethod extends StandardSQLFunction {
public SqlServerMethod(String name) {
super( name );
}
@Override
public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) {
StringBuffer buf = new StringBuffer();
if (arguments.size() < 1) {
buf.append(getName()).append("()");
} else {
buf.append( arguments.get( 0 ) ).append(".")
.append(getName()).append("(");
for ( int i = 1; i < arguments.size(); i++ ) {
buf.append(arguments.get(i));
if (i < arguments.size()-1) {
buf.append(",");
}
}
buf.append(")");
}
return buf.toString();
}
}

View File

@ -1,56 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.Geometry;
abstract class AbstractDecoder<G extends Geometry> implements Decoder<G> {
public G decode(SqlServerGeometry nativeGeom) {
if ( !accepts( nativeGeom ) ) {
throw new IllegalArgumentException( getClass().getSimpleName() + " received object of type " + nativeGeom.openGisType() );
}
if ( nativeGeom.isEmpty() ) {
G nullGeom = createNullGeometry();
return nullGeom;
}
return createGeometry( nativeGeom );
}
public boolean accepts(OpenGisType type) {
return type == getOpenGisType();
}
public boolean accepts(SqlServerGeometry nativeGeom) {
return accepts( nativeGeom.openGisType() );
}
protected abstract OpenGisType getOpenGisType();
protected abstract G createNullGeometry();
protected abstract G createGeometry(SqlServerGeometry nativeGeom);
protected abstract G createGeometry(SqlServerGeometry nativeGeom, int shapeIndex);
}

View File

@ -1,97 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.ArrayList;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.PointCollection;
abstract class AbstractEncoder<G extends Geometry> implements Encoder<G> {
public SqlServerGeometry encode(G geom) {
SqlServerGeometry nativeGeom = new SqlServerGeometry();
int srid = geom.getSRID();
nativeGeom.setSrid( srid < 0 ? 0 : srid );
nativeGeom.setIsValid();
if ( geom.isMeasured() ) {
nativeGeom.setHasMValues();
}
CountingPointSequenceBuilder coordinates = new CountingPointSequenceBuilder(geom.getDimensionalFlag(), geom.getCrsId());
List<Figure> figures = new ArrayList<Figure>();
List<Shape> shapes = new ArrayList<Shape>();
encode( geom, -1, coordinates, figures, shapes );
encodePoints( nativeGeom, coordinates.toPointSequence() );
encodeFigures( nativeGeom, figures );
encodeShapes( nativeGeom, shapes );
return nativeGeom;
}
/**
* Appends the points, figures, shapes to the resp. lists
*
* @param geom geometry to serialization
* @param parentShapeIndex index of the parent Shape for the geometry
* @param coordinates coordinate list to append to
* @param figures figure list to append to
* @param shapes shape list to append to
*/
protected abstract void encode(Geometry geom, int parentShapeIndex, CountingPointSequenceBuilder coordinates, List<Figure> figures, List<Shape> shapes);
protected void encodeShapes(SqlServerGeometry nativeGeom, List<Shape> shapes) {
nativeGeom.setNumberOfShapes( shapes.size() );
for ( int i = 0; i < shapes.size(); i++ ) {
nativeGeom.setShape( i, shapes.get( i ) );
}
}
protected void encodeFigures(SqlServerGeometry nativeGeom, List<Figure> figures) {
nativeGeom.setNumberOfFigures( figures.size() );
for ( int i = 0; i < figures.size(); i++ ) {
nativeGeom.setFigure( i, figures.get( i ) );
}
}
protected void encodePoints(SqlServerGeometry nativeGeom, PointCollection coordinates) {
nativeGeom.setNumberOfPoints( coordinates.size() );
nativeGeom.allocateMValueArray();
for ( int i = 0; i < coordinates.size(); i++ ) {
setCoordinate( nativeGeom, i, coordinates);
}
}
protected void setCoordinate(SqlServerGeometry nativeGeom, int idx, PointCollection coordinate) {
if ( !nativeGeom.hasZValues() && !Double.isNaN( coordinate.getZ(idx) ) ) {
nativeGeom.setHasZValues();
nativeGeom.allocateZValueArray();
}
nativeGeom.setCoordinate( idx, coordinate );
}
}

View File

@ -1,69 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.ArrayList;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.GeometryCollection;
abstract class AbstractGeometryCollectionDecoder<T extends GeometryCollection> extends AbstractDecoder<T> {
@Override
protected OpenGisType getOpenGisType() {
return OpenGisType.GEOMETRYCOLLECTION;
}
@Override
protected T createNullGeometry() {
return createGeometry( (List<Geometry>) null, false );
}
@Override
protected T createGeometry(SqlServerGeometry nativeGeom) {
return createGeometry( nativeGeom, 0 );
}
@Override
protected T createGeometry(SqlServerGeometry nativeGeom, int shapeIndex) {
int startChildIdx = shapeIndex + 1;
List<Geometry> geometries = new ArrayList<Geometry>( nativeGeom.getNumShapes() );
for ( int childIdx = startChildIdx; childIdx < nativeGeom.getNumShapes(); childIdx++ ) {
if ( !nativeGeom.isParentShapeOf( shapeIndex, childIdx ) ) {
continue;
}
AbstractDecoder<?> decoder = (AbstractDecoder<?>) Decoders.decoderFor(
nativeGeom.getOpenGisTypeOfShape(
childIdx
)
);
Geometry geometry = decoder.createGeometry( nativeGeom, childIdx );
geometries.add( geometry );
}
return createGeometry( geometries, nativeGeom.hasMValues() );
}
abstract protected T createGeometry(List<Geometry> geometries, boolean hasM);
}

View File

@ -1,67 +0,0 @@
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.*;
import org.geolatte.geom.crs.CrsId;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 10/19/12
*/
public class CountingPointSequenceBuilder implements PointSequenceBuilder {
final private PointSequenceBuilder delegate;
private int num = 0;
public CountingPointSequenceBuilder(DimensionalFlag df, CrsId crsId) {
delegate = PointSequenceBuilders.variableSized(df, crsId);
}
@Override
public PointSequenceBuilder add(double[] coordinates) {
num++;
return delegate.add(coordinates);
}
@Override
public PointSequenceBuilder add(double x, double y) {
num++;
return delegate.add(x, y);
}
@Override
public PointSequenceBuilder add(double x, double y, double zOrm) {
num++;
return delegate.add(x, y, zOrm);
}
@Override
public PointSequenceBuilder add(double x, double y, double z, double m) {
num++;
return delegate.add(x, y, z, m);
}
@Override
public PointSequenceBuilder add(Point pnt) {
num++;
return delegate.add(pnt);
}
@Override
public DimensionalFlag getDimensionalFlag() {
return delegate.getDimensionalFlag();
}
@Override
public CrsId getCrsId() {
return delegate.getCrsId();
}
@Override
public PointSequence toPointSequence() {
return delegate.toPointSequence();
}
public int getNumAdded(){
return num;
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.Geometry;
/**
* Decodes native database objects to geometries of type T.
*
* @author Karel Maesen, Geovise BVBA.
*/
public interface Decoder<T extends Geometry> {
public T decode(SqlServerGeometry nativeGeom);
public boolean accepts(SqlServerGeometry nativeGeom);
public boolean accepts(OpenGisType type);
}

View File

@ -1,88 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.Geometry;
import java.util.ArrayList;
import java.util.List;
/**
* Decodes SQL Server Geometry objects to JTS <code>Geometry</code>s.
*
* @author Karel Maesen, Geovise BVBA.
*/
public class Decoders {
final private static List<Decoder<? extends Geometry>> DECODERS = new ArrayList<Decoder<? extends Geometry>>();
static {
//Decoders
DECODERS.add( new PointDecoder() );
DECODERS.add( new LineStringDecoder() );
DECODERS.add( new PolygonDecoder() );
DECODERS.add( new MultiLineStringDecoder( ) );
DECODERS.add( new MultiPolygonDecoder( ) );
DECODERS.add( new MultiPointDecoder( ) );
DECODERS.add( new GeometryCollectionDecoder( ) );
}
private static Decoder<? extends Geometry> decoderFor(SqlServerGeometry object) {
for ( Decoder<? extends Geometry> decoder : DECODERS ) {
if ( decoder.accepts( object ) ) {
return decoder;
}
}
throw new IllegalArgumentException( "No decoder for type " + object.openGisType() );
}
/**
* Decodes the SQL Server Geometry object to its JTS Geometry instance
*
* @param raw
*
* @return
*/
public static Geometry decode(byte[] raw) {
SqlServerGeometry sqlServerGeom = SqlServerGeometry.deserialize( raw );
Decoder decoder = decoderFor( sqlServerGeom );
return decoder.decode( sqlServerGeom );
}
/**
* Returns the decoder capable of decoding an object of the specified OpenGisType
*
* @param type OpenGisType for which a decoder is returned
*
* @return
*/
public static Decoder<? extends Geometry> decoderFor(OpenGisType type) {
for ( Decoder<? extends Geometry> decoder : DECODERS ) {
if ( decoder.accepts( type ) ) {
return decoder;
}
}
throw new IllegalArgumentException( "No decoder for type " + type );
}
}

View File

@ -1,38 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.Geometry;
/**
* An <code>Encoder</code> can encode
* geometries of type T to a <code>SqlServerGeometry</code>.
*
* @author Karel Maesen, Geovise BVBA.
*/
public interface Encoder<T extends Geometry> {
public SqlServerGeometry encode(T geom);
public boolean accepts(Geometry geom);
}

View File

@ -1,70 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.ArrayList;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.GeometryCollection;
import org.geolatte.geom.MultiLineString;
import org.geolatte.geom.MultiPoint;
import org.geolatte.geom.MultiPolygon;
/**
* Serializes a JTS <code>Geometry</code> to a byte-array.
*
* @author Karel Maesen, Geovise BVBA.
*/
public class Encoders {
final private static List<Encoder<? extends Geometry>> ENCODERS = new ArrayList<Encoder<? extends Geometry>>();
static {
//Encoders
ENCODERS.add( new PointEncoder() );
ENCODERS.add( new LineStringEncoder() );
ENCODERS.add( new PolygonEncoder() );
ENCODERS.add( new GeometryCollectionEncoder<MultiPoint>(OpenGisType.MULTIPOINT) );
ENCODERS.add( new GeometryCollectionEncoder<MultiLineString>( OpenGisType.MULTILINESTRING ) );
ENCODERS.add( new GeometryCollectionEncoder<MultiPolygon>( OpenGisType.MULTIPOLYGON ) );
ENCODERS.add( new GeometryCollectionEncoder<GeometryCollection>( OpenGisType.GEOMETRYCOLLECTION ) );
}
public static Encoder<? extends Geometry> encoderFor(Geometry geom) {
for ( Encoder<? extends Geometry> encoder : ENCODERS ) {
if ( encoder.accepts( geom ) ) {
return encoder;
}
}
throw new IllegalArgumentException( "No encoder for type " + geom.getGeometryType() );
}
public static <T extends Geometry> byte[] encode(T geom) {
Encoder<T> encoder = (Encoder<T>) encoderFor( geom );
SqlServerGeometry sqlServerGeometry = encoder.encode( geom );
return SqlServerGeometry.serialize( sqlServerGeometry );
}
}

View File

@ -1,58 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.nio.ByteBuffer;
class Figure {
final FigureAttribute figureAttribute;
final int pointOffset;
Figure(FigureAttribute attribute, int offset) {
this.figureAttribute = attribute;
this.pointOffset = offset;
}
static int getByteSize() {
return 5;
}
void store(ByteBuffer buffer) {
buffer.put( figureAttribute.byteValue );
buffer.putInt( pointOffset );
}
boolean isInteriorRing() {
return this.figureAttribute.equals( FigureAttribute.InteriorRing );
}
boolean isExteriorRing() {
return this.figureAttribute.equals( FigureAttribute.ExteriorRing );
}
boolean isStroke() {
return this.figureAttribute.equals( FigureAttribute.Stroke );
}
}

View File

@ -1,48 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
/**
* @author Karel Maesen, Geovise BVBA
* @Date 2009-11-29
*/
enum FigureAttribute {
InteriorRing( (byte) 0 ),
Stroke( (byte) 1 ),
ExteriorRing( (byte) 2 );
final byte byteValue;
FigureAttribute(byte v) {
byteValue = v;
}
static FigureAttribute valueOf(byte b) {
for ( FigureAttribute fa : values() ) {
if ( fa.byteValue == b ) {
return fa;
}
}
throw new IllegalArgumentException( String.format( "Can't interpret value %d as FigureAttribute.", b ) );
}
}

View File

@ -1,48 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.GeometryCollection;
/**
* <code>Decoder</code> for GeometryCollections.
*
* @Author Karel Maesen
*/
class GeometryCollectionDecoder extends AbstractGeometryCollectionDecoder<GeometryCollection> {
@Override
protected OpenGisType getOpenGisType() {
return OpenGisType.GEOMETRYCOLLECTION;
}
protected GeometryCollection createGeometry(List<Geometry> geometries, boolean hasM) {
Geometry[] geomArray = geometries != null ? geometries.toArray( new Geometry[geometries.size()] ) : null;
return new GeometryCollection( geomArray );
}
}

View File

@ -1,74 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.GeometryCollection;
/**
* <code>Encoder</code> for GeometryCollections.
*
* @Author Karel Maesen
*/
class GeometryCollectionEncoder<T extends GeometryCollection> extends AbstractEncoder<T> {
private final OpenGisType openGisType;
GeometryCollectionEncoder(OpenGisType openGisType) {
this.openGisType = openGisType;
}
public boolean accepts(Geometry geom) {
return this.openGisType.typeOf( geom );
}
@Override
protected void encode(Geometry geom, int parentShapeIndex, CountingPointSequenceBuilder coordinates, List<Figure> figures, List<Shape> shapes) {
if ( geom.isEmpty() ) {
shapes.add( new Shape( parentShapeIndex, -1, this.openGisType ) );
return;
}
int thisShapeIndex = shapes.size();
Shape thisShape = createShape( parentShapeIndex, figures );
shapes.add( thisShape );
if (! (geom instanceof GeometryCollection)) {
throw new IllegalArgumentException( "Expect GeometryCollection argument." );
}
GeometryCollection gc = (GeometryCollection) geom;
for ( int i = 0; i < gc.getNumGeometries(); i++ ) {
Geometry component = gc.getGeometryN( i );
encodeComponent( component, thisShapeIndex, coordinates, figures, shapes );
}
}
protected Shape createShape(int parentShapeIndex, List<Figure> figures) {
Shape thisShape = new Shape( parentShapeIndex, figures.size(), this.openGisType );
return thisShape;
}
protected void encodeComponent(Geometry geom, int thisShapeIndex, CountingPointSequenceBuilder coordinates, List<Figure> figures, List<Shape> shapes) {
AbstractEncoder<? extends Geometry> encoder = (AbstractEncoder<? extends Geometry>) Encoders.encoderFor( geom );
encoder.encode( geom, thisShapeIndex, coordinates, figures, shapes );
}
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
/**
* A Range of indices.
*/
class IndexRange {
final int start;
final int end;
IndexRange(int start, int end) {
this.start = start;
this.end = end;
}
int length() {
return this.end - this.start;
}
}

View File

@ -1,57 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.LineString;
import org.geolatte.geom.PointSequence;
class LineStringDecoder extends AbstractDecoder<LineString> {
@Override
protected OpenGisType getOpenGisType() {
return OpenGisType.LINESTRING;
}
protected LineString createNullGeometry() {
return LineString.createEmpty();
}
protected LineString createGeometry(SqlServerGeometry nativeGeom) {
return createLineString( nativeGeom, new IndexRange( 0, nativeGeom.getNumPoints() ) );
}
@Override
protected LineString createGeometry(SqlServerGeometry nativeGeom, int shapeIndex) {
if ( nativeGeom.isEmptyShape( shapeIndex ) ) {
return createNullGeometry();
}
int figureOffset = nativeGeom.getFiguresForShape( shapeIndex ).start;
IndexRange pntIndexRange = nativeGeom.getPointsForFigure( figureOffset );
return createLineString( nativeGeom, pntIndexRange );
}
protected LineString createLineString(SqlServerGeometry nativeGeom, IndexRange pntIndexRange) {
PointSequence coordinates = nativeGeom.coordinateRange( pntIndexRange );
return new LineString(coordinates);
}
}

View File

@ -1,64 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.LineString;
import org.geolatte.geom.Point;
import org.geolatte.geom.PointCollection;
import org.geolatte.geom.PointSequence;
class LineStringEncoder extends AbstractEncoder<LineString> {
@Override
protected void encode(Geometry geom, int parentShapeIndex, CountingPointSequenceBuilder coordinates, List<Figure> figures, List<Shape> shapes) {
if ( !( geom instanceof LineString ) ) {
throw new IllegalArgumentException( "Require LineString geometry" );
}
if ( geom.isEmpty() ) {
shapes.add( new Shape( parentShapeIndex, -1, OpenGisType.LINESTRING ) );
return;
}
int figureOffset = figures.size();
int pointOffset = coordinates.getNumAdded();
for ( Point point : (PointSequence)geom.getPoints() ) {
coordinates.add( point );
}
figures.add( new Figure( FigureAttribute.Stroke, pointOffset ) );
shapes.add( new Shape( parentShapeIndex, figureOffset, OpenGisType.LINESTRING ) );
}
@Override
protected void encodePoints(SqlServerGeometry nativeGeom, PointCollection coordinates) {
super.encodePoints( nativeGeom, coordinates );
if ( coordinates.size() == 2 ) {
nativeGeom.setIsSingleLineSegment();
}
}
public boolean accepts(Geometry geom) {
return geom instanceof LineString;
}
}

View File

@ -1,45 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.LineString;
import org.geolatte.geom.MultiLineString;
class MultiLineStringDecoder extends AbstractGeometryCollectionDecoder<MultiLineString> {
@Override
protected OpenGisType getOpenGisType() {
return OpenGisType.MULTILINESTRING;
}
@Override
protected MultiLineString createGeometry(List<Geometry> geometries, boolean hasM) {
LineString[] lAr = geometries != null ? geometries.toArray( new LineString[geometries.size()] ) : null;
return new MultiLineString( lAr );
}
}

View File

@ -1,49 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.MultiPoint;
import org.geolatte.geom.Point;
/**
* <code>Decoder</code> for GeometryCollections.
*
* @author Karel Maesen, Geovise BVBA
*/
class MultiPointDecoder extends AbstractGeometryCollectionDecoder<MultiPoint> {
@Override
protected OpenGisType getOpenGisType() {
return OpenGisType.MULTIPOINT;
}
@Override
protected MultiPoint createGeometry(List<Geometry> geometries, boolean hasM) {
Point[] points = geometries != null ? geometries.toArray( new Point[geometries.size()] ) : null;
return new MultiPoint( points );
}
}

View File

@ -1,44 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.MultiPolygon;
import org.geolatte.geom.Polygon;
class MultiPolygonDecoder extends AbstractGeometryCollectionDecoder<MultiPolygon> {
@Override
protected OpenGisType getOpenGisType() {
return OpenGisType.MULTIPOLYGON;
}
@Override
protected MultiPolygon createGeometry(List<Geometry> geometries, boolean hasM) {
Polygon[] polygons = geometries != null ? geometries.toArray( new Polygon[geometries.size()] ) : null;
return new MultiPolygon( polygons );
}
}

View File

@ -1,70 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.GeometryCollection;
import org.geolatte.geom.LineString;
import org.geolatte.geom.MultiLineString;
import org.geolatte.geom.MultiPoint;
import org.geolatte.geom.MultiPolygon;
import org.geolatte.geom.Point;
import org.geolatte.geom.Polygon;
/**
* The type of geometry.
*
* @author Karel Maesen, Geovise BVBA.
* Date: Nov 2, 2009
*/
public enum OpenGisType {
POINT( (byte) 1, Point.class ),
LINESTRING( (byte) 2, LineString.class ),
POLYGON( (byte) 3, Polygon.class ),
MULTIPOINT( (byte) 4, MultiPoint.class ),
MULTILINESTRING( (byte) 5, MultiLineString.class ),
MULTIPOLYGON( (byte) 6, MultiPolygon.class ),
GEOMETRYCOLLECTION( (byte) 7, GeometryCollection.class ),
INVALID_TYPE( (byte) 0, null );
final byte byteValue;
final Class geomClass;
OpenGisType(byte v, Class geomClass) {
this.byteValue = v;
this.geomClass = geomClass;
}
boolean typeOf(Object o) {
return geomClass.isAssignableFrom( o.getClass() );
}
static OpenGisType valueOf(byte b) {
for ( OpenGisType t : values() ) {
if ( t.byteValue == b ) {
return t;
}
}
return INVALID_TYPE;
}
}

View File

@ -1,66 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.DimensionalFlag;
import org.geolatte.geom.Point;
import org.geolatte.geom.PointSequence;
/**
* @author Karel Maesen, Geovise BVBA.
* Date: Nov 2, 2009
*/
class PointDecoder extends AbstractDecoder<Point> {
@Override
protected OpenGisType getOpenGisType() {
return OpenGisType.POINT;
}
protected Point createNullGeometry() {
return Point.createEmpty();
}
protected Point createGeometry(SqlServerGeometry nativeGeom) {
return createPoint( nativeGeom, 0 );
}
@Override
protected Point createGeometry(SqlServerGeometry nativeGeom, int shapeIndex) {
if ( nativeGeom.isEmptyShape( shapeIndex ) ) {
return createNullGeometry();
}
int figureOffset = nativeGeom.getFiguresForShape( shapeIndex ).start;
int pntOffset = nativeGeom.getPointsForFigure( figureOffset ).start;
return createPoint( nativeGeom, pntOffset );
}
private Point createPoint(SqlServerGeometry nativeGeom, int pntOffset) {
DimensionalFlag df = DimensionalFlag.valueOf(nativeGeom.hasZValues(), nativeGeom.hasMValues());
PointSequence pointSequence = nativeGeom.coordinateRange(new IndexRange(pntOffset, pntOffset + 1));
return new Point(pointSequence);
}
}

View File

@ -1,96 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.util.List;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.Point;
/**
* @author Karel Maesen, Geovise BVBA.
* Date: Nov 2, 2009
*/
class PointEncoder extends AbstractEncoder<Point> {
/**
* Encodes a point as an <code>SQLGeometryV1</code> object.
* <p/>
* This is a specific implementation because points don't explicitly serialize figure and shape components.
*
* @param geom Geometry to serialize
*
* @return
*/
@Override
public SqlServerGeometry encode(Point geom) {
SqlServerGeometry sqlServerGeom = new SqlServerGeometry();
int srid = geom.getSRID();
sqlServerGeom.setSrid( srid < 0 ? 0 : srid );
sqlServerGeom.setIsValid();
if ( geom.isEmpty() ) {
sqlServerGeom.setNumberOfPoints( 0 );
sqlServerGeom.setNumberOfFigures( 0 );
sqlServerGeom.setNumberOfShapes( 1 );
sqlServerGeom.setShape( 0, new Shape( -1, -1, OpenGisType.POINT ) );
return sqlServerGeom;
}
sqlServerGeom.setIsSinglePoint();
sqlServerGeom.setNumberOfPoints( 1 );
if ( geom.is3D() ) {
sqlServerGeom.setHasZValues();
sqlServerGeom.allocateZValueArray();
}
if ( geom.isMeasured() ) {
sqlServerGeom.setHasMValues();
sqlServerGeom.allocateMValueArray();
}
sqlServerGeom.setCoordinate( 0, geom.getPoints() );
return sqlServerGeom;
}
@Override
protected void encode(Geometry geom, int parentIdx, CountingPointSequenceBuilder coordinates, List<Figure> figures, List<Shape> shapes) {
if ( !( geom instanceof Point ) ) {
throw new IllegalArgumentException( "Require Point geometry" );
}
if ( geom.isEmpty() ) {
shapes.add( new Shape( parentIdx, -1, OpenGisType.POINT ) );
return;
}
int pntOffset = coordinates.getNumAdded();
int figureOffset = figures.size();
coordinates.add( geom.getPointN(0) );
Figure figure = new Figure( FigureAttribute.Stroke, pntOffset );
figures.add( figure );
Shape shape = new Shape( parentIdx, figureOffset, OpenGisType.POINT );
shapes.add( shape );
}
public boolean accepts(Geometry geom) {
return geom instanceof Point;
}
}

View File

@ -1,72 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.LinearRing;
import org.geolatte.geom.PointSequence;
import org.geolatte.geom.Polygon;
/**
* @author Karel Maesen, Geovise BVBA
*/
class PolygonDecoder extends AbstractDecoder<Polygon> {
@Override
protected OpenGisType getOpenGisType() {
return OpenGisType.POLYGON;
}
protected Polygon createNullGeometry() {
return Polygon.createEmpty();
}
protected Polygon createGeometry(SqlServerGeometry nativeGeom) {
return createGeometry( nativeGeom, 0 );
}
protected Polygon createGeometry(SqlServerGeometry nativeGeom, int shapeIndex) {
if ( nativeGeom.isEmptyShape( shapeIndex ) ) {
return createNullGeometry();
}
//polygons consist of one exterior ring figure, and several interior ones.
IndexRange figureRange = nativeGeom.getFiguresForShape( shapeIndex );
LinearRing[] rings = new LinearRing[figureRange.length()];
//the rings should contain all inner rings from index 1 to index length - 1
// index = 0 should be reserved for the shell.
for ( int figureIdx = figureRange.start, i = 1; figureIdx < figureRange.end; figureIdx++ ) {
IndexRange pntIndexRange = nativeGeom.getPointsForFigure( figureIdx );
if ( nativeGeom.isFigureInteriorRing( figureIdx ) ) {
rings[i++] = toLinearRing( nativeGeom, pntIndexRange );
}
else {
rings[0] = toLinearRing( nativeGeom, pntIndexRange );
}
}
return new Polygon(rings);
}
private LinearRing toLinearRing(SqlServerGeometry nativeGeom, IndexRange range) {
PointSequence pointSequence = nativeGeom.coordinateRange(range);
return new LinearRing(pointSequence);
}
}

View File

@ -1,88 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.*;
import java.util.List;
/**
* <code>Encoder</code> for Polygons.
*
* @uthor Karel Maesen, Geovise BVBA
*/
class PolygonEncoder extends AbstractEncoder<Polygon> {
public boolean accepts(Geometry geom) {
return geom instanceof Polygon;
}
@Override
protected void encode(Geometry geom, int parentShapeIndex, CountingPointSequenceBuilder coordinates, List<Figure> figures, List<Shape> shapes) {
if ( !( geom instanceof Polygon ) ) {
throw new IllegalArgumentException( "Polygon geometry expected." );
}
if ( geom.isEmpty() ) {
shapes.add( new Shape( parentShapeIndex, -1, OpenGisType.POLYGON ) );
return;
}
Polygon polygon = (Polygon) geom;
int figureOffset = figures.size();
shapes.add( new Shape( parentShapeIndex, figureOffset, OpenGisType.POLYGON ) );
int pointOffset = coordinates.getNumAdded();
addExteriorRing( polygon, coordinates, figures );
addInteriorRings( polygon, coordinates, figures );
}
private void addInteriorRings(Polygon geom, CountingPointSequenceBuilder coordinates, List<Figure> figures) {
for ( int idx = 0; idx < geom.getNumInteriorRing(); idx++ ) {
addInteriorRing( geom.getInteriorRingN( idx ), coordinates, figures );
}
}
private void addInteriorRing(LineString ring,CountingPointSequenceBuilder coordinates, List<Figure> figures) {
int pointOffset = coordinates.getNumAdded();
addPoints( ring, coordinates );
Figure figure = new Figure( FigureAttribute.InteriorRing, pointOffset );
figures.add( figure );
}
private void addPoints(LineString ring, CountingPointSequenceBuilder coordinates) {
for ( Point c : ring.getPoints() ) {
coordinates.add( c );
}
}
private void addExteriorRing(Polygon geom, CountingPointSequenceBuilder coordinates, List<Figure> figures) {
LineString shell = geom.getExteriorRing();
int offset = coordinates.getNumAdded();
addPoints( shell, coordinates );
Figure exterior = new Figure( FigureAttribute.ExteriorRing, offset );
figures.add( exterior );
}
}

View File

@ -1,46 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.nio.ByteBuffer;
class Shape {
final int parentOffset;
final int figureOffset;
final OpenGisType openGisType;
Shape(int parentOffset, int figureOffset, OpenGisType openGisType) {
this.figureOffset = figureOffset;
this.parentOffset = parentOffset;
this.openGisType = openGisType;
}
static int getByteSize() {
return 9;
}
void store(ByteBuffer buffer) {
buffer.putInt( parentOffset );
buffer.putInt( figureOffset );
buffer.put( openGisType.byteValue );
}
}

View File

@ -1,485 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import com.vividsolutions.jts.geom.Coordinate;
import org.geolatte.geom.DimensionalFlag;
import org.geolatte.geom.PointCollection;
import org.geolatte.geom.PointSequence;
import org.geolatte.geom.PointSequenceBuilder;
import org.geolatte.geom.PointSequenceBuilders;
import org.geolatte.geom.crs.CrsId;
import org.hibernate.spatial.jts.mgeom.MCoordinate;
/**
* A <code>SqlServerGeometry</code> represents the native SQL Server database object.
* <p/>
* <p>Instances are created by deserializing the byte array returned in the JDBC result set.
* They present the structure of the SQL Server Geometry object as specified in <a href="http://download.microsoft.com/download/7/9/3/79326E29-1E2E-45EE-AA73-74043587B17D/%5BMS-SSCLRT%5D.pdf">Microsoft SQL Server CLR Types Serialization Formats</a> .
*
* @author Karel Maesen, Geovise BVBA.
*/
public class SqlServerGeometry {
public static final byte SUPPORTED_VERSION = 1;
private static final byte hasZValuesMask = 1;
private static final byte hasMValuesMask = 2;
private static final byte isValidMask = 4;
private static final byte isSinglePointMask = 8;
private static final byte isSingleLineSegment = 16;
private ByteBuffer buffer;
private Integer srid;
private byte version;
private byte serializationPropertiesByte;
private int numberOfPoints;
private double[] points;
private double[] mValues;
private double[] zValues;
private int numberOfFigures;
private Figure[] figures = null;
private int numberOfShapes;
private Shape[] shapes = null;
private SqlServerGeometry(byte[] bytes) {
buffer = ByteBuffer.wrap( bytes );
buffer.order( ByteOrder.LITTLE_ENDIAN );
}
SqlServerGeometry() {
}
public static byte[] serialize(SqlServerGeometry sqlServerGeom) {
int capacity = sqlServerGeom.calculateCapacity();
ByteBuffer buffer = ByteBuffer.allocate( capacity );
buffer.order( ByteOrder.LITTLE_ENDIAN );
buffer.putInt( sqlServerGeom.srid );
buffer.put( SUPPORTED_VERSION );
buffer.put( sqlServerGeom.serializationPropertiesByte );
if ( !sqlServerGeom.isSinglePoint() && !sqlServerGeom.isSingleLineSegment() ) {
buffer.putInt( sqlServerGeom.numberOfPoints );
}
for ( int i = 0; i < sqlServerGeom.getNumPoints(); i++ ) {
buffer.putDouble( sqlServerGeom.points[2 * i] );
buffer.putDouble( sqlServerGeom.points[2 * i + 1] );
}
if ( sqlServerGeom.hasZValues() ) {
for ( int i = 0; i < sqlServerGeom.zValues.length; i++ ) {
buffer.putDouble( sqlServerGeom.zValues[i] );
}
}
if ( sqlServerGeom.hasMValues() ) {
for ( int i = 0; i < sqlServerGeom.mValues.length; i++ ) {
buffer.putDouble( sqlServerGeom.mValues[i] );
}
}
if ( sqlServerGeom.isSingleLineSegment() || sqlServerGeom.isSinglePoint() ) {
return buffer.array();
}
//in all other cases, we continue to serialize shapes and figures
buffer.putInt( sqlServerGeom.getNumFigures() );
for ( int i = 0; i < sqlServerGeom.getNumFigures(); i++ ) {
sqlServerGeom.getFigure( i ).store( buffer );
}
buffer.putInt( sqlServerGeom.getNumShapes() );
for ( int i = 0; i < sqlServerGeom.getNumShapes(); i++ ) {
sqlServerGeom.getShape( i ).store( buffer );
}
return buffer.array();
}
public static SqlServerGeometry deserialize(byte[] bytes) {
SqlServerGeometry result = new SqlServerGeometry( bytes );
result.parse();
return result;
}
void copyCoordinate(int index, double[] coords, DimensionalFlag df) {
coords[0] = points[2 * index];
coords[1] = points[2 * index + 1];
if ( hasZValues() ) {
assert ( df.is3D() );
coords[df.Z] = zValues[index];
}
if ( hasMValues() ) {
assert ( df.isMeasured() );
coords[df.M] = mValues[index];
}
}
boolean isParentShapeOf(int parent, int child) {
return getShape( child ).parentOffset == parent;
}
boolean isEmptyShape(int shapeIndex) {
return getShape( shapeIndex ).figureOffset == -1;
}
IndexRange getFiguresForShape(int shapeIndex) {
int startIdx = getShape( shapeIndex ).figureOffset;
if ( startIdx == -1 ) {
return new IndexRange( -1, -1 ); //empty figures
}
int endIdx = -1;
int nextShapeIdx = shapeIndex + 1;
if ( nextShapeIdx == getNumShapes() ) {
endIdx = getNumFigures();
}
else {
endIdx = getShape( nextShapeIdx ).figureOffset;
}
return new IndexRange( startIdx, endIdx );
}
/**
* Returns the range of indices in the point array for the specified figure.
*
* @param figureIndex index to shape in shape array
*
* @return index range for
*/
IndexRange getPointsForFigure(int figureIndex) {
int start = getFigure( figureIndex ).pointOffset;
int end = -1;
int nextFigure = figureIndex + 1;
if ( nextFigure == getNumFigures() ) {
end = getNumPoints();
}
else {
end = getFigure( nextFigure ).pointOffset;
}
return new IndexRange( start, end );
}
boolean isFigureInteriorRing(int figureIdx) {
return getFigure( figureIdx ).isInteriorRing();
}
OpenGisType getOpenGisTypeOfShape(int shpIdx) {
return getShape( shpIdx ).openGisType;
}
PointSequence coordinateRange(IndexRange range) {
DimensionalFlag df = DimensionalFlag.valueOf( hasZValues(), hasMValues() );
PointSequenceBuilder psBuilder = PointSequenceBuilders.fixedSized(
range.end - range.start,
df,
CrsId.valueOf( getSrid() )
);
double[] coordinates = new double[df.getCoordinateDimension()];
for ( int idx = range.start, i = 0; idx < range.end; idx++, i++ ) {
copyCoordinate( idx, coordinates, df );
psBuilder.add( coordinates );
}
return psBuilder.toPointSequence();
}
private Coordinate[] createCoordinateArray(int size) {
if ( hasMValues() ) {
return new MCoordinate[size];
}
else {
return new Coordinate[size];
}
}
private Figure getFigure(int index) {
return figures[index];
}
private Shape getShape(int index) {
return shapes[index];
}
void setCoordinate(int index, PointCollection coordinate) {
points[2 * index] = coordinate.getX( index );
points[2 * index + 1] = coordinate.getY( index );
if ( hasZValues() ) {
zValues[index] = coordinate.getZ( index );
}
if ( hasMValues() ) {
mValues[index] = coordinate.getM( index );
}
}
boolean isEmpty() {
return this.numberOfPoints == 0;
}
OpenGisType openGisType() {
if ( isValid() && isSinglePoint() ) {
return OpenGisType.POINT;
}
if ( isValid() && isSingleLineSegment() ) {
return OpenGisType.LINESTRING;
}
return firstShapeOpenGisType();
}
void setHasZValues() {
serializationPropertiesByte |= hasZValuesMask;
}
void allocateZValueArray() {
if ( this.hasZValues() ) {
this.zValues = new double[this.numberOfPoints];
}
}
void allocateMValueArray() {
if ( this.hasMValues() ) {
this.mValues = new double[this.numberOfPoints];
}
}
void setHasMValues() {
serializationPropertiesByte |= hasMValuesMask;
}
void setIsValid() {
serializationPropertiesByte |= isValidMask;
}
void setIsSinglePoint() {
setNumberOfPoints( 1 );
serializationPropertiesByte |= isSinglePointMask;
}
void setIsSingleLineSegment() {
serializationPropertiesByte |= isSingleLineSegment;
}
int getNumPoints() {
return this.numberOfPoints;
}
void setNumberOfPoints(int num) {
this.numberOfPoints = num;
this.points = new double[2 * this.numberOfPoints];
}
private void parse() {
srid = buffer.getInt();
version = buffer.get();
if ( !isCompatible() ) {
throw new IllegalStateException( "Version mismatch. Expected version " + SUPPORTED_VERSION + ", but received version " + version );
}
serializationPropertiesByte = buffer.get();
determineNumberOfPoints();
readPoints();
if ( hasZValues() ) {
readZValues();
}
if ( hasMValues() ) {
readMValues();
}
if ( isSingleLineSegment() ||
isSinglePoint() ) {
//generate figure and shape.
// These are assumed, not explicitly encoded in the
// serialized data. See specs.
setNumberOfFigures( 1 );
setFigure( 0, new Figure( FigureAttribute.Stroke, 0 ) );
setNumberOfShapes( 1 );
OpenGisType gisType = isSinglePoint() ? OpenGisType.POINT : OpenGisType.LINESTRING;
setShape( 0, new Shape( -1, 0, gisType ) );
return;
}
//in all other cases, figures and shapes are
//explicitly encoded.
readFigures();
readShapes();
}
private void readShapes() {
setNumberOfShapes( buffer.getInt() );
for ( int sIdx = 0; sIdx < numberOfShapes; sIdx++ ) {
int parentOffset = buffer.getInt();
int figureOffset = buffer.getInt();
byte ogtByte = buffer.get();
OpenGisType type = OpenGisType.valueOf( ogtByte );
Shape shape = new Shape( parentOffset, figureOffset, type );
setShape( sIdx, shape );
}
}
private void readFigures() {
setNumberOfFigures( buffer.getInt() );
for ( int fIdx = 0; fIdx < numberOfFigures; fIdx++ ) {
byte faByte = buffer.get();
int pointOffset = buffer.getInt();
FigureAttribute fa = FigureAttribute.valueOf( faByte );
Figure figure = new Figure( fa, pointOffset );
setFigure( fIdx, figure );
}
}
private OpenGisType firstShapeOpenGisType() {
if ( shapes == null || shapes.length == 0 ) {
return OpenGisType.INVALID_TYPE;
}
return shapes[0].openGisType;
}
private int calculateCapacity() {
int numPoints = getNumPoints();
int prefixSize = 6;
if ( isSinglePoint() ||
isSingleLineSegment() ) {
int capacity = prefixSize + 16 * numPoints;
if ( hasZValues() ) {
capacity += 8 * numPoints;
}
if ( hasMValues() ) {
capacity += 8 * numPoints;
}
return capacity;
}
int pointSize = getPointByteSize();
int size = prefixSize + 3 * 4; // prefix + 3 ints for points, shapes and figures
size += getNumPoints() * pointSize;
size += getNumFigures() * Figure.getByteSize();
size += getNumShapes() * Shape.getByteSize();
return size;
}
int getNumShapes() {
return this.numberOfShapes;
}
private int getPointByteSize() {
int size = 16; //for X/Y values
if ( hasMValues() ) {
size += 8;
}
if ( hasZValues() ) {
size += 8;
}
return size;
}
private void readPoints() {
points = new double[2 * numberOfPoints];
for ( int i = 0; i < numberOfPoints; i++ ) {
points[2 * i] = buffer.getDouble();
points[2 * i + 1] = buffer.getDouble();
}
}
private void readZValues() {
zValues = new double[numberOfPoints];
for ( int i = 0; i < numberOfPoints; i++ ) {
zValues[i] = buffer.getDouble();
}
}
private void readMValues() {
mValues = new double[numberOfPoints];
for ( int i = 0; i < numberOfPoints; i++ ) {
mValues[i] = buffer.getDouble();
}
}
private void determineNumberOfPoints() {
if ( isSinglePoint() ) {
numberOfPoints = 1;
return;
}
if ( isSingleLineSegment() ) {
numberOfPoints = 2;
return;
}
numberOfPoints = buffer.getInt();
}
boolean isCompatible() {
return version == SUPPORTED_VERSION;
}
void setSrid(Integer srid) {
this.srid = ( srid == null ) ? -1 : srid;
}
Integer getSrid() {
return srid != -1 ? srid : null;
}
boolean hasZValues() {
return ( serializationPropertiesByte & hasZValuesMask ) != 0;
}
boolean hasMValues() {
return ( serializationPropertiesByte & hasMValuesMask ) != 0;
}
boolean isValid() {
return ( serializationPropertiesByte & isValidMask ) != 0;
}
boolean isSinglePoint() {
return ( serializationPropertiesByte & isSinglePointMask ) != 0;
}
boolean isSingleLineSegment() {
return ( serializationPropertiesByte & isSingleLineSegment ) != 0;
}
void setNumberOfFigures(int num) {
numberOfFigures = num;
figures = new Figure[numberOfFigures];
}
void setFigure(int i, Figure figure) {
figures[i] = figure;
}
void setNumberOfShapes(int num) {
numberOfShapes = num;
shapes = new Shape[numberOfShapes];
}
void setShape(int i, Shape shape) {
shapes[i] = shape;
}
int getNumFigures() {
return this.numberOfFigures;
}
}

View File

@ -1,34 +0,0 @@
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2012 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
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
</head>
<body>
<p>Provides classes to translate between SQL Server Geometries and JTS <code>Geometry</code>s. </p>
<p>The binary format of a SQL Server Geometry is specified in <a
href="http://download.microsoft.com/download/7/9/3/79326E29-1E2E-45EE-AA73-74043587B17D/%5BMS-SSCLRT%5D.pdf">Microsoft
SQL Server CLR Types Serialization Formats</a>.</p>
</body>
</html>

View File

@ -1,44 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts;
import org.hibernate.spatial.jts.mgeom.MGeometryFactory;
/**
* A static utility class
*
* @author Karel Maesen
*/
public class JTS {
private static MGeometryFactory defaultGeomFactory = new MGeometryFactory();
/**
* Make sure nobody can instantiate this class
*/
private JTS() {
}
public static MGeometryFactory getDefaultGeometryFactory() {
return defaultGeomFactory;
}
}

View File

@ -1,76 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import java.util.ArrayList;
import java.util.List;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
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() );
}
}

View File

@ -1,224 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import java.io.Serializable;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Envelope;
/**
* 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();
}
}

View File

@ -1,80 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.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 );
}
}

View File

@ -1,177 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import java.io.Serializable;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
* 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>.
* <p/>
* Modifying the returned <code>Geometry</code> will result in internal state changes.
*
* @return this object as a Geometry.
*/
public Geometry asGeometry();
}

View File

@ -1,61 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.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;
}
}

View File

@ -1,102 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.PrecisionModel;
/**
* 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
*
* @return An instance of MLineString containing the coordinates
*
* @see #createLineString(com.vividsolutions.jts.geom.Coordinate[])
*/
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 );
}
}

View File

@ -1,758 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import java.util.ArrayList;
import java.util.List;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateArrays;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineSegment;
import com.vividsolutions.jts.geom.LineString;
/**
* 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.hibernate.spatial.mgeom.MGeometry##MGeometry#getMaxM()
*/
public double getMaxM() {
if ( this.isEmpty() ) {
return Double.NaN;
}
else {
double[] measures = this.getMeasures();
if ( this.getMeasureDirection() == INCREASING ) {
return measures[measures.length - 1];
}
else if ( this.getMeasureDirection() == DECREASING
|| this.getMeasureDirection() == CONSTANT ) {
return measures[0];
}
else {
double ma = Double.NEGATIVE_INFINITY;
for ( int i = 0; i < measures.length; i++ ) {
if ( ma < measures[i] ) {
ma = measures[i];
}
}
return ma;
}
}
}
/**
* Copies the coordinates of the specified array that fall between fromM and toM to a CoordinateSubSequence.
* <p/>
* The CoordinateSubSequence also contains the array indices of the first and last coordinate in firstIndex, resp.
* lastIndex. If there are no coordinates between fromM and toM, then firstIndex will contain -1, and lastIndex
* will point to the coordinate that is close to fromM or toM.
* <p/>
* This function expects that fromM is less than or equal to toM, and that the coordinates in the array are
* sorted monotonic w.r.t. to their m-values.
*
* @param mcoordinates
* @param fromM
* @param toM
* @param direction INCREASING or DECREASING
*
* @return a CoordinateSubSequence containing the coordinates between fromM and toM
*/
private CoordinateSubSequence copyCoordinatesBetween(MCoordinate[] mcoordinates, double fromM, double toM, int direction) {
CoordinateSubSequence sseq = new CoordinateSubSequence();
sseq.firstIndex = -1;
sseq.lastIndex = -1;
for ( int i = 0; i < mcoordinates.length; i++ ) {
double m = mcoordinates[i].m;
if ( m >= fromM && m <= toM ) {
sseq.vertices.add( mcoordinates[i] );
if ( sseq.firstIndex == -1 ) {
sseq.firstIndex = i;
}
}
if ( direction == INCREASING ) {
if ( m > toM ) {
break;
}
sseq.lastIndex = i;
}
else {
if ( m < fromM ) {
break;
}
sseq.lastIndex = i;
}
}
return sseq;
}
/**
* Interpolates a coordinate between mco1, mco2, based on the measured value m
*/
private MCoordinate interpolate(MCoordinate mco1, MCoordinate mco2, double m) {
if ( mco1.m > mco2.m ) {
MCoordinate h = mco1;
mco1 = mco2;
mco2 = h;
}
if ( m < mco1.m || m > mco2.m ) {
throw new IllegalArgumentException( "Internal Error: m-value not in interval mco1.m/mco2.m" );
}
double r = ( m - mco1.m ) / ( mco2.m - mco1.m );
MCoordinate interpolated = new MCoordinate(
mco1.x + r * ( mco2.x - mco1.x ),
mco1.y + r * ( mco2.y - mco1.y ),
mco1.z + r * ( mco2.z - mco1.z ),
m
);
this.getPrecisionModel().makePrecise( interpolated );
return interpolated;
}
public CoordinateSequence[] getCoordinatesBetween(double fromM, double toM) throws MGeometryException {
if ( !this.isMonotone( false ) ) {
throw new MGeometryException(
MGeometryException.OPERATION_REQUIRES_MONOTONE,
"Operation requires geometry with monotonic measures"
);
}
if ( fromM > toM ) {
return getCoordinatesBetween( toM, fromM );
}
MCoordinateSequence mc;
if ( !isOverlapping( fromM, toM ) ) {
mc = new MCoordinateSequence( new MCoordinate[] { } );
}
else {
MCoordinate[] mcoordinates = (MCoordinate[]) this.getCoordinates();
CoordinateSubSequence subsequence = copyCoordinatesBetween(
mcoordinates,
fromM,
toM,
this.getMeasureDirection()
);
addInterpolatedEndPoints( fromM, toM, mcoordinates, subsequence );
MCoordinate[] ra = subsequence.vertices.toArray( new MCoordinate[subsequence.vertices.size()] );
mc = new MCoordinateSequence( ra );
}
return new MCoordinateSequence[] { mc };
}
private boolean isOverlapping(double fromM, double toM) {
if ( this.isEmpty() ) {
return false;
}
//WARNING: this assumes a monotonic increasing or decreasing measures
MCoordinate beginCo = (MCoordinate) this.getCoordinateN( 0 );
MCoordinate endCo = (MCoordinate) this.getCoordinateN( this.getNumPoints() - 1 );
return !( Math.min( fromM, toM ) > Math.max( beginCo.m, endCo.m ) ||
Math.max( fromM, toM ) < Math.min( beginCo.m, endCo.m ) );
}
private void addInterpolatedEndPoints(double fromM, double toM, MCoordinate[] mcoordinates, CoordinateSubSequence subsequence) {
boolean increasing = this.getMeasureDirection() == 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 NON_MONOTONE;
}
MCoordinate c1 = (MCoordinate) this.getCoordinateN( 0 );
MCoordinate c2 = (MCoordinate) this
.getCoordinateN( this.getNumPoints() - 1 );
if ( c1.m < c2.m ) {
return INCREASING;
}
else if ( c1.m > c2.m ) {
return DECREASING;
}
else {
return 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() == INCREASING ) {
return a[0];
}
else if ( this.getMeasureDirection() == DECREASING
|| this.getMeasureDirection() == 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() == DECREASING ) {
CoordinateArrays.reverse( linecoar );
}
Coordinate[] thiscoar = this.getCoordinates();
if ( this.getMeasureDirection() == 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>();
}
}

View File

@ -1,292 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.MultiLineString;
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 = 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() == 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 == 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.hibernate.spatial.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.hibernate.spatial.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.hibernate.spatial.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.hibernate.spatial.mgeom.MGeometry#isMonotone()
*/
public boolean isMonotone(boolean strictMonotone) {
return strictMonotone ? this.strictMonotone : monotone;
}
public Geometry asGeometry() {
return this;
}
}

View File

@ -1,151 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
/**
* @author Karel Maesen, Geovise BVBA.
* Date: Nov 2, 2009
*/
import java.io.IOException;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.PointCollection;
import org.geolatte.geom.PointCollectionEquality;
import org.geolatte.geom.PointCollectionPointEquality;
import org.hibernate.spatial.Log;
import org.hibernate.spatial.LogFactory;
import org.hibernate.spatial.testing.DataSourceUtils;
import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
import org.hibernate.spatial.testing.TestData;
import org.hibernate.spatial.testing.TestSupport;
import org.hibernate.spatial.testing.dialects.sqlserver.SQLServerExpressionTemplate;
import org.hibernate.spatial.testing.dialects.sqlserver.SQLServerTestSupport;
import org.hibernate.testing.AfterClassOnce;
import static org.junit.Assert.assertTrue;
/**
* @author Karel Maesen, Geovise BVBA.
* Date: Nov 2, 2009
*/
public abstract class AbstractConvertorTest extends SpatialFunctionalTestCase {
private final static Log LOG = LogFactory.make();
private final static TestSupport support = new SQLServerTestSupport();
protected PointCollectionEquality pointCollectionEquality = new PointCollectionPointEquality();
Map<Integer, Geometry> decodedGeoms;
Map<Integer, Object> rawResults;
Map<Integer, byte[]> encodedGeoms;
Map<Integer, Geometry> expectedGeoms;
public void beforeClass() {
dataSourceUtils = new DataSourceUtils(
"sqlserver/hibernate-spatial-sqlserver-test.properties",
new SQLServerExpressionTemplate()
);
try {
String sql = dataSourceUtils.parseSqlIn( "sqlserver/create-sqlserver-test-schema.sql" );
dataSourceUtils.executeStatement( sql );
TestData testData = support.createTestData( null );
dataSourceUtils.insertTestData( testData );
}
catch ( SQLException e ) {
throw new RuntimeException( e );
}
catch ( IOException e ) {
throw new RuntimeException( e );
}
}
public void doDecoding(OpenGisType type) {
rawResults = dataSourceUtils.rawDbObjects( type.toString() );
TestData testData = support.createTestData( null );
expectedGeoms = dataSourceUtils.expectedGeoms( type.toString(), testData );
decodedGeoms = new HashMap<Integer, Geometry>();
for ( Integer id : rawResults.keySet() ) {
Geometry geometry = Decoders.decode( (byte[]) rawResults.get( id ) );
decodedGeoms.put( id, geometry );
}
}
public void doEncoding() {
encodedGeoms = new HashMap<Integer, byte[]>();
for ( Integer id : decodedGeoms.keySet() ) {
Geometry geom = decodedGeoms.get( id );
byte[] bytes = Encoders.encode(geom);
encodedGeoms.put( id, bytes );
}
}
public void test_encoding() {
for ( Integer id : encodedGeoms.keySet() ) {
assertTrue(
"Wrong encoding for case " + id,
Arrays.equals( (byte[]) rawResults.get( id ), encodedGeoms.get( id ) )
);
}
}
public void test_decoding() {
for ( Integer id : decodedGeoms.keySet() ) {
Geometry expected = expectedGeoms.get( id );
Geometry received = decodedGeoms.get( id );
assertTrue( "Wrong decoding for case " + id, expected.equals( received ) );
}
}
@AfterClassOnce
public void afterClassOnce(){
try {
String sql = dataSourceUtils.parseSqlIn( "sqlserver/drop-sqlserver-test-schema.sql" );
dataSourceUtils.executeStatement( sql );
}
catch ( SQLException e ) {
throw new RuntimeException( e );
}
catch ( IOException e ) {
throw new RuntimeException( e );
}
}
public void prepareTest() {
}
public void assertPointCollectionEquality(PointCollection received, PointCollection expected) {
assertTrue( pointCollectionEquality.equals( received, expected ));
}
@Override
protected Log getLogger() {
return LOG;
}
}

View File

@ -1,57 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.junit.Test;
import org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.RequiresDialect;
/**
* Created by IntelliJ IDEA.
* User: maesenka
* Date: Jan 24, 2010
* Time: 5:33:19 PM
* To change this template use File | Settings | File Templates.
*/
@RequiresDialect(value = SqlServer2008SpatialDialect.class)
public class GeometryCollectionConvertorTest extends AbstractConvertorTest {
@BeforeClassOnce
public void beforeClass() {
super.beforeClass();
doDecoding( OpenGisType.GEOMETRYCOLLECTION );
doEncoding();
}
@Test
public void test_encoding() {
super.test_encoding();
}
@Test
public void test_decoding() {
super.test_decoding();
}
}

View File

@ -1,107 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.DimensionalFlag;
import org.geolatte.geom.LineString;
import org.geolatte.geom.PointCollection;
import org.geolatte.geom.PointSequenceBuilders;
import org.geolatte.geom.crs.CrsId;
import org.junit.Test;
import org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.RequiresDialect;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RequiresDialect(SqlServer2008SpatialDialect.class)
public class LineStringConvertorTest extends AbstractConvertorTest {
CrsId WGS84 = CrsId.valueOf( 4326 );
@BeforeClassOnce
public void beforeClass() {
super.beforeClass();
doDecoding( OpenGisType.LINESTRING );
doEncoding();
}
@Test
public void test_srid() {
assertTrue( decodedGeoms.get( 5 ) instanceof LineString );
assertTrue( decodedGeoms.get( 6 ) instanceof LineString );
assertEquals( 4326, decodedGeoms.get( 5 ).getSRID() );
assertEquals( 4326, decodedGeoms.get( 6 ).getSRID() );
}
@Test
public void test_num_points() {
assertEquals( 2, decodedGeoms.get( 5 ).getNumPoints() );
assertEquals( 4, decodedGeoms.get( 6 ).getNumPoints() );
}
@Test
public void test_coordinates() {
PointCollection received = decodedGeoms.get( 5 ).getPoints();
PointCollection expected = PointSequenceBuilders.fixedSized( 2, DimensionalFlag.d2D, WGS84 ).add(10, 5).add(20,15).toPointSequence();
assertPointCollectionEquality( received, expected );
received = decodedGeoms.get( 6 ).getPoints();
expected = PointSequenceBuilders.fixedSized( 4, DimensionalFlag.d2D, WGS84).add(10,5).add(20,15).add(30.3, 22.4).add(10,30).toPointSequence();
assertPointCollectionEquality( received, expected );
received = decodedGeoms.get( 7 ).getPoints();
expected = PointSequenceBuilders.fixedSized( 2, DimensionalFlag.d3D, WGS84).add(10,5,0).add(20,15,3).toPointSequence();
assertPointCollectionEquality( received, expected );
//case 9
received = decodedGeoms.get( 9 ).getPoints();
expected = PointSequenceBuilders.fixedSized( 4, DimensionalFlag.d3D, WGS84).add(10,5,1).add(20,15,2).add(30.3, 22.4,5).add(10,30,2).toPointSequence();
assertPointCollectionEquality( received, expected );
//case 10
received = decodedGeoms.get( 10 ).getPoints();
expected = PointSequenceBuilders.fixedSized( 4, DimensionalFlag.d3DM, WGS84).add(10,5,1,1).add(20,15,2,3).add(30.3, 22.4,5,10).add(10,30,2,12).toPointSequence();
assertPointCollectionEquality( received, expected );
}
@Test
public void test_encoding() {
super.test_encoding();
}
@Test
public void test_decoding() {
super.test_decoding();
}
}

View File

@ -1,50 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.junit.Test;
import org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.RequiresDialect;
@RequiresDialect(SqlServer2008SpatialDialect.class)
public class MultiLineStringConvertorTest extends AbstractConvertorTest {
@BeforeClassOnce
public void beforeClass() {
super.beforeClass();
doDecoding( OpenGisType.MULTILINESTRING );
doEncoding();
}
@Test
public void test_encoding() {
super.test_encoding();
}
@Test
public void test_decoding() {
super.test_decoding();
}
}

View File

@ -1,50 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.junit.Test;
import org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.RequiresDialect;
@RequiresDialect(SqlServer2008SpatialDialect.class)
public class MultiPointConvertorTest extends AbstractConvertorTest {
@BeforeClassOnce
public void beforeClass() {
super.beforeClass();
doDecoding( OpenGisType.MULTIPOINT );
doEncoding();
}
@Test
public void test_encoding() {
super.test_encoding();
}
@Test
public void test_decoding() {
super.test_decoding();
}
}

View File

@ -1,50 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.junit.Test;
import org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.RequiresDialect;
@RequiresDialect(SqlServer2008SpatialDialect.class)
public class MultiPolygonConvertorTest extends AbstractConvertorTest {
@BeforeClassOnce
public void beforeClass() {
super.beforeClass();
doDecoding( OpenGisType.MULTIPOLYGON );
doEncoding();
}
@Test
public void test_encoding() {
super.test_encoding();
}
@Test
public void test_decoding() {
super.test_decoding();
}
}

View File

@ -1,97 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.geolatte.geom.Point;
import org.geolatte.geom.Points;
import org.geolatte.geom.crs.CrsId;
import org.junit.Test;
import org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.RequiresDialect;
import static junit.framework.Assert.assertEquals;
/**
* @author Karel Maesen, Geovise BVBA.
* Date: Nov 2, 2009
*/
@RequiresDialect(SqlServer2008SpatialDialect.class)
public class PointConvertorTest extends AbstractConvertorTest {
@BeforeClassOnce
public void beforeClass() {
super.beforeClass();
doDecoding( OpenGisType.POINT );
doEncoding();
}
@Test
public void test_verify_srid() {
assertEquals( -1, decodedGeoms.get( 1 ).getSRID() );
assertEquals( 4326, decodedGeoms.get( 2 ).getSRID() );
assertEquals( 31370, decodedGeoms.get( 3 ).getSRID() );
}
@Test
public void test_class() {
for ( Integer id : decodedGeoms.keySet() ) {
assertEquals( Point.class, decodedGeoms.get( id ).getClass() );
}
}
@Test
public void test_coordinates() {
Point expected;
expected = Points.create2D( 10.0, 5.0);
assertEquals( expected, decodedGeoms.get( 1 ).getPointN(0) );
expected = Points.create2D(52.25, 2.53, CrsId.valueOf(4326));
assertEquals( expected, decodedGeoms.get( 2 ).getPointN( 0 ) );
expected = Points.create2D(150000.0, 200000.0, CrsId.valueOf(31370));
assertEquals( expected, decodedGeoms.get( 3 ).getPointN( 0 ) );
expected = Points.create3DM(10.0, 2.0, 1.0, 3.0, CrsId.valueOf(4326));
assertEquals( expected, decodedGeoms.get( 4 ).getPointN( 0 ) );
}
@Test
public void test_encoding() {
super.test_encoding();
}
@Test
public void test_decoding() {
super.test_decoding();
}
@Test
public void test_test_empty_point() {
//TODO -- How?
}
@Test
public void test_no_srid() {
//TODO -- How?
}
}

View File

@ -1,52 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.dialect.sqlserver.convertors;
import org.junit.Test;
import org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.RequiresDialect;
@RequiresDialect(SqlServer2008SpatialDialect.class)
public class PolygonConvertorTest extends AbstractConvertorTest {
@BeforeClassOnce
public void beforeClass() {
super.beforeClass();
doDecoding( OpenGisType.POLYGON );
doEncoding();
}
@Test
public void test_encoding() {
super.test_encoding();
}
@Test
public void test_decoding() {
super.test_decoding();
}
}

View File

@ -48,8 +48,6 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
private static Log LOG = LogFactory.make(); private static Log LOG = LogFactory.make();
private static String JTS = "jts";
private static String GEOLATTE = "geolatte";
protected Log getLogger() { protected Log getLogger() {
return LOG; return LOG;
@ -71,7 +69,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
Map<Integer, Integer> dbexpected = expectationsFactory.getDimension(); Map<Integer, Integer> dbexpected = expectationsFactory.getDimension();
String hql = format( "SELECT id, dimension(geom) FROM org.hibernate.spatial.integration.%s.GeomEntity", pckg ); String hql = format( "SELECT id, dimension(geom) FROM org.hibernate.spatial.integration.%s.GeomEntity", pckg );
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
} }
@Test @Test
@ -90,7 +88,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
Map<Integer, String> dbexpected = expectationsFactory.getAsText(); Map<Integer, String> dbexpected = expectationsFactory.getAsText();
String hql = format( "SELECT id, astext(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg ); String hql = format( "SELECT id, astext(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg );
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg);
} }
@Test @Test
@ -110,7 +108,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
Map<Integer, byte[]> dbexpected = expectationsFactory.getAsBinary(); Map<Integer, byte[]> dbexpected = expectationsFactory.getAsBinary();
String hql = format( "SELECT id, asbinary(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg ); String hql = format( "SELECT id, asbinary(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg );
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
} }
@Test @Test
@ -132,7 +130,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
"SELECT id, geometrytype(geom) from org.hibernate.spatial.integration.%s.GeomEntity", "SELECT id, geometrytype(geom) from org.hibernate.spatial.integration.%s.GeomEntity",
pckg pckg
); );
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
} }
@Test @Test
@ -151,7 +149,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
Map<Integer, Integer> dbexpected = expectationsFactory.getSrid(); Map<Integer, Integer> dbexpected = expectationsFactory.getSrid();
String hql = format( "SELECT id, srid(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg ); String hql = format( "SELECT id, srid(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg );
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
} }
@Test @Test
@ -170,7 +168,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
Map<Integer, Boolean> dbexpected = expectationsFactory.getIsSimple(); Map<Integer, Boolean> dbexpected = expectationsFactory.getIsSimple();
String hql = format( "SELECT id, issimple(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg ); String hql = format( "SELECT id, issimple(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg );
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
} }
@Test @Test
@ -189,7 +187,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
Map<Integer, Boolean> dbexpected = expectationsFactory.getIsEmpty(); Map<Integer, Boolean> dbexpected = expectationsFactory.getIsEmpty();
String hql = format( "SELECT id, isEmpty(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg ); String hql = format( "SELECT id, isEmpty(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg );
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
} }
@Test @Test
@ -208,7 +206,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
Map<Integer, Geometry> dbexpected = expectationsFactory.getBoundary(); Map<Integer, Geometry> dbexpected = expectationsFactory.getBoundary();
String hql = format( "SELECT id, boundary(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg ); String hql = format( "SELECT id, boundary(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg );
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
} }
@Test @Test
@ -227,7 +225,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
} }
Map<Integer, Geometry> dbexpected = expectationsFactory.getEnvelope(); Map<Integer, Geometry> dbexpected = expectationsFactory.getEnvelope();
String hql = format("SELECT id, envelope(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg); String hql = format("SELECT id, envelope(geom) from org.hibernate.spatial.integration.%s.GeomEntity", pckg);
retrieveHQLResultsAndCompare( dbexpected, hql ); retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
} }
@Test @Test
@ -248,7 +246,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, within(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, within(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where within(geom, :filter) = true and srid(geom) = 4326", pckg); "where within(geom, :filter) = true and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -269,7 +267,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, equals(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, equals(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where equals(geom, :filter) = true and srid(geom) = 4326", pckg); "where equals(geom, :filter) = true and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -290,7 +288,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, crosses(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, crosses(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where crosses(geom, :filter) = true and srid(geom) = 4326", pckg); "where crosses(geom, :filter) = true and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@ -312,7 +310,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, contains(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, contains(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where contains(geom, :filter) = true and srid(geom) = 4326", pckg); "where contains(geom, :filter) = true and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -333,7 +331,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, disjoint(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, disjoint(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where disjoint(geom, :filter) = true and srid(geom) = 4326", pckg); "where disjoint(geom, :filter) = true and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -354,7 +352,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, intersects(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, intersects(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where intersects(geom, :filter) = true and srid(geom) = 4326", pckg); "where intersects(geom, :filter) = true and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -375,7 +373,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, overlaps(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, overlaps(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where overlaps(geom, :filter) = true and srid(geom) = 4326", pckg); "where overlaps(geom, :filter) = true and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -396,7 +394,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
"where touches(geom, :filter) = true and srid(geom) = 4326", pckg); "where touches(geom, :filter) = true and srid(geom) = 4326", pckg);
Map<Integer, Boolean> dbexpected = expectationsFactory.getTouches( expectationsFactory.getTestPolygon() ); Map<Integer, Boolean> dbexpected = expectationsFactory.getTouches( expectationsFactory.getTestPolygon() );
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -422,12 +420,12 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
"where relate(geom, :filter, :matrix) = true and srid(geom) = 4326", pckg); "where relate(geom, :filter, :matrix) = true and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
params.put( "matrix", matrix ); params.put( "matrix", matrix );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
matrix = "FF*FF****"; matrix = "FF*FF****";
dbexpected = expectationsFactory.getRelate( expectationsFactory.getTestPolygon(), matrix ); dbexpected = expectationsFactory.getRelate( expectationsFactory.getTestPolygon(), matrix );
params.put( "matrix", matrix ); params.put( "matrix", matrix );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@ -449,7 +447,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, distance(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, distance(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where srid(geom) = 4326", pckg); "where srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -470,7 +468,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, buffer(geom, :distance) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, buffer(geom, :distance) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where srid(geom) = 4326", pckg); "where srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "distance", Double.valueOf( 1.0 ) ); Map<String, Object> params = createQueryParams( "distance", Double.valueOf( 1.0 ) );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@ -492,7 +490,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, convexhull(geomunion(geom, :polygon)) from org.hibernate.spatial.integration" + String hql = format("SELECT id, convexhull(geomunion(geom, :polygon)) from org.hibernate.spatial.integration" +
".%s.GeomEntity where srid(geom) = 4326", pckg); ".%s.GeomEntity where srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@ -514,7 +512,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, intersection(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, intersection(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where srid(geom) = 4326", pckg); "where srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -535,7 +533,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, difference(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, difference(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where srid(geom) = 4326", pckg); "where srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -556,7 +554,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, symdifference(geom, :polygon) from " + String hql = format("SELECT id, symdifference(geom, :polygon) from " +
"org.hibernate.spatial.integration.%s.GeomEntity where srid(geom) = 4326", pckg); "org.hibernate.spatial.integration.%s.GeomEntity where srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -577,7 +575,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, geomunion(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, geomunion(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where srid(geom) = 4326", pckg); "where srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() ); Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg);
} }
@Test @Test
@ -604,7 +602,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
"and srid(geom) = 4326", pckg); "and srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPoint() ); Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPoint() );
params.put( "distance", 30.0 ); params.put( "distance", 30.0 );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
@Test @Test
@ -626,18 +624,18 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
String hql = format("SELECT id, transform(geom, :epsg) from org.hibernate.spatial.integration.%s.GeomEntity " + String hql = format("SELECT id, transform(geom, :epsg) from org.hibernate.spatial.integration.%s.GeomEntity " +
"where srid(geom) = 4326", pckg); "where srid(geom) = 4326", pckg);
Map<String, Object> params = createQueryParams( "epsg", Integer.valueOf( epsg ) ); Map<String, Object> params = createQueryParams( "epsg", Integer.valueOf( epsg ) );
retrieveHQLResultsAndCompare( dbexpected, hql, params ); retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
} }
public <T> void retrieveHQLResultsAndCompare(Map<Integer, T> dbexpected, String hql) { public <T> void retrieveHQLResultsAndCompare(Map<Integer, T> dbexpected, String hql, String geometryType) {
retrieveHQLResultsAndCompare( dbexpected, hql, null ); retrieveHQLResultsAndCompare( dbexpected, hql, null, geometryType);
} }
protected <T> void retrieveHQLResultsAndCompare(Map<Integer, T> dbexpected, String hql, Map<String, Object> params) { protected <T> void retrieveHQLResultsAndCompare(Map<Integer, T> dbexpected, String hql, Map<String, Object> params, String geometryType) {
Map<Integer, T> hsreceived = new HashMap<Integer, T>(); Map<Integer, T> hsreceived = new HashMap<Integer, T>();
doInSession( hql, hsreceived, params ); doInSession( hql, hsreceived, params );
compare( dbexpected, hsreceived ); compare( dbexpected, hsreceived, geometryType );
} }
private Map<String, Object> createQueryParams(String filterParamName, Object value) { private Map<String, Object> createQueryParams(String filterParamName, Object value) {

View File

@ -4,7 +4,9 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.vividsolutions.jts.geom.Geometry; import org.geolatte.geom.Geometry;
import org.geolatte.geom.GeometryEquality;
import org.geolatte.geom.GeometryPointEquality;
import org.geolatte.geom.codec.WktDecodeException; import org.geolatte.geom.codec.WktDecodeException;
import org.junit.Test; import org.junit.Test;
@ -13,7 +15,6 @@ import org.hibernate.Session;
import org.hibernate.Transaction; import org.hibernate.Transaction;
import org.hibernate.spatial.Log; import org.hibernate.spatial.Log;
import org.hibernate.spatial.LogFactory; import org.hibernate.spatial.LogFactory;
import org.hibernate.spatial.integration.jts.GeomEntity;
import org.hibernate.spatial.testing.SpatialDialectMatcher; import org.hibernate.spatial.testing.SpatialDialectMatcher;
import org.hibernate.spatial.testing.SpatialFunctionalTestCase; import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
import org.hibernate.spatial.testing.TestDataElement; import org.hibernate.spatial.testing.TestDataElement;
@ -42,7 +43,7 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
@Test @Test
public void testAfterStoreRetrievingEqualObject() throws WktDecodeException { public void testAfterStoreRetrievingEqualObject() throws WktDecodeException {
Map<Integer, org.hibernate.spatial.integration.jts.GeomEntity> stored = new HashMap<Integer, org.hibernate.spatial.integration.jts.GeomEntity>(); Map<Integer,GeomEntity> stored = new HashMap<Integer, GeomEntity>();
//check whether we retrieve exactly what we store //check whether we retrieve exactly what we store
storeTestObjects( stored ); storeTestObjects( stored );
retrieveAndCompare( stored ); retrieveAndCompare( stored );
@ -54,20 +55,21 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
retrieveNullGeometry(); retrieveNullGeometry();
} }
private void retrieveAndCompare(Map<Integer, org.hibernate.spatial.integration.jts.GeomEntity> stored) { private void retrieveAndCompare(Map<Integer, GeomEntity> stored) {
int id = -1; int id = -1;
Transaction tx = null; Transaction tx = null;
Session session = null; Session session = null;
GeometryEquality geomEq = new GeometryPointEquality();
try { try {
session = openSession(); session = openSession();
tx = session.beginTransaction(); tx = session.beginTransaction();
for ( org.hibernate.spatial.integration.jts.GeomEntity storedEntity : stored.values() ) { for ( GeomEntity storedEntity : stored.values() ) {
id = storedEntity.getId(); id = storedEntity.getId();
org.hibernate.spatial.integration.jts.GeomEntity retrievedEntity = (org.hibernate.spatial.integration.jts.GeomEntity) session.get( org.hibernate.spatial.integration.jts.GeomEntity.class, id ); GeomEntity retrievedEntity = (GeomEntity) session.get( GeomEntity.class, id );
Geometry retrievedGeometry = retrievedEntity.getGeom(); Geometry retrievedGeometry = retrievedEntity.getGeom();
Geometry storedGeometry = storedEntity.getGeom(); Geometry storedGeometry = storedEntity.getGeom();
String msg = createFailureMessage( storedEntity.getId(), storedGeometry, retrievedGeometry ); String msg = createFailureMessage( storedEntity.getId(), storedGeometry, retrievedGeometry );
assertTrue( msg, geometryEquality.test( storedGeometry, retrievedGeometry ) ); assertTrue( msg, geomEq.equals( storedGeometry, retrievedGeometry ) );
} }
tx.commit(); tx.commit();
} }
@ -85,8 +87,8 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
} }
private String createFailureMessage(int id, Geometry storedGeometry, Geometry retrievedGeometry) { private String createFailureMessage(int id, Geometry storedGeometry, Geometry retrievedGeometry) {
String expectedText = ( storedGeometry != null ? storedGeometry.toText() : "NULL" ); String expectedText = ( storedGeometry != null ? storedGeometry.asText() : "NULL" );
String retrievedText = ( retrievedGeometry != null ? retrievedGeometry.toText() : "NULL" ); String retrievedText = ( retrievedGeometry != null ? retrievedGeometry.asText() : "NULL" );
return String.format( return String.format(
"Equality testsuite-suite failed for %d.\nExpected: %s\nReceived:%s", "Equality testsuite-suite failed for %d.\nExpected: %s\nReceived:%s",
id, id,
@ -95,7 +97,7 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
); );
} }
private void storeTestObjects(Map<Integer, org.hibernate.spatial.integration.jts.GeomEntity> stored) { private void storeTestObjects(Map<Integer,GeomEntity> stored) {
Session session = null; Session session = null;
Transaction tx = null; Transaction tx = null;
int id = -1; int id = -1;
@ -106,12 +108,7 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
for ( TestDataElement element : testData ) { for ( TestDataElement element : testData ) {
id = element.id; id = element.id;
tx = session.beginTransaction(); tx = session.beginTransaction();
org.hibernate.spatial.integration.jts.GeomEntity entity = org.hibernate GeomEntity entity = GeomEntity.createFrom( element );
.spatial
.integration
.jts
.GeomEntity
.createFrom( element );
stored.put( entity.getId(), entity ); stored.put( entity.getId(), entity );
session.save( entity ); session.save( entity );
tx.commit(); tx.commit();
@ -131,13 +128,13 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
} }
private void storeNullGeometry() { private void storeNullGeometry() {
org.hibernate.spatial.integration.jts.GeomEntity entity = null; GeomEntity entity = null;
Session session = null; Session session = null;
Transaction tx = null; Transaction tx = null;
try { try {
session = openSession(); session = openSession();
tx = session.beginTransaction(); tx = session.beginTransaction();
entity = new org.hibernate.spatial.integration.jts.GeomEntity(); entity = new GeomEntity();
entity.setId( 1 ); entity.setId( 1 );
entity.setType( "NULL OBJECT" ); entity.setType( "NULL OBJECT" );
session.save( entity ); session.save( entity );
@ -162,8 +159,8 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
try { try {
session = openSession(); session = openSession();
tx = session.beginTransaction(); tx = session.beginTransaction();
Criteria criteria = session.createCriteria( org.hibernate.spatial.integration.jts.GeomEntity.class ); Criteria criteria = session.createCriteria( GeomEntity.class );
List<org.hibernate.spatial.integration.jts.GeomEntity> retrieved = criteria.list(); List<GeomEntity> retrieved = criteria.list();
assertEquals( "Expected exactly one result", 1, retrieved.size() ); assertEquals( "Expected exactly one result", 1, retrieved.size() );
GeomEntity entity = retrieved.get( 0 ); GeomEntity entity = retrieved.get( 0 );
assertNull( entity.getGeom() ); assertNull( entity.getGeom() );

View File

@ -1,783 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.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;
/**
* @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 );
mcoar = new MCoordinate[l];
for ( int i = 0; i < mcoar.length; i++ ) {
double x = Math.random() * 100000.0;
double y = Math.random() * 100000.0;
double z = Double.NaN; // JTS doesn't support operations on the
// z-coordinate value
double m = Math.random() * 100000.0;
mcoar[i] = new MCoordinate( x, y, z, m );
}
arbitraryLine = mgeomFactory.createMLineString( mcoar );
mcoar = new MCoordinate[0];
nullLine = mgeomFactory.createMLineString( mcoar );
}
/*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
}
/**
* Constructor for MLineStringTest.
*
* @param name
*/
public MLineStringTest(String name) {
super( name );
}
//
// public void testMLineString() {
// }
/*
* Class under testsuite-suite for Object clone()
*/
public void testClone() {
MLineString mltest = (MLineString) arbitraryLine.clone();
Coordinate[] testco = mltest.getCoordinates();
Coordinate[] arco = arbitraryLine.getCoordinates();
assertEquals( testco.length, arco.length );
for ( int i = 0; i < arco.length; i++ ) {
// clones must have equal, but not identical coordinates
assertEquals( arco[i], testco[i] );
assertNotSame( arco[i], testco[i] );
}
mltest = (MLineString) nullLine.clone();
assertEquals( mltest.isEmpty(), nullLine.isEmpty() );
assertTrue( mltest.isEmpty() );
}
public void testGetClosestPoint() {
try {
if ( !arbitraryLine.isMonotone( false ) ) {
Coordinate mc = arbitraryLine.getClosestPoint(
new Coordinate(
1.0, 2.0
), 0.1
);
assertTrue( false ); // should never evaluate this
}
}
catch ( Exception e ) {
assertTrue( ( (MGeometryException) e ).getType() == MGeometryException.OPERATION_REQUIRES_MONOTONE );
}
try {
// check reaction on null string
MCoordinate mc = nullLine.getClosestPoint(
new Coordinate( 0.0, 1.0 ),
1.0
);
assertNull( mc );
// must return the very same coordinate if the coordinate is a
// coordinate of the line
arbitraryLine.measureOnLength( false );
int selp = (int) ( arbitraryLine.getNumPoints() / 2 );
MCoordinate mcexp = (MCoordinate) arbitraryLine
.getCoordinateN( selp );
MCoordinate mctest = arbitraryLine.getClosestPoint( mcexp, 1 );
assertEquals( mcexp, mctest );
// must not return a point that is beyond the tolerance
mctest = controlledLine.getClosestPoint(
new Coordinate( 20.0, 20, 0 ), 1.0
);
assertNull( mctest );
// check for cases of circular MGeometry: lowest measure should be
// return.
ringLine.measureOnLength( false );
assertTrue( ringLine.isRing() );
assertTrue( ringLine.isMonotone( false ) );
assertTrue( ringLine.getMeasureDirection() == MGeometry.INCREASING );
MCoordinate expCo = MCoordinate.create2dWithMeasure( 0.0, 0.0, 0.0 );
MCoordinate testCo = ringLine.getClosestPoint( expCo, 0.1 );
assertTrue( DoubleComparator.equals( testCo.m, expCo.m ) );
ringLine.reverseMeasures();
testCo = ringLine.getClosestPoint( expCo, 0.1 );
assertTrue( DoubleComparator.equals( testCo.m, expCo.m ) );
ringLine.measureOnLength( false );
int n = ringLine.getNumPoints() - 1;
ringLine.setMeasureAtIndex( n, 100.0 );
ringLine.setMeasureAtIndex( 0, 0.0 );
testCo = ringLine.getClosestPoint( expCo, 0.001 );
assertTrue( DoubleComparator.equals( testCo.m, 0.0 ) );
// get two neighbouring points along the arbitraryline
arbitraryLine.measureOnLength( false );
int elem1Indx = (int) ( Math.random() * ( arbitraryLine
.getNumPoints() - 1 ) );
int elem2Indx = 0;
if ( elem1Indx == arbitraryLine.getNumPoints() - 1 ) {
elem2Indx = elem1Indx - 1;
}
else {
elem2Indx = elem1Indx + 1;
}
// testsuite-suite whether a coordinate between these two returns exactly
MCoordinate mco1 = (MCoordinate) arbitraryLine
.getCoordinateN( elem1Indx );
MCoordinate mco2 = (MCoordinate) arbitraryLine
.getCoordinateN( elem2Indx );
double d = mco1.distance( mco2 );
double offset = Math.random();
mcexp = MCoordinate.create2dWithMeasure(
mco1.x + offset
* ( mco2.x - mco1.x ), mco1.y + offset * ( mco2.y - mco1.y ),
0.0
);
mctest = arbitraryLine.getClosestPoint( mcexp, d );
mcexp.m = mco1.m + offset * ( mco2.m - mco1.m );
assertEquals( mcexp.x, mctest.x, 0.001 );
assertEquals( mcexp.y, mctest.y, 0.001 );
assertEquals( mcexp.z, mctest.z, 0.001 );
double delta = Math.random();
MCoordinate mcin = MCoordinate.create2dWithMeasure(
mco1.x + offset
* ( mco2.x - mco1.x ) + delta, mco1.y + offset
* ( mco2.y - mco1.y ) + delta, 0.0
);
// returned point is on the line
mctest = arbitraryLine.getClosestPoint( mcin, d );
assertEquals( mcin.x, mctest.x, delta * Math.sqrt( 2 ) );
assertEquals( mcin.y, mctest.y, delta * Math.sqrt( 2 ) );
}
catch ( Exception e ) {
e.printStackTrace();
assertTrue( false ); // should never reach this point
}
}
public void testGetCoordinateAtM() {
// what if null string
try {
Coordinate mc = nullLine.getCoordinateAtM( 2 );
assertNull( mc );
// get two neighbouring points along the arbitraryline
arbitraryLine.measureOnLength( false );
int elem1Indx = (int) ( Math.random() * ( arbitraryLine
.getNumPoints() - 1 ) );
int elem2Indx = 0;
if ( elem1Indx == arbitraryLine.getNumPoints() - 1 ) {
elem2Indx = elem1Indx - 1;
}
else {
elem2Indx = elem1Indx + 1;
}
// if m is value of a coordinate, the returned coordinate should
// equal that coordinate
MCoordinate mco1 = (MCoordinate) arbitraryLine
.getCoordinateN( elem1Indx );
MCoordinate mcotest = (MCoordinate) arbitraryLine
.getCoordinateAtM( mco1.m );
assertNotSame( mco1, mcotest );
assertEquals( mco1.x, mcotest.x, Math.ulp( 100 * mco1.x ) );
assertEquals( mco1.y, mcotest.y, Math.ulp( 100 * mco1.y ) );
assertEquals( mco1.m, mcotest.m, Math.ulp( 100 * mco1.m ) );
MCoordinate mco2 = (MCoordinate) arbitraryLine
.getCoordinateN( elem2Indx );
double offset = Math.random();
double newM = mco1.m + offset * ( mco2.m - mco1.m );
MCoordinate mcexp = new MCoordinate(
mco1.x + offset
* ( mco2.x - mco1.x ), mco1.y + offset * ( mco2.y - mco1.y ),
Double.NaN, mco1.m + offset * ( mco2.m - mco1.m )
);
MCoordinate mctest = (MCoordinate) arbitraryLine
.getCoordinateAtM( newM );
assertEquals( mcexp.x, mctest.x, 0.0001 );
assertEquals( mcexp.y, mctest.y, 0.0001 );
assertEquals( mcexp.m, mctest.m, 0.0001 );
}
catch ( Exception e ) {
System.err.println( e );
}
}
/*
* Class under testsuite-suite for String getGeometryType()
*/
public void testGetGeometryType() {
assertEquals( "MLineString", arbitraryLine.getGeometryType() );
}
public void testGetMatCoordinate() {
try {
// what in case of the null string
assertTrue(
Double.isNaN(
nullLine.getMatCoordinate(
new Coordinate(
1.0, 1.0
), 1.0
)
)
);
// get two neighbouring points along the arbitraryline
arbitraryLine.measureOnLength( false );
int elem1Indx = (int) ( Math.random() * ( arbitraryLine
.getNumPoints() - 1 ) );
int elem2Indx = 0;
if ( elem1Indx == arbitraryLine.getNumPoints() - 1 ) {
elem2Indx = elem1Indx - 1;
}
else {
elem2Indx = elem1Indx + 1;
}
// if a coordinate of the geometry is passed, it should return
// exactly that m-value
MCoordinate mco1 = (MCoordinate) arbitraryLine
.getCoordinateN( elem1Indx );
double m = arbitraryLine.getMatCoordinate( mco1, 0.00001 );
assertEquals(
mco1.m, m, DoubleComparator
.defaultNumericalPrecision()
);
// check for a coordinate between mco1 and mco2 (neighbouring
// coordinates)
MCoordinate mco2 = (MCoordinate) arbitraryLine
.getCoordinateN( elem2Indx );
double offset = Math.random();
double expectedM = mco1.m + offset * ( mco2.m - mco1.m );
Coordinate mctest = new Coordinate(
mco1.x + offset
* ( mco2.x - mco1.x ), mco1.y + offset * ( mco2.y - mco1.y )
);
double testM = arbitraryLine.getMatCoordinate( mctest, offset );
assertEquals(
expectedM, testM, DoubleComparator
.defaultNumericalPrecision()
);
}
catch ( Exception e ) {
e.printStackTrace();
assertTrue( false );// should never reach here
}
}
public void testGetMatN() {
// Implement getMatN().
}
public void testGetMaxM() {
// Implement getMaxM().
}
public void testGetCoordinatesBetween() {
try {
// what if the null value is passed
CoordinateSequence[] cs = nullLine.getCoordinatesBetween( 0.0, 5.0 );
assertTrue( "cs.length = " + cs.length + ". Should be 1", cs.length == 1 );
assertEquals( cs[0].size(), 0 );
arbitraryLine.measureOnLength( false );
// what if from/to is outside of the range of values
double maxM = arbitraryLine.getMaxM();
cs = arbitraryLine.getCoordinatesBetween( maxM + 1.0, maxM + 10.0 );
// check for several ascending M-values
int minIdx = (int) ( Math.random() * ( arbitraryLine.getNumPoints() - 1 ) );
int maxIdx = Math.min(
( arbitraryLine.getNumPoints() - 1 ),
minIdx + 10
);
double minM = ( (MCoordinate) arbitraryLine.getCoordinateN( minIdx ) ).m;
maxM = ( (MCoordinate) arbitraryLine.getCoordinateN( maxIdx ) ).m;
cs = arbitraryLine.getCoordinatesBetween( minM, maxM );
assertNotNull( cs );
assertTrue( cs.length > 0 );
Coordinate[] coar = cs[0].toCoordinateArray();
int j = 0;
for ( int i = minIdx; i <= maxIdx; i++ ) {
assertEquals(
(MCoordinate) arbitraryLine.getCoordinateN( i ),
coar[j]
);
j++;
}
minM = Math.max( 0.0, minM - Math.random() * 10 );
cs = arbitraryLine.getCoordinatesBetween( minM, maxM );
coar = cs[0].toCoordinateArray();
MCoordinate mctest = (MCoordinate) coar[0];
MCoordinate mcexp = (MCoordinate) arbitraryLine
.getCoordinateAtM( minM );
assertEquals( mcexp, mctest );
assertEquals(
mctest.m, minM, DoubleComparator
.defaultNumericalPrecision()
);
maxM = Math.min(
arbitraryLine.getLength(), maxM + Math.random()
* 10
);
cs = arbitraryLine.getCoordinatesBetween( minM, maxM );
coar = cs[0].toCoordinateArray();
mctest = (MCoordinate) coar[coar.length - 1];
mcexp = (MCoordinate) arbitraryLine.getCoordinateAtM( maxM );
assertEquals( mcexp.x, mctest.x, Math.ulp( mcexp.x ) * 100 );
assertEquals( mcexp.y, mctest.y, Math.ulp( mcexp.y ) * 100 );
assertEquals(
mctest.m, maxM, DoubleComparator
.defaultNumericalPrecision()
);
}
catch ( Exception e ) {
e.printStackTrace();
assertTrue( false );// should never reach here
}
}
public void testGetMeasureDirection() {
assertTrue( nullLine.isMonotone( false ) );
assertTrue(
arbitraryLine.isMonotone( false )
|| ( !arbitraryLine.isMonotone( false ) && arbitraryLine
.getMeasureDirection() == MGeometry.NON_MONOTONE )
);
arbitraryLine.measureOnLength( false );
assertEquals( MGeometry.INCREASING, arbitraryLine.getMeasureDirection() );
arbitraryLine.reverseMeasures();
assertEquals( MGeometry.DECREASING, arbitraryLine.getMeasureDirection() );
for ( int i = 0; i < arbitraryLine.getNumPoints(); i++ ) {
arbitraryLine.setMeasureAtIndex( i, 0.0 );
}
assertEquals( MGeometry.CONSTANT, arbitraryLine.getMeasureDirection() );
}
public void testGetMeasures() {
}
public void testGetMinM() {
}
public void testInterpolate() {
MCoordinate mc0NaN = MCoordinate.create2d( 0.0, 0.0 );
MCoordinate mc0 = MCoordinate.create2dWithMeasure( 0.0, 0.0, 0.0 );
MCoordinate mc2NaN = MCoordinate.create2d( 2.0, 0.0 );
MCoordinate mc5NaN = MCoordinate.create2d( 5.0, 0.0 );
MCoordinate mc10NaN = MCoordinate.create2d( 10.0, 0.0 );
MCoordinate mc10 = MCoordinate.create2dWithMeasure( 10.0, 0.0, 10.0 );
// Internal coordinate measures are not defined, outer measures are
// 0-10, total 2d length is 10
MLineString line = mgeomFactory.createMLineString(
new MCoordinate[] {
mc0, mc2NaN, mc5NaN, mc10
}
);
MLineString lineBeginNaN = mgeomFactory
.createMLineString(
new MCoordinate[] {
mc0NaN, mc2NaN, mc5NaN,
mc10
}
);
MLineString lineEndNaN = mgeomFactory
.createMLineString(
new MCoordinate[] {
mc0, mc2NaN, mc5NaN,
mc10NaN
}
);
assertTrue( DoubleComparator.equals( line.getLength(), 10 ) );
assertTrue( DoubleComparator.equals( lineBeginNaN.getLength(), 10 ) );
assertTrue( DoubleComparator.equals( lineEndNaN.getLength(), 10 ) );
line.interpolate( mc0.m, mc10.m );
lineBeginNaN.interpolate( mc0.m, mc10.m );
lineEndNaN.interpolate( mc0.m, mc10.m );
assertTrue( line.isMonotone( false ) );
assertTrue( line.isMonotone( true ) );
assertTrue( lineBeginNaN.isMonotone( false ) );
assertTrue( lineBeginNaN.isMonotone( true ) );
assertTrue( lineEndNaN.isMonotone( false ) );
assertTrue( lineEndNaN.isMonotone( true ) );
double[] expectedM = new double[] { mc0.m, 2.0, 5.0, mc10.m };
for ( int i = 0; i < expectedM.length; i++ ) {
double actualMLine = line.getCoordinateSequence().getOrdinate(
i,
CoordinateSequence.M
);
double actualBeginNaN = lineBeginNaN.getCoordinateSequence()
.getOrdinate( i, CoordinateSequence.M );
double actualEndNaN = lineEndNaN.getCoordinateSequence()
.getOrdinate( i, CoordinateSequence.M );
assertTrue( DoubleComparator.equals( expectedM[i], actualMLine ) );
assertTrue( DoubleComparator.equals( expectedM[i], actualBeginNaN ) );
assertTrue( DoubleComparator.equals( expectedM[i], actualEndNaN ) );
}
// Test Continuous case by interpolating with begin and end measures
// equal
double continuousMeasure = 0.0D;
line.interpolate( continuousMeasure, continuousMeasure );
double[] measures = line.getMeasures();
for ( int i = 0; i < measures.length; i++ ) {
assertTrue( DoubleComparator.equals( measures[i], continuousMeasure ) );
}
}
public void testIsMonotone() {
MCoordinate mc0NaN = MCoordinate.create2d( 1.0, 0.0 );
MCoordinate mc0 = MCoordinate.create2dWithMeasure( 0.0, 0.0, 0.0 );
MCoordinate mc1NaN = MCoordinate.create2d( 1.0, 0.0 );
MCoordinate mc1 = MCoordinate.create2dWithMeasure( 1.0, 0.0, 1.0 );
MCoordinate mc2NaN = MCoordinate.create2d( 2.0, 0.0 );
MCoordinate mc2 = MCoordinate.create2dWithMeasure( 2.0, 0.0, 2.0 );
MCoordinate mc3NaN = MCoordinate.create2d( 3.0, 0.0 );
MCoordinate mc3 = MCoordinate.create2dWithMeasure( 3.0, 0.0, 3.0 );
MLineString emptyLine = mgeomFactory
.createMLineString( new MCoordinate[] { } );
MLineString orderedLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc0, mc1, mc2, mc3 } );
MLineString unorderedLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc0, mc2, mc1, mc3 } );
MLineString constantLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc2, mc2, mc2, mc2 } );
MLineString reverseOrderedLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc3, mc2, mc1, mc0 } );
MLineString reverseUnOrderedLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc3, mc1, mc2, mc0 } );
MLineString dupCoordLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc0, mc1, mc1, mc2 } );
MLineString reverseDupCoordLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc2, mc1, mc1, mc0 } );
assertTrue( emptyLine.isMonotone( false ) );
assertTrue( emptyLine.isMonotone( true ) );
assertTrue( orderedLine.isMonotone( false ) );
assertTrue( orderedLine.isMonotone( true ) );
// testsuite-suite reversing the ordered line
orderedLine.reverseMeasures();
assertTrue( orderedLine.isMonotone( false ) );
assertTrue( orderedLine.isMonotone( true ) );
// testsuite-suite shifting
orderedLine.shiftMeasure( 1.0 );
assertTrue( orderedLine.isMonotone( false ) );
assertTrue( orderedLine.isMonotone( true ) );
orderedLine.shiftMeasure( -1.0 );
assertTrue( orderedLine.isMonotone( false ) );
assertTrue( orderedLine.isMonotone( true ) );
assertFalse( unorderedLine.isMonotone( false ) );
assertFalse( unorderedLine.isMonotone( true ) );
assertTrue( constantLine.isMonotone( false ) );
assertFalse( constantLine.isMonotone( true ) );
// testsuite-suite shifting
constantLine.shiftMeasure( 1.0 );
assertTrue( constantLine.isMonotone( false ) );
assertFalse( constantLine.isMonotone( true ) );
constantLine.shiftMeasure( -1.0 );
assertTrue( constantLine.isMonotone( false ) );
assertFalse( constantLine.isMonotone( true ) );
assertTrue( reverseOrderedLine.isMonotone( false ) );
assertTrue( reverseOrderedLine.isMonotone( true ) );
// testsuite-suite reversing the line
reverseOrderedLine.reverseMeasures();
assertTrue( reverseOrderedLine.isMonotone( false ) );
assertTrue( reverseOrderedLine.isMonotone( true ) );
// testsuite-suite shifting
reverseOrderedLine.shiftMeasure( 1.0 );
assertTrue( reverseOrderedLine.isMonotone( false ) );
assertTrue( reverseOrderedLine.isMonotone( true ) );
reverseOrderedLine.shiftMeasure( -1.0 );
assertTrue( reverseOrderedLine.isMonotone( false ) );
assertTrue( reverseOrderedLine.isMonotone( true ) );
assertFalse( reverseUnOrderedLine.isMonotone( false ) );
assertFalse( reverseUnOrderedLine.isMonotone( true ) );
assertTrue( dupCoordLine.isMonotone( false ) );
assertFalse( dupCoordLine.isMonotone( true ) );
// testsuite-suite shifting
dupCoordLine.shiftMeasure( 1.0 );
assertTrue( dupCoordLine.isMonotone( false ) );
assertFalse( dupCoordLine.isMonotone( true ) );
dupCoordLine.shiftMeasure( -1.0 );
assertTrue( dupCoordLine.isMonotone( false ) );
assertFalse( dupCoordLine.isMonotone( true ) );
assertTrue( reverseDupCoordLine.isMonotone( false ) );
assertFalse( reverseDupCoordLine.isMonotone( true ) );
// testsuite-suite shifting
reverseDupCoordLine.shiftMeasure( 1.0 );
assertTrue( reverseDupCoordLine.isMonotone( false ) );
assertFalse( reverseDupCoordLine.isMonotone( true ) );
reverseDupCoordLine.shiftMeasure( -1.0 );
assertTrue( reverseDupCoordLine.isMonotone( false ) );
assertFalse( reverseDupCoordLine.isMonotone( true ) );
assertEquals( orderedLine.getMeasureDirection(), MGeometry.INCREASING );
assertEquals(
unorderedLine.getMeasureDirection(),
MGeometry.NON_MONOTONE
);
assertEquals(
reverseOrderedLine.getMeasureDirection(),
MGeometry.DECREASING
);
assertEquals( dupCoordLine.getMeasureDirection(), MGeometry.INCREASING );
assertEquals(
reverseDupCoordLine.getMeasureDirection(),
MGeometry.DECREASING
);
// Test scenario where there are NaN middle measures
MLineString internalNaNLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc0, mc1NaN, mc2NaN, mc3 } );
MLineString beginNaNLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc0NaN, mc2, mc3 } );
MLineString endNaNLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc0, mc2, mc3NaN } );
MLineString beginEndNaNLine = mgeomFactory
.createMLineString( new MCoordinate[] { mc0NaN, mc2, mc3NaN } );
assertFalse( internalNaNLine.isMonotone( false ) );
assertFalse( internalNaNLine.isMonotone( true ) );
internalNaNLine.measureOnLength( false );
assertTrue( internalNaNLine.isMonotone( false ) );
assertTrue( internalNaNLine.isMonotone( true ) );
assertFalse( beginNaNLine.isMonotone( false ) );
assertFalse( beginNaNLine.isMonotone( true ) );
beginNaNLine.measureOnLength( false );
assertTrue( beginNaNLine.isMonotone( false ) );
assertTrue( beginNaNLine.isMonotone( true ) );
assertFalse( endNaNLine.isMonotone( false ) );
assertFalse( endNaNLine.isMonotone( true ) );
endNaNLine.measureOnLength( false );
assertTrue( endNaNLine.isMonotone( false ) );
assertTrue( endNaNLine.isMonotone( true ) );
assertFalse( beginEndNaNLine.isMonotone( false ) );
assertFalse( beginEndNaNLine.isMonotone( true ) );
beginEndNaNLine.measureOnLength( false );
assertTrue( beginEndNaNLine.isMonotone( false ) );
assertTrue( beginEndNaNLine.isMonotone( true ) );
}
public void testGetCoordinatesBetweenNonStrict() {
try {
CoordinateSequenceComparator coordCompare = new CoordinateSequenceComparator();
MCoordinate mc0 = MCoordinate.create2dWithMeasure( 0.0, 0.0, 0 );
MCoordinate mc1 = MCoordinate.create2dWithMeasure( 0.0, 1.0, 1 );
MCoordinate mc2_1 = MCoordinate.create2dWithMeasure( 0.0, 2.0, 1 );
MCoordinate mc2 = MCoordinate.create2dWithMeasure( 0.0, 2.0, 2 );
MCoordinate mc3 = MCoordinate.create2dWithMeasure( 0.0, 3.0, 3 );
MCoordinate mc4 = MCoordinate.create2dWithMeasure( 0.0, 4.0, 4 );
// Test non-strict sequence where all coordinate x,y positions are
// unique, but contains a
// duplicate measure. The measure sequence in this testsuite-suite s
// [0,1,1,3,4]
MLineString nonStrictPointLine = mgeomFactory
.createMLineString(
new MCoordinate[] {
mc0, mc1, mc2_1,
mc3, mc4
}
);
CoordinateSequence[] nonStrictSeq = nonStrictPointLine
.getCoordinatesBetween( mc0.m, mc2_1.m );
assertNotNull( nonStrictSeq );
nonStrictSeq = nonStrictPointLine.getCoordinatesBetween(
mc0.m,
mc4.m
);
assertNotNull( nonStrictSeq );
nonStrictSeq = nonStrictPointLine.getCoordinatesBetween(
mc1.m,
mc4.m
);
assertNotNull( nonStrictSeq );
nonStrictSeq = nonStrictPointLine
.getCoordinatesBetween( 1.1D, mc4.m );
assertNotNull( nonStrictSeq );
}
catch ( MGeometryException e ) {
e.printStackTrace();
}
}
public void testmeasureOnLength() {
arbitraryLine.measureOnLength( false );
double maxM = arbitraryLine.getMaxM();
double minM = arbitraryLine.getMinM();
assertEquals(
maxM, arbitraryLine.getLength(), DoubleComparator
.defaultNumericalPrecision()
);
assertEquals( minM, 0.0d, DoubleComparator.defaultNumericalPrecision() );
MCoordinate mco = (MCoordinate) arbitraryLine
.getCoordinateN( arbitraryLine.getNumPoints() - 1 );
assertEquals( mco.m, maxM, DoubleComparator.defaultNumericalPrecision() );
mco = (MCoordinate) arbitraryLine.getCoordinateN( 0 );
assertEquals( mco.m, minM, DoubleComparator.defaultNumericalPrecision() );
}
public void testReverseMeasures() {
nullLine.reverseMeasures();
arbitraryLine.measureOnLength( false );
arbitraryLine.reverseMeasures();
assertTrue( arbitraryLine.getMeasureDirection() == MGeometry.DECREASING );
double mlast = arbitraryLine.getMatN( arbitraryLine.getNumPoints() - 1 );
arbitraryLine.reverseMeasures();
assertTrue( arbitraryLine.getMeasureDirection() == MGeometry.INCREASING );
double mfirst = arbitraryLine.getMatN( 0 );
assertEquals(
mlast, mfirst, DoubleComparator
.defaultNumericalPrecision()
);
}
public void testSetMatN() {
// TODO Implement setMeasureAtIndex().
}
public void testShiftMBy() {
// TODO Implement shiftMeasure().
}
/*
* Class under testsuite-suite for String toString()
*/
public void testToString() {
// TODO Implement toString().
}
public void testUnionM() {
// TODO Implement unionM().
}
public void testVerifyMonotone() {
// TODO Implement verifyMonotone().
}
}

View File

@ -1,193 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.GeometryFactory;
import junit.framework.TestCase;
/**
* @author Karel Maesen
*/
public class MultiMLineStringTest extends TestCase {
private final MCoordinateSequenceFactory mcfactory = MCoordinateSequenceFactory
.instance();
private final GeometryFactory geomfactory = new GeometryFactory( mcfactory );
protected MLineString ml1;
protected MLineString ml2;
protected MultiMLineString mm1;
protected MultiMLineString mmsimple;
protected MCoordinate lastco;
public static void main(String[] args) {
junit.textui.TestRunner.run( MultiMLineStringTest.class );
}
/*
* @see TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
MCoordinate mc0 = new MCoordinate( 0.0, 0.0, 0.0, 0.0 );
MCoordinate mc1 = new MCoordinate( 1.0, 0.0, 0.0, 0.1 );
MCoordinate mc2 = new MCoordinate( 1.0, 1.0, 0.0, 0.2 );
MCoordinate mc3 = new MCoordinate( 5.0, 1.0, 0.0, 0.3 );
MCoordinate mc4 = new MCoordinate( 5.0, 3.0, 0.0, 0.4 );
lastco = mc4;
MCoordinate[] m1 = { mc0, mc1, mc2 };
MCoordinate[] m2 = { mc3, mc4 };
CoordinateSequence mseq1 = mcfactory.create( m1 );
ml1 = new MLineString( mseq1, geomfactory );
CoordinateSequence mseq2 = mcfactory.create( m2 );
ml2 = new MLineString( mseq2, geomfactory );
mmsimple = new MultiMLineString(
new MLineString[] { ml1 }, 0.1,
geomfactory
);
mm1 = new MultiMLineString(
new MLineString[] { ml1, ml2 }, 0.1,
geomfactory
);
}
/*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
}
public void testMaxM() {
assertEquals( 0.4, mm1.getMaxM(), 0.000001 );
}
/*
* Class under testsuite-suite for java.lang.String getGeometryType()
*/
public void testGetGeometryType() {
assertTrue(
"wrong type reported", mm1.getGeometryType()
.equalsIgnoreCase( "multimlinestring" )
);
}
public void testGetDimension() {
// TODO Implement getDimension().
}
public void testGetBoundary() {
// TODO Implement getBoundary().
}
public void testGetBoundaryDimension() {
// TODO Implement getBoundaryDimension().
}
/*
* Class under testsuite-suite for boolean
* equalsExact(com.vividsolutions.jts.geom.Geometry, double)
*/
public void testEqualsExactGeometrydouble() {
// TODO Implement equalsExact().
}
/*
* Class under testsuite-suite for void
* MultiLineString(com.vividsolutions.jts.geom.LineString[],
* com.vividsolutions.jts.geom.PrecisionModel, int)
*/
public void testMultiLineStringLineStringArrayPrecisionModelint() {
// TODO Implement MultiLineString().
}
/*
* Class under testsuite-suite for void
* MultiLineString(com.vividsolutions.jts.geom.LineString[],
* com.vividsolutions.jts.geom.GeometryFactory)
*/
public void testMultiLineStringLineStringArrayGeometryFactory() {
// TODO Implement MultiLineString().
}
public void testIsClosed() {
// TODO Implement isClosed().
}
public void testClone() {
// TODO implement
}
public void testInterpolate() {
mm1.measureOnLength( false );
Coordinate[] ca = mm1.getCoordinates();
assertTrue( "co 0 not OK", ( (MCoordinate) ca[0] ).m == 0.0 );
assertTrue(
"co 1 not OK",
Math.abs( ( (MCoordinate) ca[1] ).m - 1.0 ) < 0.00001
);
assertTrue(
"co 2 not OK",
Math.abs( ( (MCoordinate) ca[2] ).m - 2.0 ) < 0.00001
);
assertTrue(
"co 3 not OK", Math.abs(
( (MCoordinate) ca[3] ).m
- ( 2.0 + mm1.getMGap() )
) < 0.00001
);
assertTrue(
"co 4 not OK", Math.abs(
( (MCoordinate) ca[4] ).m
- ( 4.0 + mm1.getMGap() )
) < 0.00001
);
double dist = mm1.getLength();
dist += ( mm1.getNumGeometries() - 1 ) * mm1.getMGap();
assertTrue(
"interpolation not consistent with distance", Math
.abs( ( (MCoordinate) ca[4] ).m - dist ) < 0.00001
);
}
}

View File

@ -1,116 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.PrecisionModel;
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() );
}
}

View File

@ -1,509 +0,0 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 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
*/
package org.hibernate.spatial.jts.mgeom;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.PrecisionModel;
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 );
}
}
}

View File

@ -25,14 +25,14 @@ import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryCollection;
import org.hibernate.spatial.jts.mgeom.MCoordinate;
/** /**
* This class tests for the equality between geometries. * This class tests for the equality between geometries.
* <p/> * <p/>
* The notion of geometric equality can differ slightly between * The notion of geometric equality can differ slightly between
* spatial databases. * spatial databases.
*/ */
//TODO -- replace by Geolatte-geom
@Deprecated
public class GeometryEquality { public class GeometryEquality {
public boolean test(Geometry geom1, Geometry geom2) { public boolean test(Geometry geom1, Geometry geom2) {
@ -116,16 +116,16 @@ public class GeometryEquality {
} }
private boolean testCoordinateEquality(Coordinate c1, Coordinate c2) { private boolean testCoordinateEquality(Coordinate c1, Coordinate c2) {
if ( c1 instanceof MCoordinate ) { // if ( c1 instanceof MCoordinate ) {
if ( !( c2 instanceof MCoordinate ) ) { // if ( !( c2 instanceof MCoordinate ) ) {
return false; // return false;
} // }
MCoordinate mc1 = (MCoordinate) c1; // MCoordinate mc1 = (MCoordinate) c1;
MCoordinate mc2 = (MCoordinate) c2; // MCoordinate mc2 = (MCoordinate) c2;
if ( !Double.isNaN( mc1.m ) && mc1.m != mc2.m ) { // if ( !Double.isNaN( mc1.m ) && mc1.m != mc2.m ) {
return false; // return false;
} // }
} // }
if ( !Double.isNaN( c1.z ) && c1.z != c2.z ) { if ( !Double.isNaN( c1.z ) && c1.z != c2.z ) {
return false; return false;
} }

View File

@ -49,6 +49,10 @@ import static org.junit.Assert.fail;
*/ */
public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCase { public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCase {
protected static String JTS = "jts";
protected static String GEOLATTE = "geolatte";
protected TestData testData; protected TestData testData;
protected DataSourceUtils dataSourceUtils; protected DataSourceUtils dataSourceUtils;
protected GeometryEquality geometryEquality; protected GeometryEquality geometryEquality;
@ -207,30 +211,45 @@ public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCa
} }
} }
protected <T> void compare(Map<Integer, T> expected, Map<Integer, T> received) { protected <T> void compare(Map<Integer, T> expected, Map<Integer, T> received, String geometryType) {
for ( Integer id : expected.keySet() ) { for ( Integer id : expected.keySet() ) {
getLogger().debug( "Case :" + id ); getLogger().debug( "Case :" + id );
getLogger().debug( "expected: " + expected.get( id ) ); getLogger().debug( "expected: " + expected.get( id ) );
getLogger().debug( "received: " + received.get( id ) ); getLogger().debug( "received: " + received.get( id ) );
compare( id, expected.get( id ), received.get( id ) ); compare( id, expected.get( id ), received.get( id ), geometryType );
} }
} }
protected void compare(Integer id, Object expected, Object received) { protected void compare(Integer id, Object expected, Object received, String geometryType) {
assertTrue( expected != null || ( expected == null && received == null ) ); assertTrue( expected != null || ( expected == null && received == null ) );
if ( expected instanceof byte[] ) { if ( expected instanceof byte[] ) {
assertArrayEquals( "Failure on testsuite-suite for case " + id, (byte[]) expected, (byte[]) received ); assertArrayEquals( "Failure on testsuite-suite for case " + id, (byte[]) expected, (byte[]) received );
} } else if ( expected instanceof Geometry ) {
else if ( expected instanceof Geometry ) { if ( geometryType == JTS ) {
if ( !( received instanceof Geometry ) ) { if ( !( received instanceof Geometry ) ) {
fail( "Expected a Geometry, but received an object of type " + received.getClass().getCanonicalName() ); fail(
"Expected a JTS Geometry, but received an object of type " + received.getClass()
.getCanonicalName()
);
} }
assertTrue( assertTrue(
"Failure on testsuite-suite for case " + id, "Failure on testsuite-suite for case " + id,
geometryEquality.test( (Geometry) expected, (Geometry) received ) geometryEquality.test( (Geometry) expected, (Geometry) received )
); );
} else {
if ( !( received instanceof org.geolatte.geom.Geometry ) ) {
fail(
"Expected a Geolatte Geometry, but received an object of type " + received.getClass()
.getCanonicalName()
);
}
assertTrue(
"Failure on testsuite-suite for case " + id,
geometryEquality.test( (Geometry) expected, (Geometry) org.geolatte.geom.jts.JTS.to((org.geolatte.geom.Geometry)received) )
);
}
} }
else { else {

View File

@ -35,6 +35,7 @@ import org.hibernate.spatial.testing.GeometryEquality;
* *
* @author Jan Boonen, Geodan IT b.v. * @author Jan Boonen, Geodan IT b.v.
*/ */
@Deprecated //NO LONGER REQUIRED
public class GeoDBGeometryEquality extends GeometryEquality { public class GeoDBGeometryEquality extends GeometryEquality {
@Override @Override

View File

@ -23,9 +23,9 @@ package org.hibernate.spatial.testing.dialects.sqlserver;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Point;
import org.geolatte.geom.codec.sqlserver.Decoders;
import org.geolatte.geom.jts.JTS; import org.geolatte.geom.jts.JTS;
import org.hibernate.spatial.dialect.sqlserver.convertors.Decoders;
import org.hibernate.spatial.testing.AbstractExpectationsFactory; import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.DataSourceUtils; import org.hibernate.spatial.testing.DataSourceUtils;
import org.hibernate.spatial.testing.NativeSQLStatement; import org.hibernate.spatial.testing.NativeSQLStatement;