Fix Hibernate Spatial test on SAP HANA
This commit is contained in:
parent
54b506ecf4
commit
8de0f9e2a1
|
@ -25,14 +25,18 @@ public class HANAGeometryTypeDescriptor implements SqlTypeDescriptor {
|
|||
|
||||
private static final long serialVersionUID = -6978798264716544804L;
|
||||
|
||||
/**
|
||||
* An instance of the descrtiptor
|
||||
*/
|
||||
public static final HANAGeometryTypeDescriptor INSTANCE = new HANAGeometryTypeDescriptor();
|
||||
public static final HANAGeometryTypeDescriptor CRS_LOADING_INSTANCE = new HANAGeometryTypeDescriptor( true );
|
||||
public static final HANAGeometryTypeDescriptor INSTANCE = new HANAGeometryTypeDescriptor( false );
|
||||
|
||||
final boolean determineCrsIdFromDatabase;
|
||||
|
||||
public HANAGeometryTypeDescriptor(boolean determineCrsIdFromDatabase) {
|
||||
this.determineCrsIdFromDatabase = determineCrsIdFromDatabase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSqlType() {
|
||||
return Types.ARRAY;
|
||||
return Types.OTHER;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -67,7 +71,12 @@ public class HANAGeometryTypeDescriptor implements SqlTypeDescriptor {
|
|||
|
||||
@Override
|
||||
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
|
||||
return getJavaDescriptor().wrap( HANASpatialUtils.toGeometry( rs.getObject( name ) ), options );
|
||||
if ( HANAGeometryTypeDescriptor.this.determineCrsIdFromDatabase ) {
|
||||
return getJavaDescriptor().wrap( HANASpatialUtils.toGeometry( rs, name ), options );
|
||||
}
|
||||
else {
|
||||
return getJavaDescriptor().wrap( HANASpatialUtils.toGeometry( rs.getObject( name ) ), options );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.spatial.dialect.hana;
|
|||
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.dialect.HANAColumnStoreDialect;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService.Converter;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.spatial.GeolatteGeometryType;
|
||||
import org.hibernate.spatial.JTSGeometryType;
|
||||
|
@ -21,6 +23,8 @@ public class HANASpatialDialect extends HANAColumnStoreDialect implements Spatia
|
|||
|
||||
private static final long serialVersionUID = -432631517465714911L;
|
||||
|
||||
private static final String DETERMINE_CRS_ID_FROM_DATABASE_PARAMETER_NAME = "hibernate.spatial.dialect.hana.determine_crs_id_from_database";
|
||||
|
||||
public HANASpatialDialect() {
|
||||
registerColumnType( HANAGeometryTypeDescriptor.INSTANCE.getSqlType(), "ST_GEOMETRY" );
|
||||
registerColumnType( HANAPointTypeDescriptor.INSTANCE.getSqlType(), "ST_POINT" );
|
||||
|
@ -62,7 +66,7 @@ public class HANASpatialDialect extends HANAColumnStoreDialect implements Spatia
|
|||
registerFunction( SpatialFunction.overlaps.name(),
|
||||
new HANASpatialFunction( "ST_Overlaps", StandardBasicTypes.NUMERIC_BOOLEAN, true ) );
|
||||
registerFunction( SpatialFunction.relate.name(),
|
||||
new HANASpatialFunction( "ST_Relate", StandardBasicTypes.INTEGER, true ) );
|
||||
new HANASpatialFunction( "ST_Relate", StandardBasicTypes.NUMERIC_BOOLEAN, true ) );
|
||||
registerFunction( SpatialFunction.srid.name(),
|
||||
new HANASpatialFunction( "ST_SRID", StandardBasicTypes.INTEGER, false ) );
|
||||
registerFunction( SpatialFunction.symdifference.name(), new HANASpatialFunction( "ST_SymDifference", true ) );
|
||||
|
@ -102,8 +106,29 @@ public class HANASpatialDialect extends HANAColumnStoreDialect implements Spatia
|
|||
@Override
|
||||
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
super.contributeTypes( typeContributions, serviceRegistry );
|
||||
typeContributions.contributeType( new GeolatteGeometryType( HANAGeometryTypeDescriptor.INSTANCE ) );
|
||||
typeContributions.contributeType( new JTSGeometryType( HANAGeometryTypeDescriptor.INSTANCE ) );
|
||||
|
||||
final ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
|
||||
boolean determineCrsIdFromDatabase = configurationService.getSetting(
|
||||
DETERMINE_CRS_ID_FROM_DATABASE_PARAMETER_NAME,
|
||||
new Converter<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean convert(Object value) {
|
||||
return Boolean.valueOf( value.toString() );
|
||||
}
|
||||
|
||||
},
|
||||
Boolean.FALSE ).booleanValue();
|
||||
|
||||
if ( determineCrsIdFromDatabase ) {
|
||||
typeContributions.contributeType( new GeolatteGeometryType( HANAGeometryTypeDescriptor.CRS_LOADING_INSTANCE ) );
|
||||
typeContributions.contributeType( new JTSGeometryType( HANAGeometryTypeDescriptor.CRS_LOADING_INSTANCE ) );
|
||||
}
|
||||
else {
|
||||
typeContributions.contributeType( new GeolatteGeometryType( HANAGeometryTypeDescriptor.INSTANCE ) );
|
||||
typeContributions.contributeType( new JTSGeometryType( HANAGeometryTypeDescriptor.INSTANCE ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -203,5 +228,4 @@ public class HANASpatialDialect extends HANAColumnStoreDialect implements Spatia
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import org.hibernate.type.Type;
|
|||
|
||||
public class HANASpatialFunction extends StandardSQLFunction {
|
||||
|
||||
private static final String AS_EWKB_SUFFIX = ".ST_AsEWKB()";
|
||||
|
||||
private final boolean firstArgumentIsGeometryType;
|
||||
|
||||
public HANASpatialFunction(String name, boolean firstArgumentIsGeometryType) {
|
||||
|
@ -33,14 +35,22 @@ public class HANASpatialFunction extends StandardSQLFunction {
|
|||
}
|
||||
else {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append( arguments.get( 0 ) ).append( "." ).append( getName() ).append( '(' );
|
||||
// If the first argument is an expression, e.g. a nested function, strip the .ST_AsEWKB() suffix
|
||||
buf.append( stripEWKBSuffix( arguments.get( 0 ) ) );
|
||||
|
||||
// Add function call
|
||||
buf.append( "." ).append( getName() ).append( '(' );
|
||||
|
||||
// Add function arguments
|
||||
for ( int i = 1; i < arguments.size(); i++ ) {
|
||||
final Object argument = arguments.get( i );
|
||||
final boolean parseFromWKB = this.firstArgumentIsGeometryType && i == 1 && "?".equals( argument );
|
||||
// Check if first argument needs to be parsed from EWKB. This is the case if the first argument is a
|
||||
// parameter that is set as EWKB or if it's a nested function call.
|
||||
final boolean parseFromWKB = ( this.firstArgumentIsGeometryType && i == 1 && "?".equals( argument ) );
|
||||
if ( parseFromWKB ) {
|
||||
buf.append( "ST_GeomFromEWKB(" );
|
||||
}
|
||||
buf.append( argument );
|
||||
buf.append( stripEWKBSuffix( argument ) );
|
||||
if ( parseFromWKB ) {
|
||||
buf.append( ")" );
|
||||
}
|
||||
|
@ -49,7 +59,20 @@ public class HANASpatialFunction extends StandardSQLFunction {
|
|||
}
|
||||
}
|
||||
buf.append( ')' );
|
||||
// If it doesn't specify an explicit type, assume it's a geometry
|
||||
if ( this.getType() == null ) {
|
||||
buf.append( AS_EWKB_SUFFIX );
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private Object stripEWKBSuffix(Object argument) {
|
||||
if ( ( argument instanceof String ) && ( (String) argument ).endsWith( AS_EWKB_SUFFIX ) ) {
|
||||
String argumentString = (String) argument;
|
||||
return argumentString.substring( 0, argumentString.length() - AS_EWKB_SUFFIX.length() );
|
||||
}
|
||||
|
||||
return argument;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
package org.hibernate.spatial.dialect.hana;
|
||||
|
||||
import java.sql.Blob;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.geolatte.geom.ByteBuffer;
|
||||
|
@ -18,7 +21,95 @@ import org.geolatte.geom.codec.WkbEncoder;
|
|||
|
||||
public class HANASpatialUtils {
|
||||
|
||||
private static final int POSTGIS_SRID_FLAG = 0x20000000;
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public static Geometry<?> toGeometry(ResultSet rs, String name) throws SQLException {
|
||||
ByteBuffer buffer = toByteBuffer( rs.getObject( name ) );
|
||||
|
||||
if ( buffer == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get table and column names from the result set metadata
|
||||
String tableName = null;
|
||||
String columnName = null;
|
||||
for ( int i = 1; i <= rs.getMetaData().getColumnCount(); i++ ) {
|
||||
if ( name.equals( rs.getMetaData().getColumnLabel( i ) ) || name.toUpperCase().equals( rs.getMetaData().getColumnLabel( i ) ) ) {
|
||||
tableName = rs.getMetaData().getTableName( i );
|
||||
columnName = rs.getMetaData().getColumnName( i );
|
||||
}
|
||||
}
|
||||
|
||||
assert tableName != null;
|
||||
assert columnName != null;
|
||||
|
||||
// no table and/or column names found (
|
||||
if ( tableName.isEmpty() || columnName.isEmpty() ) {
|
||||
return toGeometry( buffer );
|
||||
}
|
||||
|
||||
byte orderByte = buffer.get();
|
||||
int typeCode = (int) buffer.getUInt();
|
||||
|
||||
Connection connection = rs.getStatement().getConnection();
|
||||
|
||||
// Check if SRID is set
|
||||
if ( ( typeCode & POSTGIS_SRID_FLAG ) != POSTGIS_SRID_FLAG ) {
|
||||
// No SRID set => try to get SRID from the database
|
||||
try ( PreparedStatement psSrid = connection
|
||||
.prepareStatement( "SELECT SRS_ID FROM SYS.ST_GEOMETRY_COLUMNS WHERE SCHEMA_NAME=CURRENT_SCHEMA AND TABLE_NAME=? AND COLUMN_NAME=?" ) ) {
|
||||
psSrid.setString( 1, tableName );
|
||||
psSrid.setString( 2, columnName );
|
||||
|
||||
try ( ResultSet rsSrid = psSrid.executeQuery() ) {
|
||||
if ( rsSrid.next() ) {
|
||||
int crsId = rsSrid.getInt( 1 );
|
||||
buffer = addCrsId( buffer.toByteArray(), orderByte, typeCode, crsId );
|
||||
}
|
||||
else {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toGeometry( buffer );
|
||||
}
|
||||
|
||||
private static ByteBuffer addCrsId(byte[] wkb, byte orderByte, int typeCode, int crsId) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate( wkb.length + 4 ); // original capacity + 4 bytes for the CRS ID
|
||||
buffer.setByteOrder( ByteOrder.valueOf( orderByte ) );
|
||||
|
||||
buffer.put( orderByte ); // write byte order
|
||||
|
||||
buffer.putUInt( typeCode | POSTGIS_SRID_FLAG ); // set SRID flag
|
||||
|
||||
buffer.putInt( crsId ); // write CRS ID
|
||||
|
||||
// write remaining data
|
||||
|
||||
for ( int i = 5; i < wkb.length; i++ ) {
|
||||
buffer.put( wkb[i] );
|
||||
}
|
||||
|
||||
buffer.rewind();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Geometry<?> toGeometry(Object obj) {
|
||||
return toGeometry( toByteBuffer( obj ) );
|
||||
}
|
||||
|
||||
private static Geometry<?> toGeometry(ByteBuffer buffer) {
|
||||
if ( buffer == null ) {
|
||||
return null;
|
||||
}
|
||||
WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.HANA_EWKB );
|
||||
return decoder.decode( buffer );
|
||||
}
|
||||
|
||||
private static ByteBuffer toByteBuffer(Object obj) {
|
||||
byte[] raw = null;
|
||||
if ( obj == null ) {
|
||||
return null;
|
||||
|
@ -34,9 +125,8 @@ public class HANASpatialUtils {
|
|||
}
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.from( raw );
|
||||
|
||||
WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.HANA_EWKB );
|
||||
return decoder.decode( buffer );
|
||||
buffer.setByteOrder( ByteOrder.valueOf( raw[0] ) );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static byte[] toByteArray(Blob blob) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.Transaction;
|
|||
import org.hibernate.spatial.HSMessageLogger;
|
||||
import org.hibernate.spatial.SpatialFunction;
|
||||
import org.hibernate.spatial.dialect.h2geodb.GeoDBDialect;
|
||||
import org.hibernate.spatial.dialect.hana.HANASpatialDialect;
|
||||
import org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect;
|
||||
import org.hibernate.spatial.testing.SpatialDialectMatcher;
|
||||
import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
|
||||
|
@ -239,7 +240,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Boolean> dbexpected = expectationsFactory.getWithin( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, within(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where within(geom, :filter) = true and srid(geom) = 4326", pckg
|
||||
"where within(geom, :filter) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -262,7 +263,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Boolean> dbexpected = expectationsFactory.getEquals( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, equals(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where equals(geom, :filter) = true and srid(geom) = 4326", pckg
|
||||
"where equals(geom, :filter) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -285,7 +286,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Boolean> dbexpected = expectationsFactory.getCrosses( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, crosses(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where crosses(geom, :filter) = true and srid(geom) = 4326", pckg
|
||||
"where crosses(geom, :filter) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -309,7 +310,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Boolean> dbexpected = expectationsFactory.getContains( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, contains(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where contains(geom, :filter) = true and srid(geom) = 4326", pckg
|
||||
"where contains(geom, :filter) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -332,7 +333,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Boolean> dbexpected = expectationsFactory.getDisjoint( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, disjoint(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where disjoint(geom, :filter) = true and srid(geom) = 4326", pckg
|
||||
"where disjoint(geom, :filter) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -355,7 +356,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Boolean> dbexpected = expectationsFactory.getIntersects( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, intersects(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where intersects(geom, :filter) = true and srid(geom) = 4326", pckg
|
||||
"where intersects(geom, :filter) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -378,7 +379,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Boolean> dbexpected = expectationsFactory.getOverlaps( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, overlaps(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where overlaps(geom, :filter) = true and srid(geom) = 4326", pckg
|
||||
"where overlaps(geom, :filter) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -400,7 +401,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
}
|
||||
String hql = format(
|
||||
"SELECT id, touches(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where touches(geom, :filter) = true and srid(geom) = 4326", pckg
|
||||
"where touches(geom, :filter) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<Integer, Boolean> dbexpected = expectationsFactory.getTouches( expectationsFactory.getTestPolygon() );
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
|
@ -428,7 +429,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
);
|
||||
String hql = format(
|
||||
"SELECT id, relate(geom, :filter, :matrix) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where relate(geom, :filter, :matrix) = true and srid(geom) = 4326", pckg
|
||||
"where relate(geom, :filter, :matrix) = true and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
params.put( "matrix", matrix );
|
||||
|
@ -458,7 +459,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Double> dbexpected = expectationsFactory.getDistance( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, distance(geom, :filter) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where srid(geom) = 4326", pckg
|
||||
"where srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -481,7 +482,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Geometry> dbexpected = expectationsFactory.getBuffer( Double.valueOf( 1.0 ) );
|
||||
String hql = format(
|
||||
"SELECT id, buffer(geom, :distance) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where srid(geom) = 4326", pckg
|
||||
"where srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "distance", Double.valueOf( 1.0 ) );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -511,7 +512,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Geometry> dbexpected = expectationsFactory.getConvexHull( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, convexhull(geomunion(geom, :polygon)) from org.hibernate.spatial.integration" +
|
||||
".%s.GeomEntity where srid(geom) = 4326", pckg
|
||||
".%s.GeomEntity where srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -539,7 +540,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Geometry> dbexpected = expectationsFactory.getIntersection( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, intersection(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where srid(geom) = 4326", pckg
|
||||
"where srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -562,7 +563,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Geometry> dbexpected = expectationsFactory.getDifference( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, difference(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where srid(geom) = 4326", pckg
|
||||
"where srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -585,7 +586,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Geometry> dbexpected = expectationsFactory.getSymDifference( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, symdifference(geom, :polygon) from " +
|
||||
"org.hibernate.spatial.integration.%s.GeomEntity where srid(geom) = 4326", pckg
|
||||
"org.hibernate.spatial.integration.%s.GeomEntity where srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -608,7 +609,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Geometry> dbexpected = expectationsFactory.getGeomUnion( expectationsFactory.getTestPolygon() );
|
||||
String hql = format(
|
||||
"SELECT id, geomunion(geom, :polygon) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where srid(geom) = 4326", pckg
|
||||
"where srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "polygon", expectationsFactory.getTestPolygon() );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
@ -636,13 +637,13 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
String hql = format(
|
||||
"SELECT id, dwithin(geom, :filter, :distance) from " +
|
||||
"org.hibernate.spatial.integration.%s.GeomEntity where dwithin(geom, :filter, :distance) = true " +
|
||||
"and srid(geom) = 4326", pckg
|
||||
"and srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPoint() );
|
||||
if ( getDialect() instanceof OracleSpatial10gDialect ) {
|
||||
//because this uses the weird syntax and conventions of SDO_WITHIN_DISTANCE which returns a string (really)
|
||||
// we use a different boolean expression guaranteed to be true, and we set the third parameter to key/value string
|
||||
hql = "SELECT id, issimple(geom) from org.hibernate.spatial.integration.GeomEntity where dwithin(geom, :filter, :distance) = true and srid(geom) = 4326";
|
||||
hql = "SELECT id, issimple(geom) from org.hibernate.spatial.integration.GeomEntity where dwithin(geom, :filter, :distance) = true and srid(geom) = " + expectationsFactory.getTestSrid();
|
||||
params.put( "distance", "distance = 30" );
|
||||
}
|
||||
else {
|
||||
|
@ -650,13 +651,17 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
}
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
}
|
||||
|
||||
// The transform tests are skipped for HANA because there is no transform definition for SRID 0
|
||||
|
||||
@Test
|
||||
@SkipForDialect(value = HANASpatialDialect.class)
|
||||
public void test_transform_on_jts() throws SQLException {
|
||||
transform( JTS );
|
||||
}
|
||||
|
||||
@Test
|
||||
@SkipForDialect(value = HANASpatialDialect.class)
|
||||
public void test_transform_on_geolatte() throws SQLException {
|
||||
transform( GEOLATTE );
|
||||
}
|
||||
|
@ -669,7 +674,7 @@ public class TestSpatialFunctions extends SpatialFunctionalTestCase {
|
|||
Map<Integer, Geometry> dbexpected = expectationsFactory.getTransform( epsg );
|
||||
String hql = format(
|
||||
"SELECT id, transform(geom, :epsg) from org.hibernate.spatial.integration.%s.GeomEntity " +
|
||||
"where srid(geom) = 4326", pckg
|
||||
"where srid(geom) = %d", pckg, expectationsFactory.getTestSrid()
|
||||
);
|
||||
Map<String, Object> params = createQueryParams( "epsg", Integer.valueOf( epsg ) );
|
||||
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
|
||||
|
|
|
@ -11,6 +11,8 @@ 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.testing.TestDataElement;
|
||||
|
||||
import org.geolatte.geom.Geometry;
|
||||
|
@ -60,8 +62,14 @@ public class GeomEntity {
|
|||
this.geom = geom;
|
||||
}
|
||||
|
||||
public static GeomEntity createFrom(TestDataElement element) throws WktDecodeException {
|
||||
WktDecoder decoder = Wkt.newDecoder( Wkt.Dialect.POSTGIS_EWKT_1 );
|
||||
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 );
|
||||
|
|
|
@ -23,6 +23,7 @@ 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.testing.SpatialDialectMatcher;
|
||||
import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
|
||||
|
@ -115,12 +116,14 @@ public class TestStoreRetrieveUsingGeolatte extends SpatialFunctionalTestCase {
|
|||
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 );
|
||||
;
|
||||
GeomEntity entity = GeomEntity.createFrom( element, dialect );
|
||||
stored.put( entity.getId(), entity );
|
||||
session.save( entity );
|
||||
tx.commit();
|
||||
|
|
|
@ -16,7 +16,8 @@ import com.vividsolutions.jts.io.ParseException;
|
|||
import org.geolatte.geom.codec.Wkt;
|
||||
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.testing.TestDataElement;
|
||||
|
||||
/**
|
||||
|
@ -58,8 +59,14 @@ public class GeomEntity {
|
|||
this.geom = geom;
|
||||
}
|
||||
|
||||
public static GeomEntity createFrom(TestDataElement element) throws ParseException {
|
||||
WktDecoder decoder = Wkt.newDecoder( Wkt.Dialect.POSTGIS_EWKT_1 );
|
||||
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 );
|
||||
}
|
||||
Geometry geom = JTS.to( decoder.decode( element.wkt ) );
|
||||
GeomEntity result = new GeomEntity();
|
||||
result.setId( element.id );
|
||||
|
|
|
@ -20,6 +20,7 @@ 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.testing.SpatialDialectMatcher;
|
||||
import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
|
||||
|
@ -112,12 +113,13 @@ public class TestStoreRetrieveUsingJTS extends SpatialFunctionalTestCase {
|
|||
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 );
|
||||
GeomEntity entity = GeomEntity.createFrom( element, dialect );
|
||||
stored.put( entity.getId(), entity );
|
||||
session.save( entity );
|
||||
tx.commit();
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package org.hibernate.spatial.testing.dialects.hana;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.spatial.testing.DataSourceUtils;
|
||||
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
||||
|
||||
public class HANADataSourceUtils extends DataSourceUtils {
|
||||
public HANADataSourceUtils(String jdbcDriver, String jdbcUrl, String jdbcUser, String jdbcPass,
|
||||
SQLExpressionTemplate sqlExpressionTemplate) {
|
||||
super(jdbcDriver, jdbcUrl, jdbcUser, jdbcPass, sqlExpressionTemplate);
|
||||
}
|
||||
|
||||
public HANADataSourceUtils(String propertyFile, SQLExpressionTemplate template) {
|
||||
super(propertyFile, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCreateSchema() {
|
||||
try {
|
||||
executeStatement("ALTER TABLE GEOMTEST DROP (GEOM)");
|
||||
executeStatement("ALTER TABLE GEOMTEST ADD (GEOM ST_GEOMETRY(4326))");
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,42 +33,42 @@ public class HANAExpectationsFactory extends AbstractExpectationsFactory {
|
|||
@Override
|
||||
protected NativeSQLStatement createNativeBufferStatement(Double distance) {
|
||||
return createNativeSQLStatement(
|
||||
"select t.id, t.geom.ST_Buffer(?) from GeomTest t where t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Buffer(?) from GeomTest t where t.geom.ST_SRID() = " + getTestSrid(),
|
||||
new Object[] { distance });
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeConvexHullStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Union(ST_GeomFromText(?, 0)).ST_ConvexHull().ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Union(ST_GeomFromText(?, " + getTestSrid() + ")).ST_ConvexHull().ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeIntersectionStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Intersection(ST_GeomFromText(?, 0)).ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Intersection(ST_GeomFromText(?, " + getTestSrid() + ")).ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDifferenceStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Difference(ST_GeomFromText(?, 0)).ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Difference(ST_GeomFromText(?, " + getTestSrid() + ")).ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeSymDifferenceStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_SymDifference(ST_GeomFromText(?, 0)).ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_SymDifference(ST_GeomFromText(?, " + getTestSrid() + ")).ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeGeomUnionStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Union(ST_GeomFromText(?, 0)).ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Union(ST_GeomFromText(?, " + getTestSrid() + ")).ST_AsEWKB() from GeomTest t where t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
|
@ -128,42 +128,42 @@ public class HANAExpectationsFactory extends AbstractExpectationsFactory {
|
|||
@Override
|
||||
protected NativeSQLStatement createNativeWithinStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Within(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_Within(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Within(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_Within(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeEqualsStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Equals(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_Equals(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Equals(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_Equals(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeCrossesStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Crosses(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_Crosses(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Crosses(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_Crosses(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeContainsStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Contains(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_Contains(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Contains(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_Contains(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDisjointStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Disjoint(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_Disjoint(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Disjoint(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_Disjoint(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeTransformStatement(int epsg) {
|
||||
return createNativeSQLStatement(
|
||||
"select t.id, t.geom.ST_Transform(" + epsg + ") from GeomTest t where t.geom.ST_SRID() = 0");
|
||||
"select t.id, t.geom.ST_Transform(" + epsg + ") from GeomTest t where t.geom.ST_SRID() = " + getTestSrid());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -174,63 +174,58 @@ public class HANAExpectationsFactory extends AbstractExpectationsFactory {
|
|||
@Override
|
||||
protected NativeSQLStatement createNativeIntersectsStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Intersects(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_Intersects(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Intersects(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_Intersects(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeFilterStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_IntersectsFilter(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_IntersectsFilter(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_IntersectsFilter(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_IntersectsFilter(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeTouchesStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Touches(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_Touches(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Touches(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_Touches(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeOverlapsStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Overlaps(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_Overlaps(ST_GeomFromText(?, 0)) = 1 and t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Overlaps(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_Overlaps(ST_GeomFromText(?, " + getTestSrid() + ")) = 1 and t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeRelateStatement(Geometry geom, String matrix) {
|
||||
String sql = "select t.id, t.geom.ST_Relate(ST_GeomFromText(?, 0), '" + matrix
|
||||
+ "' ) from GeomTest t where t.geom.ST_Relate(ST_GeomFromText(?, 0), '" + matrix
|
||||
+ "') = 1 and t.geom.ST_SRID() = 0";
|
||||
String sql = "select t.id, t.geom.ST_Relate(ST_GeomFromText(?, " + getTestSrid() + "), '" + matrix
|
||||
+ "' ) from GeomTest t where t.geom.ST_Relate(ST_GeomFromText(?, " + getTestSrid() + "), '" + matrix
|
||||
+ "') = 1 and t.geom.ST_SRID() = " + getTestSrid();
|
||||
return createNativeSQLStatementAllWKTParams(sql, geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDwithinStatement(Point geom, double distance) {
|
||||
return createNativeSQLStatementAllWKTParams("select t.id, t.geom.ST_WithinDistance(ST_GeomFromText(?, 0), "
|
||||
+ distance + ") from GeomTest t where t.geom.ST_WithinDistance(ST_GeomFromText(?, 0), " + distance
|
||||
+ ") = 1 and t.geom.ST_SRID() = 0", geom.toText());
|
||||
return createNativeSQLStatementAllWKTParams("select t.id, t.geom.ST_WithinDistance(ST_GeomFromText(?, " + getTestSrid() + "), "
|
||||
+ distance + ") from GeomTest t where t.geom.ST_WithinDistance(ST_GeomFromText(?, " + getTestSrid() + "), " + distance
|
||||
+ ") = 1 and t.geom.ST_SRID() = " + getTestSrid(), geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeSQLStatement createNativeDistanceStatement(Geometry geom) {
|
||||
return createNativeSQLStatementAllWKTParams(
|
||||
"select t.id, t.geom.ST_Distance(ST_GeomFromText(?, 0)) from GeomTest t where t.geom.ST_SRID() = 0",
|
||||
"select t.id, t.geom.ST_Distance(ST_GeomFromText(?, " + getTestSrid() + ")) from GeomTest t where t.geom.ST_SRID() = " + getTestSrid(),
|
||||
geom.toText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTestSrid() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Polygon getTestPolygon() {
|
||||
WKTReader reader = new WKTReader();
|
||||
try {
|
||||
Polygon polygon = (Polygon) reader.read( "POLYGON((0 0, 50 0, 90 90, 0 100, 0 0))" );
|
||||
Polygon polygon = (Polygon) reader.read( "POLYGON((0 0, 50 0, 90 90, 100 0, 0 0))" );
|
||||
polygon.setSRID( getTestSrid() );
|
||||
return polygon;
|
||||
}
|
||||
|
@ -238,5 +233,10 @@ public class HANAExpectationsFactory extends AbstractExpectationsFactory {
|
|||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getTestSrid() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.hibernate.spatial.testing.WktUtility;
|
|||
*/
|
||||
public class HANAExpressionTemplate implements SQLExpressionTemplate {
|
||||
|
||||
static final String SQL_TEMPLATE = "insert into geomtest (id, type, geom) values (%d, '%s', ST_GeomFromText('%s', %d).ST_SRID(4326))";
|
||||
static final String SQL_TEMPLATE = "insert into geomtest (id, type, geom) values (%d, '%s', ST_GeomFromText('%s', %d))";
|
||||
|
||||
@Override
|
||||
public String toInsertSql(TestDataElement testDataElement) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
package org.hibernate.spatial.testing.dialects.hana;
|
||||
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.spatial.testing.DataSourceUtils;
|
||||
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
||||
import org.hibernate.spatial.testing.TestData;
|
||||
|
@ -18,22 +17,17 @@ public class HANATestSupport extends TestSupport {
|
|||
|
||||
@Override
|
||||
public TestData createTestData(BaseCoreFunctionalTestCase testcase) {
|
||||
return TestData.fromFile("hana/test-hana-data-set.xml");
|
||||
return TestData.fromFile( "hana/test-hana-data-set.xml" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public HANAExpectationsFactory createExpectationsFactory(DataSourceUtils dataSourceUtils) {
|
||||
return new HANAExpectationsFactory(dataSourceUtils);
|
||||
return new HANAExpectationsFactory( dataSourceUtils );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLExpressionTemplate getSQLExpressionTemplate() {
|
||||
return new HANAExpressionTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceUtils createDataSourceUtil(ServiceRegistry serviceRegistry) {
|
||||
super.createDataSourceUtil(serviceRegistry);
|
||||
return new HANADataSourceUtils( driver(), url(), user(), passwd(), getSQLExpressionTemplate() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,76 +18,75 @@
|
|||
<Element>
|
||||
<id>2</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT(52.25 2.53)</wkt>
|
||||
<wkt>POINT(52.25 2.75)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>3</id>
|
||||
<type>POINT</type>
|
||||
<!-- <wkt>SRID=4326;POINT(150000 200000)</wkt> -->
|
||||
<wkt>SRID=4326;POINT(15 20)</wkt>
|
||||
<wkt>POINT(150000 200000)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>4</id>
|
||||
<type>POINT</type>
|
||||
<wkt>SRID=4326;POINT ZM(10.0 2.0 1.0 3.0)</wkt>
|
||||
<wkt>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>
|
||||
<wkt>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>
|
||||
<wkt>LINESTRING(10.0 5.0, 20.0 15.0, 30.25 22.375, 10 30.0)</wkt>
|
||||
</Element>
|
||||
|
||||
|
||||
<Element>
|
||||
<id>7</id>
|
||||
<type>LINESTRING</type>
|
||||
<wkt>SRID=4326;LINESTRING M(10.0 5.0 0.0, 20.0 15.0 3.0)</wkt>
|
||||
<wkt>LINESTRING M(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>
|
||||
<wkt>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>
|
||||
<wkt>LINESTRING M(10.0 5.0 1, 20.0 15.0 2, 30.25 22.375 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>
|
||||
<wkt>LINESTRING ZM(10.0 5.0 1 1, 20.0 15.0 2 3, 30.25 22.375 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>
|
||||
<wkt>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>MULTILINESTRING((10.0 5.0, 20.0 15.0, 30.25 22.375, 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 M((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,
|
||||
<wkt>MULTILINESTRING M((10.0 5.0 1.0, 20.0 15.0 2.0, 30.25 22.375 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>
|
||||
|
@ -95,7 +94,7 @@
|
|||
<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
|
||||
<wkt>MULTILINESTRING ZM((10.0 5.0 1.0 0.0, 20.0 15.0 2.0 0.0, 30.25 22.375 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>
|
||||
|
@ -103,137 +102,128 @@
|
|||
<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>
|
||||
<wkt>MULTILINESTRING ZM((10.0 5.0 1.0 0.0, 20.0 15.0 2.0 0.0, 30.25 22.375 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>
|
||||
<wkt>POLYGON( (0 0, 10 0, 10 10, 0 10, 0 0) )</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>17</id>
|
||||
<type>POLYGON</type>
|
||||
<wkt>SRID=4326;POLYGON M( (0 0 0, 0 10 1, 10 10 1, 10 0 1, 0 0 0) )</wkt>
|
||||
<wkt>POLYGON M( (0 0 0, 10 0 1, 10 10 1, 0 10 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>
|
||||
<wkt>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, 110 120, 120 120, 120 110, 110 110) )</wkt> -->
|
||||
<wkt>SRID=4326;POLYGON( (11 11, 11 12, 12 12, 12 11, 11 11) )</wkt>
|
||||
<wkt>POLYGON( (110 110, 120 110, 120 120, 110 120, 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> -->
|
||||
<wkt>SRID=4326;MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 10, 120 14, 130 13.4, 105 10)) )</wkt>
|
||||
<wkt>MULTIPOLYGON( ((10 20, 44 50, 30 40, 10 20)), ((105 100, 130 134, 120 140, 105 100)) )</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>21</id>
|
||||
<type>MULTIPOLYGON</type>
|
||||
<!-- <wkt>SRID=4326;MULTIPOLYGON M( ((10 20 1, 30 40 2, 44 50 2, 10 20 1)), ((105 100 0, 120 140 10, 130 134 20, 105 100 0)) ) -->
|
||||
<wkt>SRID=4326;MULTIPOLYGON M( ((10 20 1, 30 40 2, 44 50 2, 10 20 1)), ((105 10 0, 120 14 10, 130 13.4 20, 105 10 0)) )
|
||||
<wkt>MULTIPOLYGON M( ((10 20 1, 44 50 2, 30 40 2, 10 20 1)), ((105 100 0, 130 134 20, 120 140 10, 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> -->
|
||||
<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 10, 120 14, 130
|
||||
13.4, 105 10)) )
|
||||
<wkt>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>25</id>
|
||||
<type>MULTIPOINT</type>
|
||||
<wkt>SRID=4326;MULTIPOINT(21 2, 25 5, 30 3)</wkt>
|
||||
<wkt>MULTIPOINT(21 2, 25 5, 30 3)</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>26</id>
|
||||
<type>MULTIPOINT</type>
|
||||
<wkt>SRID=4326;MULTIPOINT(21 2)</wkt>
|
||||
<wkt>MULTIPOINT(21 2)</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>27</id>
|
||||
<type>MULTIPOINT</type>
|
||||
<wkt>SRID=4326;MULTIPOINT M(21 2 1, 25 5 2, 30 3 5)</wkt>
|
||||
<wkt>MULTIPOINT M(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>
|
||||
<wkt>MULTIPOINT ZM(21 2 1 0, 25 5 2 4, 30 3 5 2)</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
<id>30</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3))</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>31</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0)))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0)))</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>32</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0),(1 1, 2 1, 2 2, 1 2,
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0),(1 1, 1 2, 2 2, 2 1,
|
||||
1 1)))
|
||||
</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>33</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<!-- <wkt>SRID=4326;GEOMETRYCOLLECTION( MULTIPOINT(21 2, 25 5, 30 3), MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100, -->
|
||||
<!-- 120 140, 130 134, 105 100)) ), MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0))) -->
|
||||
<!-- </wkt> -->
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION( MULTIPOINT(21 2, 25 5, 30 3), MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 10,
|
||||
120 14, 130 13.4, 105 10)) ), MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0)))
|
||||
<wkt>GEOMETRYCOLLECTION( MULTIPOINT(21 2, 25 5, 30 3), MULTIPOLYGON( ((10 20, 44 50, 30 40, 10 20)), ((105 100,
|
||||
130 134, 120 140, 105 100)) ), MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0)))
|
||||
</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>34</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), POINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), POINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>35</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), LINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>36</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), GEOMETRYCOLLECTION EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), GEOMETRYCOLLECTION EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>37</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), POLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), POLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>38</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), MULTILINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTILINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>39</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), MULTIPOINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTIPOINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
</Element>
|
||||
<Element>
|
||||
<id>40</id>
|
||||
<type>GEOMETRYCOLLECTION</type>
|
||||
<wkt>SRID=4326;GEOMETRYCOLLECTION(POINT(4 0), MULTIPOLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTIPOLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
|
||||
</Element>
|
||||
|
||||
<Element>
|
||||
|
|
Loading…
Reference in New Issue