HHH-11790 - Support for DB2 Spatial Extender
This commit is contained in:
parent
69ed07217e
commit
0c5c7178b8
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
jdbcDependency "com.ibm.db2:db2jcc:11.1"
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# Hibernate, Relational Persistence for Idiomatic Java
|
||||
#
|
||||
# License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
# See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
#
|
||||
|
||||
hibernate.test.new_metadata_mappings = true
|
||||
hibernate.dialect org.hibernate.spatial.dialect.db2.DB2SpatialDialect
|
||||
hibernate.connection.driver_class com.ibm.db2.jcc.DB2Driver
|
||||
hibernate.connection.url jdbc:db2://localhost:50000/hibern8
|
||||
hibernate.connection.username db2inst1
|
||||
hibernate.connection.password dbinst1-pwd
|
||||
|
||||
|
||||
hibernate.connection.pool_size 5
|
||||
|
||||
hibernate.show_sql true
|
||||
hibernate.format_sql true
|
||||
|
||||
hibernate.max_fetch_depth 5
|
||||
|
||||
hibernate.cache.region_prefix hibernate.test
|
||||
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory
|
||||
|
||||
## Ensures that all geometries that are retrieved are in WGS84
|
||||
hibernate.spatial.db2.srid 4326
|
|
@ -8,9 +8,9 @@
|
|||
hibernate.test.new_metadata_mappings = true
|
||||
hibernate.dialect org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect
|
||||
hibernate.connection.driver_class org.postgresql.Driver
|
||||
hibernate.connection.url jdbc:postgresql://localhost:5432/hibbrtru
|
||||
hibernate.connection.url jdbc:postgresql://hibpg95.cctaez8ywvn2.eu-west-1.rds.amazonaws.com:5432/hibernate
|
||||
hibernate.connection.username hibbrtru
|
||||
hibernate.connection.password hibbrtru
|
||||
hibernate.connection.password QilTygcxHwk1
|
||||
|
||||
|
||||
hibernate.connection.pool_size 5
|
||||
|
|
|
@ -14,13 +14,11 @@ dependencies {
|
|||
compile(project(':hibernate-core'))
|
||||
|
||||
compile('org.postgresql:postgresql:42.1.4')
|
||||
compile([group: 'org.geolatte', name: 'geolatte-geom', version: '1.2.0'])
|
||||
|
||||
compile([group: 'org.geolatte', name: 'geolatte-geom', version: '1.3.0'])
|
||||
compile(libraries.dom4j) {
|
||||
transitive = false
|
||||
}
|
||||
|
||||
|
||||
testCompile(libraries.junit)
|
||||
testCompile(project(':hibernate-testing'))
|
||||
testCompile([group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4'])
|
||||
|
|
|
@ -19,11 +19,20 @@ public class HibernateSpatialConfigurationSettings implements Serializable {
|
|||
private HibernateSpatialConfigurationSettings() {
|
||||
//prevent this object from being instantiated
|
||||
}
|
||||
|
||||
/**
|
||||
* The canonical class name to use as Oracle ConnectionFinder implementation.
|
||||
* The canonical class name of the Oracle ConnectionFinder implementation that will be used by the
|
||||
* Oracle spatial dialects
|
||||
*/
|
||||
|
||||
public static final String CONNECTION_FINDER = "hibernate.spatial.connection_finder";
|
||||
|
||||
/**
|
||||
* SRID to use for the DB2 Spatial Dialects.
|
||||
*
|
||||
*/
|
||||
public static final String DB2_DEFAULT_SRID = "hibernate.spatial.db2.srid";
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -18,4 +18,9 @@ public interface SpatialAggregate {
|
|||
*/
|
||||
public static final int EXTENT = 1;
|
||||
|
||||
/**
|
||||
* Enum value for union aggregate (only supported in DB2)
|
||||
*/
|
||||
public static final int UNION = 2;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.spatial.dialect.db2;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Clob;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.geolatte.geom.Geometry;
|
||||
import org.geolatte.geom.codec.db.db2.Db2ClobDecoder;
|
||||
import org.geolatte.geom.codec.db.db2.Db2ClobEncoder;
|
||||
|
||||
import org.hibernate.type.descriptor.ValueBinder;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.BasicBinder;
|
||||
import org.hibernate.type.descriptor.sql.BasicExtractor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
|
||||
/**
|
||||
* Type Descriptor for the DB2 Geometry type (as Clob)
|
||||
* <p>
|
||||
* Created by Karel Maesen, Geovise BVBA, and David Adler, Adtech Geospatial
|
||||
*/
|
||||
public class DB2GeometryTypeDescriptor implements SqlTypeDescriptor {
|
||||
|
||||
|
||||
private final Integer srid;
|
||||
|
||||
public DB2GeometryTypeDescriptor(Integer srid) {
|
||||
this.srid = srid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSqlType() {
|
||||
return Types.CLOB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeRemapped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||
|
||||
return new BasicBinder<X>( javaTypeDescriptor, this ) {
|
||||
@Override
|
||||
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
|
||||
throws SQLException {
|
||||
st.setObject( index, toText( value, options ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
|
||||
throws SQLException {
|
||||
|
||||
st.setObject( name, toText( value, options ) );
|
||||
}
|
||||
|
||||
private String toText(X value, WrapperOptions options) {
|
||||
final Geometry<?> geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
|
||||
final Db2ClobEncoder encoder = new Db2ClobEncoder();
|
||||
String encoded = encoder.encode( geometry );
|
||||
return encoded;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||
return new BasicExtractor<X>( javaTypeDescriptor, this ) {
|
||||
|
||||
@Override
|
||||
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
|
||||
return getJavaDescriptor().wrap( toGeometry( rs.getObject( name ) ), options );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
|
||||
return getJavaDescriptor().wrap( toGeometry( statement.getObject( index ) ), options );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected X doExtract(CallableStatement statement, String name, WrapperOptions options)
|
||||
throws SQLException {
|
||||
return getJavaDescriptor().wrap( toGeometry( statement.getObject( name ) ), options );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Geometry<?> toGeometry(Object object) {
|
||||
if ( object == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( object instanceof Clob ) {
|
||||
Db2ClobDecoder decoder = new Db2ClobDecoder(srid);
|
||||
return decoder.decode( (Clob) object );
|
||||
}
|
||||
|
||||
throw new IllegalStateException( "Object of type " + object.getClass()
|
||||
.getCanonicalName() + " not handled by DB2 as spatial value" );
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.spatial.dialect.db2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.spatial.GeolatteGeometryType;
|
||||
import org.hibernate.spatial.HibernateSpatialConfigurationSettings;
|
||||
import org.hibernate.spatial.JTSGeometryType;
|
||||
import org.hibernate.spatial.SpatialAggregate;
|
||||
import org.hibernate.spatial.SpatialDialect;
|
||||
import org.hibernate.spatial.SpatialFunction;
|
||||
import org.hibernate.spatial.SpatialRelation;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
/**
|
||||
* @author David Adler, Adtech Geospatial
|
||||
* creation-date: 5/22/2014
|
||||
*/
|
||||
public class DB2SpatialDialect extends DB2Dialect implements SpatialDialect {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Map<Integer, String> spatialRelationNames = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Construct a DB2Spatial dialect. Register the geometry type and spatial
|
||||
* functions supported.
|
||||
*/
|
||||
public DB2SpatialDialect() {
|
||||
super();
|
||||
registerSpatialType();
|
||||
registerSpatialFunctions();
|
||||
initializeRelationNames();
|
||||
}
|
||||
|
||||
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
final DB2GeometryTypeDescriptor typeDescriptor = mkDescriptor( serviceRegistry );
|
||||
typeContributions.contributeType( new GeolatteGeometryType( typeDescriptor ) );
|
||||
typeContributions.contributeType( new JTSGeometryType( typeDescriptor ) );
|
||||
}
|
||||
|
||||
private DB2GeometryTypeDescriptor mkDescriptor(ServiceRegistry serviceRegistry) {
|
||||
ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
|
||||
Integer srid = retrieveSridFromConfiguration( configurationService );
|
||||
return new DB2GeometryTypeDescriptor( srid );
|
||||
}
|
||||
|
||||
private Integer retrieveSridFromConfiguration(ConfigurationService configurationService) {
|
||||
Integer srid = 0;
|
||||
try {
|
||||
srid = Integer.parseInt( configurationService.getSetting(
|
||||
HibernateSpatialConfigurationSettings.DB2_DEFAULT_SRID,
|
||||
String.class,
|
||||
"0"
|
||||
) );
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new HibernateException(
|
||||
"Invalid format for configuration parameter (Integer expected): " + HibernateSpatialConfigurationSettings.DB2_DEFAULT_SRID,
|
||||
e
|
||||
);
|
||||
}
|
||||
return srid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the map relating Hibernate Spatial relation constants to DB2 function names.
|
||||
*/
|
||||
private void initializeRelationNames() {
|
||||
|
||||
spatialRelationNames.put( SpatialRelation.EQUALS, "ST_EQUALS" );
|
||||
spatialRelationNames.put( SpatialRelation.DISJOINT, "ST_DISJOINT" );
|
||||
spatialRelationNames.put( SpatialRelation.TOUCHES, "ST_TOUCHES" );
|
||||
spatialRelationNames.put( SpatialRelation.CROSSES, "ST_CROSSES" );
|
||||
spatialRelationNames.put( SpatialRelation.WITHIN, "ST_WITHIN" );
|
||||
spatialRelationNames.put( SpatialRelation.OVERLAPS, "ST_OVERLAPS" );
|
||||
spatialRelationNames.put( SpatialRelation.CONTAINS, "ST_CONTAINS" );
|
||||
spatialRelationNames.put( SpatialRelation.INTERSECTS, "ST_INTERSECTS" );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register the spatial type.
|
||||
* The type, CLOB or BLOB is defined in DB2GeometryTypeDescriptor and must match
|
||||
* the type specified in the DB2_PROGRAM transform function.
|
||||
*/
|
||||
private void registerSpatialType() {
|
||||
|
||||
// Register Geometry column type
|
||||
registerColumnType( java.sql.Types.CLOB, " db2gse.ST_Geometry" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the spatial functions supported.
|
||||
*/
|
||||
private void registerSpatialFunctions() {
|
||||
|
||||
// Register functions used as spatial predicates
|
||||
// The first parameter of registerFunction is the name that Hibernate looks for in the HQL.
|
||||
// The first parameter of StandardSQLFunction is the DB2 spatial function name that will replace it.
|
||||
// The second parameter of StandardSQLFunction is the return type of the function, always integer for functions used as predicates.
|
||||
// This is used by Hibernate independent of Hibernate Spatial.
|
||||
//
|
||||
// Note that this somewhat duplicates the information in spatialRelationNames used by getSpatialRelateSQL which
|
||||
// is invoked by Hibernate Spatial to handle SpatialRelateExpression when this is used in a Criteria.
|
||||
|
||||
registerFunction( "equals", new StandardSQLFunction(
|
||||
"db2gse.ST_Equals",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "disjoint", new StandardSQLFunction(
|
||||
"db2gse.ST_Disjoint",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "touches", new StandardSQLFunction(
|
||||
"db2gse.ST_Touches",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "crosses", new StandardSQLFunction(
|
||||
"db2gse.ST_Crosses",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
|
||||
registerFunction( "within", new StandardSQLFunction(
|
||||
"db2gse.ST_Within",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "overlaps", new StandardSQLFunction(
|
||||
"db2gse.ST_Overlaps",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "contains", new StandardSQLFunction(
|
||||
"db2gse.ST_Contains",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "intersects", new StandardSQLFunction(
|
||||
"db2gse.ST_Intersects",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "relate", new StandardSQLFunction(
|
||||
"db2gse.ST_Relate",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
|
||||
// Register functions on Geometry
|
||||
registerFunction( "dimension", new StandardSQLFunction(
|
||||
"db2gse.ST_Dimension",
|
||||
StandardBasicTypes.INTEGER
|
||||
) );
|
||||
registerFunction( "geometrytype", new StandardSQLFunction(
|
||||
"db2gse.ST_GeometryType",
|
||||
StandardBasicTypes.STRING
|
||||
) );
|
||||
registerFunction( "srid", new StandardSQLFunction(
|
||||
"db2gse.ST_Srsid",
|
||||
StandardBasicTypes.INTEGER
|
||||
) );
|
||||
registerFunction( "envelope", new StandardSQLFunction(
|
||||
"db2gse.ST_Envelope"
|
||||
) );
|
||||
registerFunction( "astext", new StandardSQLFunction(
|
||||
"db2gse.ST_AsText",
|
||||
StandardBasicTypes.STRING
|
||||
) );
|
||||
registerFunction( "asbinary", new StandardSQLFunction(
|
||||
"db2gse.ST_AsBinary",
|
||||
StandardBasicTypes.BINARY
|
||||
) );
|
||||
registerFunction( "isempty", new StandardSQLFunction(
|
||||
"db2gse.ST_IsEmpty",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "issimple", new StandardSQLFunction(
|
||||
"db2gse.ST_IsSimple",
|
||||
StandardBasicTypes.NUMERIC_BOOLEAN
|
||||
) );
|
||||
registerFunction( "boundary", new StandardSQLFunction(
|
||||
"db2gse.ST_Boundary"
|
||||
) );
|
||||
|
||||
// Register functions that support spatial analysis
|
||||
registerFunction( "distance", new StandardSQLFunction(
|
||||
"db2gse.ST_Distance",
|
||||
StandardBasicTypes.DOUBLE
|
||||
) );
|
||||
registerFunction( "buffer", new StandardSQLFunction(
|
||||
"db2gse.ST_Buffer"
|
||||
) );
|
||||
registerFunction( "convexhull", new StandardSQLFunction(
|
||||
"db2gse.ST_ConvexHull"
|
||||
) );
|
||||
registerFunction( "intersection", new StandardSQLFunction(
|
||||
"db2gse.ST_Intersection"
|
||||
) );
|
||||
registerFunction( "geomunion", new StandardSQLFunction(
|
||||
"db2gse.ST_Union"
|
||||
) );
|
||||
registerFunction( "difference", new StandardSQLFunction(
|
||||
"db2gse.ST_Difference"
|
||||
) );
|
||||
registerFunction( "symdifference", new StandardSQLFunction(
|
||||
"db2gse.ST_SymDifference"
|
||||
) );
|
||||
|
||||
// Register non-SFS functions listed in Hibernate Spatial
|
||||
|
||||
// // The srid parameter needs to be explicitly cast to INTEGER to avoid a -245 SQLCODE,
|
||||
// // ambiguous parameter.
|
||||
// registerFunction( "transform", new SQLFunctionTemplate(
|
||||
// geolatteGemetryType,
|
||||
// "DB2GSE.ST_Transform(?1, CAST (?2 AS INTEGER))"
|
||||
// ) );
|
||||
|
||||
registerFunction( "geomFromText", new StandardSQLFunction(
|
||||
"DB2GSE.ST_GeomFromText"
|
||||
) );
|
||||
|
||||
// // Register spatial aggregate function
|
||||
// registerFunction( "extent", new SQLFunctionTemplate(
|
||||
// geolatteGemetryType,
|
||||
// "db2gse.ST_GetAggrResult(MAX(db2gse.st_BuildMBRAggr(?1)))"
|
||||
// ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDWithinSQL(String columnName) {
|
||||
return "db2gse.ST_Distance(" + columnName + ",?) < ?";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHavingSridSQL(String columnName) {
|
||||
return "( db2gse.ST_srsid(" + columnName + ") = ?)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIsEmptySQL(String columnName, boolean isEmpty) {
|
||||
if ( isEmpty ) {
|
||||
return "( db2gse.ST_IsEmpty(" + columnName + ") = 1)";
|
||||
}
|
||||
else {
|
||||
return "( db2gse.ST_IsEmpty(" + columnName + ") = 0)";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpatialAggregateSQL(String columnName, int type) {
|
||||
switch ( type ) {
|
||||
case SpatialAggregate.EXTENT: // same as extent function above???
|
||||
return "db2gse.ST_GetAggrResult(MAX(db2gse.st_BuildMBRAggr(" + columnName + ")))";
|
||||
case SpatialAggregate.UNION:
|
||||
return "db2gse.ST_GetAggrResult(MAX(db2gse.st_BuildUnionAggr(" + columnName + ")))";
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Aggregation of type "
|
||||
+ type + " are not supported by this dialect"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpatialFilterExpression(String arg0) {
|
||||
throw new UnsupportedOperationException( "DB2 Dialect doesn't support spatial filtering" );
|
||||
}
|
||||
|
||||
//Temporary Fix for HHH-6074
|
||||
@Override
|
||||
public String getTypeName(int code, long length, int precision, int scale) throws HibernateException {
|
||||
if ( code == 3000 ) {
|
||||
return "DB2GSE.ST_GEOMETRY";
|
||||
}
|
||||
return super.getTypeName( code, length, precision, scale );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
|
||||
String relationName = spatialRelationNames.get( spatialRelation );
|
||||
if ( relationName != null ) {
|
||||
if ( spatialRelation != SpatialRelation.DISJOINT ) {
|
||||
return " db2gse." + relationName + "(" + columnName + ", ?) = 1 SELECTIVITY .0001";
|
||||
}
|
||||
else { // SELECTIVITY not supported for ST_Disjoint UDF
|
||||
return " db2gse." + relationName + "(" + columnName + ", ?) = 1";
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"Spatial relation " + spatialRelation + " not implemented" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(SpatialFunction function) {
|
||||
return (getFunctions().get( function.toString() ) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFiltering() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package org.hibernate.spatial.integration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
//import org.geolatte.geom.C3DM;
|
||||
//import org.geolatte.geom.Geometry;
|
||||
//import org.geolatte.geom.GeometryEquality;
|
||||
//import org.geolatte.geom.GeometryPointEquality;
|
||||
import org.geolatte.geom.codec.WktDecodeException;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.spatial.integration.geolatte.GeomEntity;
|
||||
import org.hibernate.spatial.testing.GeometryEquality;
|
||||
import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
|
||||
import org.hibernate.spatial.testing.TestDataElement;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Created by Karel Maesen, Geovise BVBA on 15/02/2018.
|
||||
*/
|
||||
public abstract class AbstractTestStoreRetrieve<G, E extends GeomEntityLike<G>> extends SpatialFunctionalTestCase {
|
||||
|
||||
|
||||
public void prepareTest() {
|
||||
|
||||
}
|
||||
|
||||
protected abstract GeometryEquality<G> getGeometryEquality();
|
||||
|
||||
protected abstract Class<E> getGeomEntityClass();
|
||||
|
||||
protected abstract E createFrom(TestDataElement element, Dialect dialect);
|
||||
|
||||
@Test
|
||||
public void testAfterStoreRetrievingEqualObject() throws WktDecodeException {
|
||||
Map<Integer, E> stored = new HashMap<>();
|
||||
//check whether we retrieve exactly what we store
|
||||
storeTestObjects( stored );
|
||||
retrieveAndCompare( stored );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoringNullGeometries() {
|
||||
storeNullGeometry();
|
||||
retrieveNullGeometry();
|
||||
}
|
||||
|
||||
private void retrieveAndCompare(Map<Integer, E> stored) {
|
||||
int id = -1;
|
||||
Transaction tx = null;
|
||||
Session session = null;
|
||||
GeometryEquality<G> geomEq = getGeometryEquality();
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
for ( E storedEntity : stored.values() ) {
|
||||
id = storedEntity.getId();
|
||||
E retrievedEntity = (E) session.get( getGeomEntityClass(), id );
|
||||
G retrievedGeometry = retrievedEntity.getGeom();
|
||||
G storedGeometry = storedEntity.getGeom();
|
||||
String msg = createFailureMessage( storedEntity.getId(), storedGeometry, retrievedGeometry );
|
||||
assertTrue( msg, geomEq.test( storedGeometry, retrievedGeometry ) );
|
||||
}
|
||||
tx.commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
throw new RuntimeException( String.format( "Failure on case: %d", id ), e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String createFailureMessage(int id, G storedGeometry, G retrievedGeometry) {
|
||||
String expectedText = ( storedGeometry != null ? storedGeometry.toString() : "NULL" );
|
||||
String retrievedText = ( retrievedGeometry != null ? retrievedGeometry.toString() : "NULL" );
|
||||
return String.format(
|
||||
"Equality testsuite-suite failed for %d.%nExpected: %s%nReceived:%s",
|
||||
id,
|
||||
expectedText,
|
||||
retrievedText
|
||||
);
|
||||
}
|
||||
|
||||
private void storeTestObjects(Map<Integer, E> stored) {
|
||||
Session session = null;
|
||||
Transaction tx = null;
|
||||
int id = -1;
|
||||
try {
|
||||
session = openSession();
|
||||
Dialect dialect = sessionFactory().getJdbcServices().getDialect();
|
||||
// Every testsuite-suite instance is committed seperately
|
||||
// to improve feedback in case of failure
|
||||
for ( TestDataElement element : testData ) {
|
||||
id = element.id;
|
||||
tx = session.beginTransaction();
|
||||
;
|
||||
E entity = createFrom( element, dialect );
|
||||
stored.put( entity.getId(), entity );
|
||||
session.save( entity );
|
||||
tx.commit();
|
||||
}
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
throw new RuntimeException( "Failed storing testsuite-suite object with id:" + id, e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void storeNullGeometry() {
|
||||
GeomEntity entity = null;
|
||||
Session session = null;
|
||||
Transaction tx = null;
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
entity = new GeomEntity();
|
||||
entity.setId( 1 );
|
||||
entity.setType( "NULL OBJECT" );
|
||||
session.save( entity );
|
||||
tx.commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
Integer id = entity != null ? entity.getId() : -1;
|
||||
throw new RuntimeException( "Failed storing testsuite-suite object with id:" + id, e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void retrieveNullGeometry() {
|
||||
Transaction tx = null;
|
||||
Session session = null;
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
Criteria criteria = session.createCriteria( GeomEntity.class );
|
||||
List<GeomEntity> retrieved = criteria.list();
|
||||
assertEquals( "Expected exactly one result", 1, retrieved.size() );
|
||||
GeomEntity entity = retrieved.get( 0 );
|
||||
assertNull( entity.getGeom() );
|
||||
tx.commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.hibernate.spatial.integration;
|
||||
|
||||
import org.geolatte.geom.codec.Wkt;
|
||||
import org.geolatte.geom.codec.WktDecoder;
|
||||
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.spatial.dialect.db2.DB2SpatialDialect;
|
||||
|
||||
/**
|
||||
* Created by Karel Maesen, Geovise BVBA on 15/02/2018.
|
||||
*/
|
||||
public class DecodeUtil {
|
||||
|
||||
public static WktDecoder getWktDecoder(Dialect dialect) {
|
||||
WktDecoder decoder = null;
|
||||
if ( dialect instanceof AbstractHANADialect ) {
|
||||
decoder = Wkt.newDecoder( Wkt.Dialect.HANA_EWKT );
|
||||
}
|
||||
else if ( dialect instanceof DB2SpatialDialect ) {
|
||||
decoder = Wkt.newDecoder( Wkt.Dialect.DB2_WKT );
|
||||
}
|
||||
else{
|
||||
decoder = Wkt.newDecoder( Wkt.Dialect.POSTGIS_EWKT_1 );
|
||||
}
|
||||
return decoder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.hibernate.spatial.integration;
|
||||
|
||||
import org.geolatte.geom.codec.WktDecodeException;
|
||||
import org.geolatte.geom.codec.WktDecoder;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.spatial.testing.TestDataElement;
|
||||
|
||||
import static org.hibernate.spatial.integration.DecodeUtil.getWktDecoder;
|
||||
|
||||
/**
|
||||
* Created by Karel Maesen, Geovise BVBA on 15/02/2018.
|
||||
*/
|
||||
public interface GeomEntityLike<G> {
|
||||
|
||||
Integer getId();
|
||||
|
||||
void setId(Integer id);
|
||||
|
||||
String getType();
|
||||
|
||||
void setType(String type);
|
||||
|
||||
G getGeom();
|
||||
|
||||
void setGeom(G geom);
|
||||
}
|
|
@ -11,15 +11,16 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.spatial.integration.GeomEntityLike;
|
||||
import org.hibernate.spatial.testing.TestDataElement;
|
||||
|
||||
import org.geolatte.geom.Geometry;
|
||||
import org.geolatte.geom.codec.Wkt;
|
||||
import org.geolatte.geom.codec.WktDecodeException;
|
||||
import org.geolatte.geom.codec.WktDecoder;
|
||||
|
||||
import static org.hibernate.spatial.integration.DecodeUtil.getWktDecoder;
|
||||
|
||||
/**
|
||||
* Test class used in unit testing.
|
||||
*
|
||||
|
@ -29,7 +30,18 @@ import org.geolatte.geom.codec.WktDecoder;
|
|||
*/
|
||||
@Entity
|
||||
@Table(name = "geomtest")
|
||||
public class GeomEntity {
|
||||
public class GeomEntity implements GeomEntityLike<Geometry> {
|
||||
|
||||
static GeomEntity createFrom(TestDataElement element, Dialect dialect) throws WktDecodeException {
|
||||
WktDecoder decoder = getWktDecoder( dialect );
|
||||
Geometry geom = decoder.decode( element.wkt );
|
||||
GeomEntity result = new GeomEntity();
|
||||
result.setId( element.id );
|
||||
result.setGeom( geom );
|
||||
result.setType( element.type );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
@ -38,45 +50,36 @@ public class GeomEntity {
|
|||
|
||||
private Geometry geom;
|
||||
|
||||
@Override
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Geometry getGeom() {
|
||||
return geom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGeom(Geometry geom) {
|
||||
this.geom = geom;
|
||||
}
|
||||
|
||||
public static GeomEntity createFrom(TestDataElement element, Dialect dialect) throws WktDecodeException {
|
||||
WktDecoder decoder = null;
|
||||
if (dialect instanceof AbstractHANADialect) {
|
||||
decoder = Wkt.newDecoder( Wkt.Dialect.HANA_EWKT );
|
||||
}
|
||||
else {
|
||||
decoder = Wkt.newDecoder( Wkt.Dialect.POSTGIS_EWKT_1 );
|
||||
}
|
||||
Geometry geom = decoder.decode( element.wkt );
|
||||
GeomEntity result = new GeomEntity();
|
||||
result.setId( element.id );
|
||||
result.setGeom( geom );
|
||||
result.setType( element.type );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
|
|
@ -6,28 +6,20 @@
|
|||
*/
|
||||
package org.hibernate.spatial.integration.geolatte;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.geolatte.geom.C3DM;
|
||||
import org.geolatte.geom.Geometry;
|
||||
import org.geolatte.geom.GeometryEquality;
|
||||
import org.geolatte.geom.GeometryPointEquality;
|
||||
import org.geolatte.geom.codec.WktDecodeException;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.spatial.HSMessageLogger;
|
||||
import org.hibernate.spatial.integration.AbstractTestStoreRetrieve;
|
||||
import org.hibernate.spatial.integration.GeomEntityLike;
|
||||
import org.hibernate.spatial.testing.GeolatteGeometryEquality;
|
||||
import org.hibernate.spatial.testing.GeometryEquality;
|
||||
import org.hibernate.spatial.testing.SpatialDialectMatcher;
|
||||
import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
|
||||
import org.hibernate.spatial.testing.TestDataElement;
|
||||
|
||||
import org.hibernate.testing.Skip;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
@ -39,7 +31,7 @@ import static org.junit.Assert.assertTrue;
|
|||
* are equal to the <code>Geometry</code>s stored.
|
||||
*/
|
||||
@Skip(condition = SpatialDialectMatcher.class, message = "No Spatial Dialect")
|
||||
public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
|
||||
public class TestStoreRetrieveUsingGeolatte extends AbstractTestStoreRetrieve<Geometry, GeomEntity> {
|
||||
|
||||
private static HSMessageLogger LOG = Logger.getMessageLogger(
|
||||
HSMessageLogger.class,
|
||||
|
@ -50,148 +42,19 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
|
|||
return LOG;
|
||||
}
|
||||
|
||||
public void prepareTest() {
|
||||
|
||||
@Override
|
||||
protected GeometryEquality getGeometryEquality() {
|
||||
return new GeolatteGeometryEquality();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterStoreRetrievingEqualObject() throws WktDecodeException {
|
||||
Map<Integer, GeomEntity> stored = new HashMap<Integer, GeomEntity>();
|
||||
//check whether we retrieve exactly what we store
|
||||
storeTestObjects( stored );
|
||||
retrieveAndCompare( stored );
|
||||
@Override
|
||||
protected Class getGeomEntityClass() {
|
||||
return GeomEntity.class;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoringNullGeometries() {
|
||||
storeNullGeometry();
|
||||
retrieveNullGeometry();
|
||||
}
|
||||
|
||||
private void retrieveAndCompare(Map<Integer, GeomEntity> stored) {
|
||||
int id = -1;
|
||||
Transaction tx = null;
|
||||
Session session = null;
|
||||
GeometryEquality geomEq = new GeometryPointEquality();
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
for ( GeomEntity storedEntity : stored.values() ) {
|
||||
id = storedEntity.getId();
|
||||
GeomEntity retrievedEntity = (GeomEntity) session.get( GeomEntity.class, id );
|
||||
Geometry<C3DM> retrievedGeometry = retrievedEntity.getGeom();
|
||||
Geometry<C3DM> storedGeometry = storedEntity.getGeom();
|
||||
String msg = createFailureMessage( storedEntity.getId(), storedGeometry, retrievedGeometry );
|
||||
assertTrue( msg, geomEq.equals( storedGeometry, retrievedGeometry ) );
|
||||
}
|
||||
tx.commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
throw new RuntimeException( String.format( "Failure on case: %d", id ), e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String createFailureMessage(int id, Geometry storedGeometry, Geometry retrievedGeometry) {
|
||||
String expectedText = ( storedGeometry != null ? storedGeometry.toString() : "NULL" );
|
||||
String retrievedText = ( retrievedGeometry != null ? retrievedGeometry.toString() : "NULL" );
|
||||
return String.format(
|
||||
"Equality testsuite-suite failed for %d.%nExpected: %s%nReceived:%s",
|
||||
id,
|
||||
expectedText,
|
||||
retrievedText
|
||||
);
|
||||
}
|
||||
|
||||
private void storeTestObjects(Map<Integer, GeomEntity> stored) {
|
||||
Session session = null;
|
||||
Transaction tx = null;
|
||||
int id = -1;
|
||||
try {
|
||||
session = openSession();
|
||||
Dialect dialect = sessionFactory().getSessionFactory().getJdbcServices().getDialect();
|
||||
// Every testsuite-suite instance is committed seperately
|
||||
// to improve feedback in case of failure
|
||||
for ( TestDataElement element : testData ) {
|
||||
id = element.id;
|
||||
tx = session.beginTransaction();
|
||||
;
|
||||
GeomEntity entity = GeomEntity.createFrom( element, dialect );
|
||||
stored.put( entity.getId(), entity );
|
||||
session.save( entity );
|
||||
tx.commit();
|
||||
}
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
throw new RuntimeException( "Failed storing testsuite-suite object with id:" + id, e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void storeNullGeometry() {
|
||||
GeomEntity entity = null;
|
||||
Session session = null;
|
||||
Transaction tx = null;
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
entity = new GeomEntity();
|
||||
entity.setId( 1 );
|
||||
entity.setType( "NULL OBJECT" );
|
||||
session.save( entity );
|
||||
tx.commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
Integer id = entity != null ? entity.getId() : -1;
|
||||
throw new RuntimeException( "Failed storing testsuite-suite object with id:" + id, e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void retrieveNullGeometry() {
|
||||
Transaction tx = null;
|
||||
Session session = null;
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
Criteria criteria = session.createCriteria( GeomEntity.class );
|
||||
List<GeomEntity> retrieved = criteria.list();
|
||||
assertEquals( "Expected exactly one result", 1, retrieved.size() );
|
||||
GeomEntity entity = retrieved.get( 0 );
|
||||
assertNull( entity.getGeom() );
|
||||
tx.commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected GeomEntity createFrom(
|
||||
TestDataElement element, Dialect dialect) throws WktDecodeException {
|
||||
return GeomEntity.createFrom( element, dialect );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,14 +18,17 @@ import org.geolatte.geom.codec.WktDecoder;
|
|||
import org.geolatte.geom.jts.JTS;
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.spatial.integration.GeomEntityLike;
|
||||
import org.hibernate.spatial.testing.TestDataElement;
|
||||
|
||||
import static org.hibernate.spatial.integration.DecodeUtil.getWktDecoder;
|
||||
|
||||
/**
|
||||
* Test class used in unit testing.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "geomtest")
|
||||
public class GeomEntity {
|
||||
public class GeomEntity implements GeomEntityLike<Geometry> {
|
||||
|
||||
|
||||
@Id
|
||||
|
@ -60,13 +63,7 @@ public class GeomEntity {
|
|||
}
|
||||
|
||||
public static GeomEntity createFrom(TestDataElement element, Dialect dialect) throws ParseException {
|
||||
WktDecoder decoder = null;
|
||||
if (dialect instanceof AbstractHANADialect) {
|
||||
decoder = Wkt.newDecoder( Wkt.Dialect.HANA_EWKT );
|
||||
}
|
||||
else {
|
||||
decoder = Wkt.newDecoder( Wkt.Dialect.POSTGIS_EWKT_1 );
|
||||
}
|
||||
WktDecoder decoder = getWktDecoder( dialect );
|
||||
Geometry geom = JTS.to( decoder.decode( element.wkt ) );
|
||||
GeomEntity result = new GeomEntity();
|
||||
result.setId( element.id );
|
||||
|
|
|
@ -6,37 +6,27 @@
|
|||
*/
|
||||
package org.hibernate.spatial.integration.jts;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.io.ParseException;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.spatial.HSMessageLogger;
|
||||
import org.hibernate.spatial.integration.AbstractTestStoreRetrieve;
|
||||
import org.hibernate.spatial.testing.GeometryEquality;
|
||||
import org.hibernate.spatial.testing.JTSGeometryEquality;
|
||||
import org.hibernate.spatial.testing.SpatialDialectMatcher;
|
||||
import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
|
||||
import org.hibernate.spatial.testing.TestDataElement;
|
||||
import org.hibernate.testing.Skip;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.hibernate.testing.Skip;
|
||||
|
||||
/**
|
||||
* This testsuite-suite class verifies whether the <code>Geometry</code>s retrieved
|
||||
* are equal to the <code>Geometry</code>s stored.
|
||||
*/
|
||||
@Skip(condition = SpatialDialectMatcher.class, message = "No Spatial Dialect")
|
||||
public class TestStoreRetrieveUsingJTS extends SpatialFunctionalTestCase {
|
||||
public class TestStoreRetrieveUsingJTS extends AbstractTestStoreRetrieve<Geometry, GeomEntity> {
|
||||
|
||||
private static final HSMessageLogger LOG = Logger.getMessageLogger(
|
||||
HSMessageLogger.class,
|
||||
|
@ -48,146 +38,26 @@ public class TestStoreRetrieveUsingJTS extends SpatialFunctionalTestCase {
|
|||
return LOG;
|
||||
}
|
||||
|
||||
public void prepareTest() {
|
||||
|
||||
@Override
|
||||
protected GeometryEquality<Geometry> getGeometryEquality() {
|
||||
return new JTSGeometryEquality();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterStoreRetrievingEqualObject() throws ParseException {
|
||||
Map<Integer, GeomEntity> stored = new HashMap<Integer, GeomEntity>();
|
||||
//check whether we retrieve exactly what we store
|
||||
storeTestObjects( stored );
|
||||
retrieveAndCompare( stored );
|
||||
@Override
|
||||
protected Class<GeomEntity> getGeomEntityClass() {
|
||||
return GeomEntity.class;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoringNullGeometries() {
|
||||
storeNullGeometry();
|
||||
retrieveNullGeometry();
|
||||
}
|
||||
|
||||
private void retrieveAndCompare(Map<Integer, GeomEntity> stored) {
|
||||
int id = -1;
|
||||
Transaction tx = null;
|
||||
Session session = null;
|
||||
@Override
|
||||
protected GeomEntity createFrom(
|
||||
TestDataElement element, Dialect dialect) {
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
for ( GeomEntity storedEntity : stored.values() ) {
|
||||
id = storedEntity.getId();
|
||||
GeomEntity retrievedEntity = (GeomEntity) session.get( GeomEntity.class, id );
|
||||
Geometry retrievedGeometry = retrievedEntity.getGeom();
|
||||
Geometry storedGeometry = storedEntity.getGeom();
|
||||
String msg = createFailureMessage( storedEntity.getId(), storedGeometry, retrievedGeometry );
|
||||
assertTrue( msg, geometryEquality.test( storedGeometry, retrievedGeometry ) );
|
||||
}
|
||||
tx.commit();
|
||||
return GeomEntity.createFrom( element, dialect );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
throw new RuntimeException( String.format( "Failure on case: %d", id ), e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String createFailureMessage(int id, Geometry storedGeometry, Geometry retrievedGeometry) {
|
||||
String expectedText = ( storedGeometry != null ? storedGeometry.toText() : "NULL" );
|
||||
String retrievedText = ( retrievedGeometry != null ? retrievedGeometry.toText() : "NULL" );
|
||||
return String.format(
|
||||
"Equality testsuite-suite failed for %d.%nExpected: %s%nReceived:%s",
|
||||
id,
|
||||
expectedText,
|
||||
retrievedText
|
||||
);
|
||||
}
|
||||
|
||||
private void storeTestObjects(Map<Integer, GeomEntity> stored) {
|
||||
Session session = null;
|
||||
Transaction tx = null;
|
||||
int id = -1;
|
||||
try {
|
||||
session = openSession();
|
||||
Dialect dialect = sessionFactory().getSessionFactory().getJdbcServices().getDialect();
|
||||
// Every testsuite-suite instance is committed seperately
|
||||
// to improve feedback in case of failure
|
||||
for ( TestDataElement element : testData ) {
|
||||
id = element.id;
|
||||
tx = session.beginTransaction();
|
||||
GeomEntity entity = GeomEntity.createFrom( element, dialect );
|
||||
stored.put( entity.getId(), entity );
|
||||
session.save( entity );
|
||||
tx.commit();
|
||||
}
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
throw new RuntimeException( "Failed storing testsuite-suite object with id:" + id, e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void storeNullGeometry() {
|
||||
GeomEntity entity = null;
|
||||
Session session = null;
|
||||
Transaction tx = null;
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
entity = new GeomEntity();
|
||||
entity.setId( 1 );
|
||||
entity.setType( "NULL OBJECT" );
|
||||
session.save( entity );
|
||||
tx.commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
Integer id = entity != null ? entity.getId() : -1;
|
||||
throw new RuntimeException( "Failed storing testsuite-suite object with id:" + id, e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void retrieveNullGeometry() {
|
||||
Transaction tx = null;
|
||||
Session session = null;
|
||||
try {
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
Criteria criteria = session.createCriteria( GeomEntity.class );
|
||||
List<GeomEntity> retrieved = criteria.list();
|
||||
assertEquals( "Expected exactly one result", 1, retrieved.size() );
|
||||
GeomEntity entity = retrieved.get( 0 );
|
||||
assertNull( entity.getGeom() );
|
||||
tx.commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
if ( tx != null ) {
|
||||
tx.rollback();
|
||||
}
|
||||
catch (ParseException e) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
finally {
|
||||
if ( session != null ) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -785,7 +785,8 @@ public abstract class AbstractExpectationsFactory {
|
|||
try {
|
||||
cn = createConnection();
|
||||
preparedStatement = nativeSQLStatement.prepare( cn );
|
||||
LOG.info( "Native SQL is: " + preparedStatement.toString() );
|
||||
LOG.info( "Native SQL is: " + nativeSQLStatement.toString() );
|
||||
|
||||
results = preparedStatement.executeQuery();
|
||||
while ( results.next() ) {
|
||||
int id = results.getInt( 1 );
|
||||
|
@ -851,6 +852,9 @@ public abstract class AbstractExpectationsFactory {
|
|||
public PreparedStatement prepare(Connection connection) throws SQLException {
|
||||
return connection.prepareStatement( sql );
|
||||
}
|
||||
public String toString() {
|
||||
return sql;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -863,6 +867,9 @@ public abstract class AbstractExpectationsFactory {
|
|||
}
|
||||
return pstmt;
|
||||
}
|
||||
public String toString(){
|
||||
return String.format("sql; %s, wkt: %s", sql, wkt);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -876,6 +883,9 @@ public abstract class AbstractExpectationsFactory {
|
|||
}
|
||||
return pstmt;
|
||||
}
|
||||
public String toString(){
|
||||
return sql;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package org.hibernate.spatial.testing;
|
||||
|
||||
import org.geolatte.geom.Geometry;
|
||||
import org.geolatte.geom.GeometryPointEquality;
|
||||
import org.geolatte.geom.Position;
|
||||
|
||||
/**
|
||||
* Created by Karel Maesen, Geovise BVBA on 15/02/2018.
|
||||
*/
|
||||
public class GeolatteGeometryEquality<P extends Position> implements GeometryEquality<Geometry<P>>{
|
||||
|
||||
private final org.geolatte.geom.GeometryEquality delegate;
|
||||
|
||||
public GeolatteGeometryEquality(){
|
||||
this( new GeometryPointEquality());
|
||||
}
|
||||
|
||||
public GeolatteGeometryEquality(org.geolatte.geom.GeometryEquality delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Geometry<P> geom1, Geometry<P> geom2) {
|
||||
return delegate.equals( geom1, geom2 );
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,124 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.testing;
|
||||
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.GeometryCollection;
|
||||
|
||||
/**
|
||||
* This class tests for the equality between geometries.
|
||||
* <p/>
|
||||
* The notion of geometric equality can differ slightly between
|
||||
* spatial databases.
|
||||
*
|
||||
* @deprecated Should be replaced by Geolatte-geom GeometryEquality
|
||||
* Created by Karel Maesen, Geovise BVBA on 15/02/2018.
|
||||
*/
|
||||
@Deprecated
|
||||
public class GeometryEquality {
|
||||
|
||||
public boolean test(Geometry geom1, Geometry geom2) {
|
||||
return test( geom1, geom2, false );
|
||||
}
|
||||
|
||||
private boolean test(Geometry geom1, Geometry geom2, boolean ignoreSRID) {
|
||||
if ( geom1 == null ) {
|
||||
return geom2 == null;
|
||||
}
|
||||
if ( geom1.isEmpty() ) {
|
||||
return geom2.isEmpty();
|
||||
}
|
||||
if ( !ignoreSRID && !equalSRID( geom1, geom2 ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( geom1 instanceof GeometryCollection ) {
|
||||
if ( !(geom2 instanceof GeometryCollection) ) {
|
||||
return false;
|
||||
}
|
||||
GeometryCollection expectedCollection = (GeometryCollection) geom1;
|
||||
GeometryCollection receivedCollection = (GeometryCollection) geom2;
|
||||
for ( int partIndex = 0; partIndex < expectedCollection.getNumGeometries(); partIndex++ ) {
|
||||
Geometry partExpected = expectedCollection.getGeometryN( partIndex );
|
||||
Geometry partReceived = receivedCollection.getGeometryN( partIndex );
|
||||
if ( !test( partExpected, partReceived, true ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return testSimpleGeometryEquality( geom1, geom2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Two geometries are equal iff both have the same SRID, or both are unknown (i.e. a SRID of 0 or -1).
|
||||
*
|
||||
* @param geom1
|
||||
* @param geom2
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean equalSRID(Geometry geom1, Geometry geom2) {
|
||||
return geom1.getSRID() == geom2.getSRID() ||
|
||||
(geom1.getSRID() < 1 && geom2.getSRID() < 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether two geometries, not of type GeometryCollection are equal.
|
||||
*
|
||||
* @param geom1
|
||||
* @param geom2
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected boolean testSimpleGeometryEquality(Geometry geom1, Geometry geom2) {
|
||||
//return geom1.equals(geom2);
|
||||
return testTypeAndVertexEquality( geom1, geom2 );
|
||||
}
|
||||
|
||||
protected boolean testTypeAndVertexEquality(Geometry geom1, Geometry geom2) {
|
||||
if ( !geom1.getGeometryType().equals( geom2.getGeometryType() ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( geom1.getNumGeometries() != geom2.getNumGeometries() ) {
|
||||
return false;
|
||||
}
|
||||
if ( geom1.getNumPoints() != geom2.getNumPoints() ) {
|
||||
return false;
|
||||
}
|
||||
Coordinate[] coordinates1 = geom1.getCoordinates();
|
||||
Coordinate[] coordinates2 = geom2.getCoordinates();
|
||||
for ( int i = 0; i < coordinates1.length; i++ ) {
|
||||
Coordinate c1 = coordinates1[i];
|
||||
Coordinate c2 = coordinates2[i];
|
||||
if ( !testCoordinateEquality( c1, c2 ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean testCoordinateEquality(Coordinate c1, Coordinate c2) {
|
||||
// if ( c1 instanceof MCoordinate ) {
|
||||
// if ( !( c2 instanceof MCoordinate ) ) {
|
||||
// return false;
|
||||
// }
|
||||
// MCoordinate mc1 = (MCoordinate) c1;
|
||||
// MCoordinate mc2 = (MCoordinate) c2;
|
||||
// if ( !Double.isNaN( mc1.m ) && mc1.m != mc2.m ) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
if ( !Double.isNaN( c1.z ) && c1.z != c2.z ) {
|
||||
return false;
|
||||
}
|
||||
return c1.x == c2.x && c1.y == c2.y;
|
||||
}
|
||||
public interface GeometryEquality<G> {
|
||||
boolean test(G geom1, G geom2);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.testing;
|
||||
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.GeometryCollection;
|
||||
|
||||
/**
|
||||
* This class tests for the equality between geometries.
|
||||
* <p/>
|
||||
* The notion of geometric equality can differ slightly between
|
||||
* spatial databases.
|
||||
*/
|
||||
public class JTSGeometryEquality implements GeometryEquality<Geometry> {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean test(Geometry geom1, Geometry geom2) {
|
||||
if ( geom1 == null ) {
|
||||
return geom2 == null;
|
||||
}
|
||||
if ( geom1.isEmpty() ) {
|
||||
return geom2.isEmpty();
|
||||
}
|
||||
if ( !equalSRID( geom1, geom2 ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( geom1 instanceof GeometryCollection ) {
|
||||
if ( !(geom2 instanceof GeometryCollection) ) {
|
||||
return false;
|
||||
}
|
||||
GeometryCollection expectedCollection = (GeometryCollection) geom1;
|
||||
GeometryCollection receivedCollection = (GeometryCollection) geom2;
|
||||
for ( int partIndex = 0; partIndex < expectedCollection.getNumGeometries(); partIndex++ ) {
|
||||
Geometry partExpected = expectedCollection.getGeometryN( partIndex );
|
||||
Geometry partReceived = receivedCollection.getGeometryN( partIndex );
|
||||
if ( !test( partExpected, partReceived ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return testSimpleGeometryEquality( geom1, geom2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Two geometries are equal iff both have the same SRID, or both are unknown (i.e. a SRID of 0 or -1).
|
||||
*
|
||||
* @param geom1
|
||||
* @param geom2
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean equalSRID(Geometry geom1, Geometry geom2) {
|
||||
return geom1.getSRID() == geom2.getSRID() ||
|
||||
(geom1.getSRID() < 1 && geom2.getSRID() < 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether two geometries, not of type GeometryCollection are equal.
|
||||
*
|
||||
* @param geom1
|
||||
* @param geom2
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected boolean testSimpleGeometryEquality(Geometry geom1, Geometry geom2) {
|
||||
//return geom1.equals(geom2);
|
||||
return testTypeAndVertexEquality( geom1, geom2 );
|
||||
}
|
||||
|
||||
protected boolean testTypeAndVertexEquality(Geometry geom1, Geometry geom2) {
|
||||
if ( !geom1.getGeometryType().equals( geom2.getGeometryType() ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( geom1.getNumGeometries() != geom2.getNumGeometries() ) {
|
||||
return false;
|
||||
}
|
||||
if ( geom1.getNumPoints() != geom2.getNumPoints() ) {
|
||||
return false;
|
||||
}
|
||||
Coordinate[] coordinates1 = geom1.getCoordinates();
|
||||
Coordinate[] coordinates2 = geom2.getCoordinates();
|
||||
for ( int i = 0; i < coordinates1.length; i++ ) {
|
||||
Coordinate c1 = coordinates1[i];
|
||||
Coordinate c2 = coordinates2[i];
|
||||
if ( !testCoordinateEquality( c1, c2 ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean testCoordinateEquality(Coordinate c1, Coordinate c2) {
|
||||
return (Double.isNaN( c1.z ) || !(c1.z != c2.z)) && c1.x == c2.x && c1.y == c2.y;
|
||||
}
|
||||
}
|
|
@ -30,4 +30,6 @@ public interface NativeSQLStatement {
|
|||
* @throws SQLException
|
||||
*/
|
||||
public PreparedStatement prepare(Connection connection) throws SQLException;
|
||||
|
||||
public String toString();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCa
|
|||
|
||||
protected TestData testData;
|
||||
protected DataSourceUtils dataSourceUtils;
|
||||
protected GeometryEquality geometryEquality;
|
||||
protected JTSGeometryEquality geometryEquality;
|
||||
protected AbstractExpectationsFactory expectationsFactory;
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,8 +27,8 @@ public abstract class TestSupport {
|
|||
return new DataSourceUtils( driver(), url(), user(), passwd(), getSQLExpressionTemplate() );
|
||||
}
|
||||
|
||||
public GeometryEquality createGeometryEquality() {
|
||||
return new GeometryEquality();
|
||||
public JTSGeometryEquality createGeometryEquality() {
|
||||
return new JTSGeometryEquality();
|
||||
}
|
||||
|
||||
public abstract TestData createTestData(BaseCoreFunctionalTestCase testcase);
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.hibernate.spatial.testing;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.PostgreSQL82Dialect;
|
||||
import org.hibernate.spatial.SpatialDialect;
|
||||
import org.hibernate.spatial.testing.dialects.db2.DB2TestSupport;
|
||||
import org.hibernate.spatial.testing.dialects.h2geodb.GeoDBTestSupport;
|
||||
import org.hibernate.spatial.testing.dialects.hana.HANATestSupport;
|
||||
import org.hibernate.spatial.testing.dialects.mysql.MySQL56TestSupport;
|
||||
|
@ -80,6 +81,10 @@ public class TestSupportFactories {
|
|||
if ( "org.hibernate.spatial.dialect.hana.HANASpatialDialect".equals( canonicalName ) ) {
|
||||
return HANATestSupport.class;
|
||||
}
|
||||
|
||||
if ("org.hibernate.spatial.dialect.db2.DB2SpatialDialect".equals( canonicalName )) {
|
||||
return DB2TestSupport.class;
|
||||
}
|
||||
throw new IllegalArgumentException( "Dialect not known in test suite" );
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2014 Adtech Geospatial
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* 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.testing.dialects.db2;
|
||||
|
||||
import org.hibernate.spatial.testing.DataSourceUtils;
|
||||
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author David Adler, Adtech Geospatial
|
||||
* creation-date: 5/22/2014
|
||||
*/
|
||||
public class DB2DataSourceUtils extends DataSourceUtils {
|
||||
|
||||
public DB2DataSourceUtils(String jdbcDriver, String jdbcUrl, String jdbcUser, String jdbcPass, SQLExpressionTemplate sqlExpressionTemplate) {
|
||||
super(jdbcDriver, jdbcUrl, jdbcUser, jdbcPass, sqlExpressionTemplate);
|
||||
}
|
||||
|
||||
private void createIndex() throws SQLException {
|
||||
String sql = "create index idx_spatial_geomtest on geomtest (geom) extend using db2gse.spatial_index(0.1,0,0)";
|
||||
executeStatement(sql);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2014 Adtech Geospatial
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* 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.testing.dialects.db2;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.Point;
|
||||
import org.geolatte.geom.jts.JTS;
|
||||
|
||||
import org.hibernate.spatial.dialect.db2.DB2GeometryTypeDescriptor;
|
||||
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
|
||||
import org.hibernate.spatial.testing.DataSourceUtils;
|
||||
import org.hibernate.spatial.testing.NativeSQLStatement;
|
||||
|
||||
/**
|
||||
* This class provides the DB2 native spatial queries to generate the
|
||||
* results which will be compared with the HQL spatial results.
|
||||
*
|
||||
* @author David Adler, Adtech Geospatial
|
||||
* creation-date: 5/22/2014
|
||||
*/
|
||||
public class DB2ExpectationsFactory extends AbstractExpectationsFactory {
|
||||
|
||||
public DB2ExpectationsFactory(DataSourceUtils utils) {
|
||||
super( utils );
|
||||
}
|
||||
|
||||
private final DB2GeometryTypeDescriptor desc = new DB2GeometryTypeDescriptor(4326);
|
||||
/**
|
||||
* Returns the expected extent of all testsuite-suite geometries.
|
||||
*
|
||||
* @return map of identifier, extent
|
||||
*
|
||||
* @throws SQLException
|
||||
*/
|
||||
public Map<Integer, Geometry> getExtent() throws SQLException {
|
||||
return retrieveExpected( createNativeExtentStatement(), GEOMETRY );
|
||||
}
|
||||
|
||||
protected NativeSQLStatement createNativeExtentStatement() {
|
||||
return createNativeSQLStatement(
|
||||
"select max(t.id), db2gse.ST_GetAggrResult(MAX(db2gse.st_BuildMBRAggr(t.geom))) from GeomTest t where db2gse.st_srid(t.geom) = 4326" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeTouchesStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_touches(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_touches(t.geom, DB2GSE.ST_geomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeOverlapsStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_overlaps(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_overlaps(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeRelateStatement(Geometry geom, String matrix) {
|
||||
String sql = "select t.id, DB2GSE.ST_relate(t.geom, DB2GSE.ST_GeomFromText(?, 4326), '" + matrix + "' ) from GeomTest t where DB2GSE.ST_relate(t.geom, DB2GSE.ST_GeomFromText(?, 4326), '" + matrix + "') = 1 and db2gse.st_srid(t.geom) = 4326";
|
||||
return createNativeSQLStatementAllWKTParams( sql, geom.toText() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDwithinStatement(Point geom, double distance) {
|
||||
String sql = "select t.id, DB2GSE.ST_dwithin(t.geom, DB2GSE.ST_GeomFromText(?, 4326), " + distance + " ) from GeomTest t where DB2GSE.ST_dwithin(t.geom, DB2GSE.ST_GeomFromText(?, 4326), " + distance + ") = 1 and db2gse.st_srid(t.geom) = 4326";
|
||||
return createNativeSQLStatementAllWKTParams( sql, geom.toText() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeIntersectsStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_intersects(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_intersects(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeFilterStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom && ST_GeomFromText(?, 4326) from GeomTest t where DB2GSE.ST_intersects(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDistanceStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_distance(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_SRID(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDimensionSQL() {
|
||||
return createNativeSQLStatement( "select id, DB2GSE.ST_dimension(geom) from geomtest" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeBufferStatement(Double distance) {
|
||||
return createNativeSQLStatement(
|
||||
"select t.id, DB2GSE.ST_buffer(t.geom,?) from GeomTest t where DB2GSE.ST_SRID(t.geom) = 4326",
|
||||
new Object[] {distance}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeConvexHullStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_convexhull(DB2GSE.ST_Union(t.geom, DB2GSE.ST_GeomFromText(?, 4326))) from GeomTest t where DB2GSE.ST_SRID(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeIntersectionStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_intersection(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_SRID(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDifferenceStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_difference(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_SRID(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeSymDifferenceStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_symdifference(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_SRID(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeGeomUnionStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_union(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_SRID(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeTransformStatement(int epsg) {
|
||||
return createNativeSQLStatement(
|
||||
"select t.id, DB2GSE.ST_transform(t.geom," + epsg + ") from GeomTest t where DB2GSE.ST_SRID(t.geom) = 4326"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeHavingSRIDStatement(int srid) {
|
||||
return createNativeSQLStatement(
|
||||
"select t.id, DB2GSE.st_srid(t.geom) from GeomTest t where DB2GSE.ST_SRID(t.geom) = " + srid );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeAsTextStatement() {
|
||||
return createNativeSQLStatement( "select id, DB2GSE.st_astext(geom) from geomtest" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeSridStatement() {
|
||||
return createNativeSQLStatement( "select id, DB2GSE.ST_SRID(geom) from geomtest" );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeIsSimpleStatement() {
|
||||
return createNativeSQLStatement( "select id, DB2GSE.ST_issimple(geom) from geomtest" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeIsEmptyStatement() {
|
||||
return createNativeSQLStatement(
|
||||
"select id, DB2GSE.ST_isempty(geom) from geomtest where db2gse.ST_IsEmpty(geom) = 1" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeIsNotEmptyStatement() { // return 'not ST_IsEmpty', 'not' is not supported by DB2
|
||||
return createNativeSQLStatement(
|
||||
"select id, case when DB2GSE.ST_isempty(geom) = 0 then 1 else 0 end from geomtest where db2gse.ST_IsEmpty(geom) = 0" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeBoundaryStatement() {
|
||||
return createNativeSQLStatement( "select id, DB2GSE.ST_boundary(geom) from geomtest" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeEnvelopeStatement() {
|
||||
return createNativeSQLStatement( "select id, DB2GSE.ST_envelope(geom) from geomtest" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeAsBinaryStatement() {
|
||||
return createNativeSQLStatement( "select id, DB2GSE.ST_asbinary(geom) from geomtest" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeGeometryTypeStatement() {
|
||||
return createNativeSQLStatement( "select id, DB2GSE.ST_GeometryType(geom) from geomtest" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeWithinStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_within(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_within(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeEqualsStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_equals(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_equals(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeCrossesStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_crosses(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_crosses(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeContainsStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_contains(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_contains(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDisjointStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, DB2GSE.ST_disjoint(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) from GeomTest t where DB2GSE.ST_disjoint(t.geom, DB2GSE.ST_GeomFromText(?, 4326)) = 1 and db2gse.st_srid(t.geom) = 4326",
|
||||
geom.toText()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry decode(Object o) {
|
||||
org.geolatte.geom.Geometry<?> geometry = desc.toGeometry( o );
|
||||
return geometry == null ? null : JTS.to( geometry );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2014 Adtech Geospatial
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* 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.testing.dialects.db2;
|
||||
|
||||
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
||||
import org.hibernate.spatial.testing.TestDataElement;
|
||||
import org.hibernate.spatial.testing.WktUtility;
|
||||
|
||||
/**
|
||||
* @author David Adler
|
||||
* creation-date: 5/22/2014
|
||||
*/
|
||||
public class DB2ExpressionTemplate implements SQLExpressionTemplate {
|
||||
|
||||
final String SQL_TEMPLATE = "insert into geomtest (id, type, geom) values (%d, '%s', DB2GSE.ST_GEOMETRY('%s', %d))";
|
||||
|
||||
public String toInsertSql(TestDataElement testDataElement) {
|
||||
String wkt = WktUtility.getWkt( testDataElement.wkt );
|
||||
int srid = WktUtility.getSRID( testDataElement.wkt );
|
||||
return String.format(
|
||||
SQL_TEMPLATE,
|
||||
testDataElement.id,
|
||||
testDataElement.type,
|
||||
wkt,
|
||||
srid
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2014 Adtech Geospatial
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* 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.testing.dialects.db2;
|
||||
|
||||
import org.hibernate.spatial.testing.DataSourceUtils;
|
||||
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
||||
import org.hibernate.spatial.testing.TestData;
|
||||
import org.hibernate.spatial.testing.TestSupport;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @author David Adler, Adtech Geospatial
|
||||
* creation-date: 5/22/2014
|
||||
*/
|
||||
public class DB2TestSupport extends TestSupport {
|
||||
|
||||
public TestData createTestData(BaseCoreFunctionalTestCase testcase) {
|
||||
if ( "org.hibernate.spatial.integration.TestSpatialFunctions".equals( testcase.getClass().getCanonicalName() ) ) {
|
||||
return TestData.fromFile( "db2/test-db2nozm-only-polygon.xml" );
|
||||
}
|
||||
return TestData.fromFile( "db2/test-db2nozm-data-set.xml" );
|
||||
}
|
||||
|
||||
public DB2ExpectationsFactory createExpectationsFactory(DataSourceUtils dataSourceUtils) {
|
||||
return new DB2ExpectationsFactory( dataSourceUtils );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLExpressionTemplate getSQLExpressionTemplate() {
|
||||
return new DB2ExpressionTemplate();
|
||||
}
|
||||
|
||||
}
|
|
@ -13,7 +13,7 @@ package org.hibernate.spatial.testing.dialects.h2geodb;
|
|||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
||||
import org.hibernate.spatial.testing.GeometryEquality;
|
||||
import org.hibernate.spatial.testing.JTSGeometryEquality;
|
||||
|
||||
/**
|
||||
* Extends the test for {@link Geometry} equality, because GeoDB uses JTS
|
||||
|
@ -23,7 +23,7 @@ import org.hibernate.spatial.testing.GeometryEquality;
|
|||
* @deprecated This should no longer be necesseary
|
||||
*/
|
||||
@Deprecated
|
||||
public class GeoDBGeometryEquality extends GeometryEquality {
|
||||
public class GeoDBGeometryEquality extends JTSGeometryEquality {
|
||||
|
||||
@Override
|
||||
public boolean test(Geometry geom1, Geometry geom2) {
|
||||
|
|
|
@ -13,7 +13,7 @@ import java.sql.SQLException;
|
|||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
|
||||
import org.hibernate.spatial.testing.DataSourceUtils;
|
||||
import org.hibernate.spatial.testing.GeometryEquality;
|
||||
import org.hibernate.spatial.testing.JTSGeometryEquality;
|
||||
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
||||
import org.hibernate.spatial.testing.TestData;
|
||||
import org.hibernate.spatial.testing.TestSupport;
|
||||
|
@ -43,7 +43,7 @@ public class GeoDBTestSupport extends TestSupport {
|
|||
return TestData.fromFile( "h2geodb/test-geodb-data-set.xml" );
|
||||
}
|
||||
|
||||
public GeometryEquality createGeometryEquality() {
|
||||
public JTSGeometryEquality createGeometryEquality() {
|
||||
return new GeoDBGeometryEquality();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,13 +10,13 @@ package org.hibernate.spatial.testing.dialects.mysql;
|
|||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
||||
import org.hibernate.spatial.testing.GeometryEquality;
|
||||
import org.hibernate.spatial.testing.JTSGeometryEquality;
|
||||
|
||||
/**
|
||||
* Extends the test for geometry equality, because
|
||||
* MySQL stores empty geometries as NULL objects.
|
||||
*/
|
||||
public class MySQLGeometryEquality extends GeometryEquality {
|
||||
public class MySQLGeometryEquality extends JTSGeometryEquality {
|
||||
|
||||
@Override
|
||||
public boolean test(Geometry geom1, Geometry geom2) {
|
||||
|
|
|
@ -10,7 +10,7 @@ package org.hibernate.spatial.testing.dialects.mysql;
|
|||
|
||||
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
|
||||
import org.hibernate.spatial.testing.DataSourceUtils;
|
||||
import org.hibernate.spatial.testing.GeometryEquality;
|
||||
import org.hibernate.spatial.testing.JTSGeometryEquality;
|
||||
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
||||
import org.hibernate.spatial.testing.TestData;
|
||||
import org.hibernate.spatial.testing.TestSupport;
|
||||
|
@ -34,7 +34,7 @@ public class MySQLTestSupport extends TestSupport {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GeometryEquality createGeometryEquality() {
|
||||
public JTSGeometryEquality createGeometryEquality() {
|
||||
return new MySQLGeometryEquality();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
EWKTReader doesn't work with the test data for Z or M data. It tests for 'POINTM' but the data is 'POINT M'.
|
||||
|
||||
TestSpatialFunctions failures:
|
||||
transform:
|
||||
DB2 transform functions between spatial reference systems with the same datum but not different datums.
|
||||
This causes the transform test in TestSpatialFunctions to fail because it transforms from WGS84 to WGS_1972_Transit_Broadcast_Ephemeris
|
|
@ -0,0 +1,67 @@
|
|||
-- pagesize of 8k needed for enable_db operation
|
||||
create database sample pagesize 8 k;
|
||||
connect to sample;
|
||||
|
||||
-- spatially-enable the database; create spatial types, functions and stored procedures
|
||||
!db2se enable_db sample;
|
||||
|
||||
-- create the spatial reference system for EPSG 4326 (WGS84)
|
||||
-- this is the same as the Spatial Extender default srid 1003
|
||||
!db2se drop_srs sample
|
||||
-srsName EPSG4326
|
||||
;
|
||||
|
||||
!db2se create_srs sample
|
||||
-srsName EPSG4326
|
||||
-srsId 4326
|
||||
-coordsysName GCS_WGS_1984
|
||||
-xOffset -180
|
||||
-xScale 1000000
|
||||
-yOffset -90
|
||||
-zOffset 0
|
||||
-zScale 1
|
||||
-mOffset 0
|
||||
-mScale 1
|
||||
;
|
||||
|
||||
-- Create SQL function to return EWKT format from a geometry
|
||||
create or replace function db2gse.asewkt(geometry db2gse.st_geometry)
|
||||
returns clob(2G)
|
||||
specific db2gse.asewkt1
|
||||
language sql
|
||||
deterministice
|
||||
no external action
|
||||
reads sql data
|
||||
return 'srid=' || varchar(db2gse.st_srsid(geometry)) || ';' || db2gse.st_astext(geometry)
|
||||
;
|
||||
|
||||
-- Create SQL function to create a geometry from EWKT format
|
||||
create or replace function db2gse.geomfromewkt(instring varchar(32000))
|
||||
returns db2gse.st_geometry
|
||||
specific db2gse.fromewkt1
|
||||
language sql
|
||||
deterministic
|
||||
no external action
|
||||
reads sql data
|
||||
return db2gse.st_geometry(
|
||||
substr(instring,posstr(instring,';')+1, length(instring) - posstr(instring,';')),
|
||||
integer(substr(instring,posstr(instring,'=')+1,posstr(instring,';')-(posstr(instring,'=')+1)))
|
||||
)
|
||||
;
|
||||
|
||||
-- Create a DB2 transform group to return and accept EWKT
|
||||
CREATE TRANSFORM FOR db2gse.ST_Geometry EWKT (
|
||||
FROM SQL WITH FUNCTION db2gse.asewkt(db2gse.ST_Geometry),
|
||||
TO SQL WITH FUNCTION db2gse.geomfromewkt(varchar(32000)) )
|
||||
;
|
||||
|
||||
-- Redefine the default DB2_PROGRAM to return and accept EWKT instead of WKT
|
||||
DROP TRANSFORM DB2_PROGRAM FOR db2gse.ST_Geometry;
|
||||
CREATE TRANSFORM FOR db2gse.ST_Geometry DB2_PROGRAM (
|
||||
FROM SQL WITH FUNCTION db2gse.asewkt(db2gse.ST_Geometry),
|
||||
TO SQL WITH FUNCTION db2gse.geomfromewkt(varchar(32000)) )
|
||||
;
|
||||
|
||||
-- Give the test userid authority to create and access tables
|
||||
grant dataaccess on database to hstest;
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
<TestData>
|
||||
<Element>
|
||||
<id>1</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=0;POINT(10 5)</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>2</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT(52.25 2.53)</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>4</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT ZM(10.0 2.0 1.0 3.0)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>5</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING(10.0 5.0, 20.0 15.0)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>6</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING(10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>7</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING Z(10.0 5.0 0.0, 20.0 15.0 3.0)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>8</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING ZM(10.0 5.0 0.0 0.0, 20.0 15.0 3.0 1.0)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>9</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING M(10.0 5.0 1, 20.0 15.0 2, 30.3 22.4 5, 10 30.0 2)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>10</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING ZM(10.0 5.0 1 1, 20.0 15.0 2 3, 30.3 22.4 5 10, 10 30.0 2 12)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>11</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0))</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>12</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING((10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0), (40.0 20.0, 42.0 18.0, 43.0 16.0, 40
|
||||
14.0))
|
||||
</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>13</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING Z((10.0 5.0 1.0, 20.0 15.0 2.0, 30.3 22.4 1.0, 10 30.0 1.0),(40.0 20.0 0.0, 42.0
|
||||
18.0 1.0,
|
||||
43.0 16.0 2.0, 40 14.0 3.0))
|
||||
</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>14</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING ZM((10.0 5.0 1.0 0.0, 20.0 15.0 2.0 0.0, 30.3 22.4 1.0 1.0, 10 30.0 1.0
|
||||
2.0),(40.0 20.0 0.0
|
||||
3.0, 42.0 18.0 1.0 4.0, 43.0 16.0 2.0 5.0, 40 14.0 3.0 6.0))
|
||||
</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>15</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING ZM((10.0 5.0 1.0 0.0, 20.0 15.0 2.0 0.0, 30.3 22.4 1.0 1.0, 10 30.0 1.0 2.0))
|
||||
</wkt>
|
||||
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>16</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0) )</wkt>
|
||||
|
||||
</Element>
|
||||
<Element>
|
||||
<id>17</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON Z( (0 0 0, 0 10 1, 10 10 1, 10 0 1, 0 0 0) )</wkt>
|
||||
|
||||
</Element>
|
||||
<Element>
|
||||
<id>18</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 5, 5 5,5 2, 2 2))</wkt>
|
||||
|
||||
</Element>
|
||||
<Element>
|
||||
<id>19</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON( (110 110, 110 120, 120 120, 120 110, 110 110) )</wkt>
|
||||
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>20</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100, 120 140, 130 134, 105 100)) )</wkt>
|
||||
|
||||
</Element>
|
||||
<Element>
|
||||
<id>21</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON Z( ((10 20 1, 30 40 2, 44 50 2, 10 20 1)), ((105 100 0, 120 140 10, 130 134 20, 105
|
||||
100 0)) )
|
||||
</wkt>
|
||||
|
||||
</Element>
|
||||
<Element>
|
||||
<id>22</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON(( (0 0, 0 50, 50 50, 50 0, 0 0), (10 10, 10 20, 20 20, 20 10, 10 10) ),((105 100,
|
||||
120 140, 130
|
||||
134, 105 100)) )
|
||||
</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>26</id>
|
||||
<type>MULTIPOINT</type>
|
||||
<wkt>SRID=4326;MULTIPOINT(21 2)</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>27</id>
|
||||
<type>MULTIPOINT</type>
|
||||
<wkt>SRID=4326;MULTIPOINT Z(21 2 1, 25 5 2, 30 3 5)</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>28</id>
|
||||
<type>MULTIPOINT</type>
|
||||
<wkt>SRID=4326;MULTIPOINT ZM(21 2 1 0, 25 5 2 4, 30 3 5 2)</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>50</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT EMPTY</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>51</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING EMPTY</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>52</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON EMPTY</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>53</id>
|
||||
<type>MULTIPOINT</type>
|
||||
<wkt>SRID=4326;MULTIPOINT EMPTY</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>54</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING EMPTY</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>55</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
</TestData>
|
|
@ -0,0 +1,127 @@
|
|||
<TestData>
|
||||
<Element>
|
||||
<id>1</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT(10 5)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>2</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT(52.25 2.53)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>5</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING(10.0 5.0, 20.0 15.0)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>6</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING(10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>11</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0))</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>12</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING((10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0), (40.0 20.0, 42.0 18.0, 43.0 16.0, 40 14.0))
|
||||
</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>16</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON( (0 0, 10 0, 10 10, 0 10, 0 0) )</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>18</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 5, 5 5, 5 2, 2 2))</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>19</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON( (110 110, 120 110, 120 120, 110 120, 110 110) )</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>20</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON(((105 100, 130 134, 120 140, 105 100)), ((10 20, 44 50, 30 40, 10 20)))</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>22</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON(((0 0, 50 0, 50 50, 0 50, 0 0), (10 10, 10 20, 20 20, 20 10, 10 10)), ((105 100, 130 134, 120 140, 105 100)))
|
||||
</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>50</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>51</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>52</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>53</id>
|
||||
<type>MULTIPOINT</type>
|
||||
<wkt>SRID=4326;MULTIPOINT EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>54</id>
|
||||
<type>MULTILINESTRING</type>
|
||||
<wkt>SRID=4326;MULTILINESTRING EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>55</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
<!-- Z, M and ZM Geometries -->
|
||||
<!-- Due to the default definition of the SRID in DB2, the M and Z values need to be whole integers -->
|
||||
<Element>
|
||||
<id>56</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT Z(4.23 50.32 10)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>57</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT M(4.23 50.32 10)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>58</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT ZM(4.23 50.32 5 10)</wkt>
|
||||
</Element>
|
||||
|
||||
|
||||
</TestData>
|
|
@ -0,0 +1,46 @@
|
|||
<TestData>
|
||||
|
||||
<Element>
|
||||
<id>16</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON( (0 0, 10 0, 10 10, 0 10, 0 0) )</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>18</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 5, 5 5, 5 2, 2 2))</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>19</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON( (110 110, 120 110, 120 120, 110 120, 110 110) )</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>20</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON(((105 100, 130 134, 120 140, 105 100)), ((10 20, 44 50, 30 40, 10 20)))</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>22</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON(((0 0, 50 0, 50 50, 0 50, 0 0), (10 10, 10 20, 20 20, 20 10, 10 10)), ((105 100, 130 134, 120 140, 105 100)))
|
||||
</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>52</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>55</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<wkt>SRID=4326;MULTIPOLYGON EMPTY</wkt>
|
||||
</Element>
|
||||
|
||||
</TestData>
|
|
@ -107,3 +107,13 @@ hibernate.connection.password @jdbc.pass@
|
|||
#hibernate.connection.url jdbc:sap://localhost:30015
|
||||
#hibernate.connection.username HIBERNATE_TEST
|
||||
#hibernate.connection.password H1bernate_test
|
||||
|
||||
##
|
||||
## DB2 dialect
|
||||
##
|
||||
#hibernate.dialect org.hibernate.spatial.dialect.db2.DB2SpatialDialect
|
||||
#hibernate.connection.driver_class com.ibm.db2.jcc.DB2Driver
|
||||
#hibernate.connection.url jdbc:db2://localhost:50000/hibern8
|
||||
#hibernate.spatial.db2.srid 4326
|
||||
#hibernate.connection.username db2inst1
|
||||
#hibernate.connection.password dbinst1-pwd
|
||||
|
|
Loading…
Reference in New Issue