HHH-6510 Added Oracle SDOGeometry support.

This commit is contained in:
Karel Maesen 2011-08-22 22:05:56 +02:00 committed by Steve Ebersole
parent 79d02e2f9d
commit f7f39cb8d2
45 changed files with 5407 additions and 9 deletions

View File

@ -20,6 +20,7 @@ dependencies {
testCompile( libraries.junit ) testCompile( libraries.junit )
testCompile( project(':hibernate-testing') ) testCompile( project(':hibernate-testing') )
testCompile( [group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4']) testCompile( [group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4'])
testCompile([group: 'com.oracle.jdbc', name:'ojdbc6', version:'11.1.0.7.0'])
} }
sourceSets { sourceSets {

View File

@ -0,0 +1,52 @@
/**
* $Id: ConnectionFinder.java 268 2010-10-28 19:16:54Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.sql.Connection;
import org.hibernate.spatial.helper.FinderStrategy;
/**
* The <code>ConnectionFinder</code> returns an OracleConnection when given a
* <code>Connection</code> object.
* <p>
* The SDOGeometryType requires access to an <code>OracleConnection</code>
* object when converting a geometry to <code>SDOGeometry</code>, prior to
* setting the geometry attribute in prepared statements. In some environments
* the prepared statements do not return an <code>OracleConnection</code> but
* a wrapper. Implementations of this interface attempt to retrieve the
* <code>OracleConnection</code> from the wrapper in such cases.
* </p>
*
* @author Karel Maesen
*/
public interface ConnectionFinder extends
FinderStrategy<Connection, Connection> {
}

View File

@ -0,0 +1,119 @@
/**
* $Id: DefaultConnectionFinder.java 286 2011-02-04 21:16:23Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import org.hibernate.HibernateException;
import org.hibernate.spatial.helper.FinderException;
/**
* Default <code>ConnectionFinder</code> implementation.
* <p>
* This implementation attempts to retrieve the <code>OracleConnection</code>
* by recursive reflection: it searches for methods that return
* <code>Connection</code> objects, executes these methods and checks the
* result. If the result is of type <code>OracleConnection</code> the object
* is returned, otherwise it recurses on it.
* <p/>
* </p>
*
* @author Karel Maesen
*/
public class DefaultConnectionFinder implements ConnectionFinder {
private final static Class<?> oracleConnectionClass;
static {
try {
oracleConnectionClass = Class.forName( "oracle.jdbc.driver.OracleConnection" );
}
catch ( ClassNotFoundException e ) {
throw new HibernateException( "Can't find Oracle JDBC Driver on classpath." );
}
}
public Connection find(Connection con) throws FinderException {
if ( con == null ) {
return null;
}
if ( oracleConnectionClass.isInstance( con ) ) {
return con;
}
// try to find the Oracleconnection recursively
for ( Method method : con.getClass().getMethods() ) {
if ( method.getReturnType().isAssignableFrom(
java.sql.Connection.class
)
&& method.getParameterTypes().length == 0 ) {
try {
method.setAccessible( true );
Connection oc = find( (Connection) ( method.invoke( con, new Object[] { } ) ) );
if ( oc == null ) {
throw new FinderException(
String.format(
"Tried retrieving OracleConnection from %s using method %s, but received null.",
con.getClass().getCanonicalName(),
method.getName()
)
);
}
return oc;
}
catch ( IllegalAccessException e ) {
throw new FinderException(
String.format(
"Illegal access on executing method %s when finding OracleConnection",
method.getName()
)
);
}
catch ( InvocationTargetException e ) {
throw new FinderException(
String.format(
"Invocation exception on executing method %s when finding OracleConnection",
method.getName()
)
);
}
}
}
throw new FinderException(
"Couldn't get at the OracleSpatial Connection object from the PreparedStatement."
);
}
}

View File

@ -0,0 +1,118 @@
package org.hibernate.spatial.dialect.oracle;
import java.math.BigDecimal;
import java.sql.Array;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Jul 1, 2010
*/
class ElemInfo {
static final String TYPE_NAME = "MDSYS.SDO_ELEM_INFO_ARRAY";
private BigDecimal[] triplets;
public ElemInfo(int size) {
this.triplets = new BigDecimal[3 * size];
}
public ElemInfo(BigDecimal[] elem_info) {
this.triplets = elem_info;
}
public ElemInfo(Array array) {
if (array == null) {
this.triplets = new BigDecimal[]{};
return;
}
try {
triplets = (BigDecimal[]) array.getArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public BigDecimal[] getElements() {
return this.triplets;
}
public int getSize() {
return this.triplets.length / 3;
}
public int getOrdinatesOffset(int i) {
return this.triplets[i * 3].intValue();
}
public void setOrdinatesOffset(int i, int offset) {
this.triplets[i * 3] = new BigDecimal(offset);
}
public ElementType getElementType(int i) {
int etype = this.triplets[i * 3 + 1].intValue();
int interp = this.triplets[i * 3 + 2].intValue();
ElementType et = ElementType.parseType(etype, interp);
return et;
}
public boolean isCompound(int i) {
return getElementType(i).isCompound();
}
public int getNumCompounds(int i) {
if (getElementType(i).isCompound()) {
return this.triplets[i * 3 + 2].intValue();
} else {
return 1;
}
}
public void setElement(int i, int ordinatesOffset, ElementType et,
int numCompounds) {
if (i > getSize()) {
throw new RuntimeException(
"Attempted to set more elements in ElemInfo Array than capacity.");
}
this.triplets[i * 3] = new BigDecimal(ordinatesOffset);
this.triplets[i * 3 + 1] = new BigDecimal(et.getEType());
this.triplets[i * 3 + 2] = et.isCompound() ? new BigDecimal(numCompounds) : new BigDecimal(et
.getInterpretation());
}
public String toString() {
return SDOGeometry.arrayToString(this.triplets);
}
public void addElement(BigDecimal[] element) {
BigDecimal[] newTriplets = new BigDecimal[this.triplets.length + element.length];
System.arraycopy(this.triplets, 0, newTriplets, 0,
this.triplets.length);
System.arraycopy(element, 0, newTriplets, this.triplets.length,
element.length);
this.triplets = newTriplets;
}
public void addElement(ElemInfo element) {
this.addElement(element.getElements());
}
public BigDecimal[] getElement(int i) {
BigDecimal[] ea = null;
if (this.getElementType(i).isCompound()) {
int numCompounds = this.getNumCompounds(i);
ea = new BigDecimal[numCompounds + 1];
} else {
ea = new BigDecimal[3];
}
System.arraycopy(this.triplets, 3 * i, ea, 0, ea.length);
return ea;
}
// public ARRAY toOracleArray(Connection conn) throws SQLException {
// ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor(
// TYPE_NAME, conn);
// return new ARRAY(arrayDescriptor, conn, this.triplets);
// }
}

View File

@ -0,0 +1,93 @@
package org.hibernate.spatial.dialect.oracle;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Jul 1, 2010
*/
enum ElementType {
UNSUPPORTED(0, true), POINT(1, 1), ORIENTATION(1, 0), POINT_CLUSTER(1,
true), LINE_STRAITH_SEGMENTS(2, 1), LINE_ARC_SEGMENTS(2, 2), INTERIOR_RING_STRAIGHT_SEGMENTS(
2003, 1), EXTERIOR_RING_STRAIGHT_SEGMENTS(1003, 1), INTERIOR_RING_ARC_SEGMENTS(
2003, 2), EXTERIOR_RING_ARC_SEGMENTS(1003, 2), INTERIOR_RING_RECT(
2003, 3), EXTERIOR_RING_RECT(1003, 3), INTERIOR_RING_CIRCLE(
2003, 4), EXTERIOR_RING_CIRCLE(1003, 4), COMPOUND_LINE(4, true), COMPOUND_EXTERIOR_RING(
1005, true), COMPOUND_INTERIOR_RING(2005, true);
private int etype;
private int interpretation = 2;
private boolean compound = false;
private ElementType(int etype, int interp) {
this.etype = etype;
this.interpretation = interp;
}
private ElementType(int etype, boolean compound) {
this.etype = etype;
this.compound = compound;
}
public int getEType() {
return this.etype;
}
public int getInterpretation() {
return this.interpretation;
}
/**
* @return true, if the SDO_INTERPRETATION value is the number of points
* or compounds in the element.
*/
public boolean isCompound() {
return this.compound;
}
public boolean isLine() {
return (etype == 2 || etype == 4);
}
public boolean isInteriorRing() {
return (etype == 2003 || etype == 2005);
}
public boolean isExteriorRing() {
return (etype == 1003 || etype == 1005);
}
public boolean isStraightSegment() {
return (interpretation == 1);
}
public boolean isArcSegment() {
return (interpretation == 2);
}
public boolean isCircle() {
return (interpretation == 4);
}
public boolean isRect() {
return (interpretation == 3);
}
public static ElementType parseType(int etype, int interpretation) {
for (ElementType t : values()) {
if (t.etype == etype) {
if (t.isCompound()
|| t.getInterpretation() == interpretation) {
return t;
}
}
}
throw new RuntimeException(
"Can't determine ElementType from etype:" + etype
+ " and interp.:" + interpretation);
}
}

View File

@ -0,0 +1,56 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.util.List;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
/**
* Implements OGC function dimension for HQL.
*/
class GetDimensionFunction extends SDOObjectMethod {
GetDimensionFunction() {
super("Get_Dims", StandardBasicTypes.INTEGER);
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
if (args.isEmpty()) {
throw new IllegalArgumentException(
"First Argument in arglist must be object to "
+ "which method is applied");
}
buf.append(args.get(0)).append(".").append(
getName()).append("()");
return buf.toString();
}
}

View File

@ -0,0 +1,62 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.util.List;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
/**
* HQL Implementation for the geometry ype function.
*/
class GetGeometryTypeFunction extends SDOObjectMethod {
GetGeometryTypeFunction() {
super("Get_GType", StandardBasicTypes.STRING);
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
if (args.isEmpty()) {
throw new IllegalArgumentException(
"First Argument in arglist must be object to which"
+ " method is applied");
}
buf.append("CASE ").append(args.get(0)).append(".").append(
getName()).append("()");
buf.append(" WHEN 1 THEN 'POINT'").append(
" WHEN 2 THEN 'LINESTRING'").append(
" WHEN 3 THEN 'POLYGON'").append(
" WHEN 5 THEN 'MULTIPOINT'").append(
" WHEN 6 THEN 'MULTILINE'").append(
" WHEN 7 THEN 'MULTIPOLYGON'").append(" END");
return buf.toString();
}
}

View File

@ -0,0 +1,213 @@
package org.hibernate.spatial.dialect.oracle;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Array;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Struct;
import org.hibernate.HibernateException;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.spatial.helper.FinderException;
/**
* Factory for Oracle JDBC extension types (ARRAY, STRUCT, ...).
*
* This factory creates the Oracle extension types using reflection in order to
* avoid creating compile-time dependencies on the proprietary Oracle driver.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: Jul 3, 2010
*/
public class OracleJDBCTypeFactory implements SQLTypeFactory {
private static Class<?> datumClass;
private static Class<?> numberClass;
private static Class<?> arrayClass;
private static Class<?> structClass;
private static Class<?> arrayDescriptorClass;
private static Class<?> structDescriptorClass;
private static Method structDescriptorCreator;
private static Method arrayDescriptorCreator;
private static Constructor<?> numberConstructor;
private static Constructor<?> arrayConstructor;
private static Constructor<?> structConstructor;
static {
Object[] obj = findDescriptorCreator( "oracle.sql.StructDescriptor" );
structDescriptorClass = (Class<?>) obj[0];
structDescriptorCreator = (Method) obj[1];
obj = findDescriptorCreator( "oracle.sql.ArrayDescriptor" );
arrayDescriptorClass = (Class<?>) obj[0];
arrayDescriptorCreator = (Method) obj[1];
datumClass = findClass( "oracle.sql.Datum" );
numberClass = findClass( "oracle.sql.NUMBER" );
arrayClass = findClass( "oracle.sql.ARRAY" );
structClass = findClass( "oracle.sql.STRUCT" );
numberConstructor = findConstructor( numberClass, java.lang.Integer.TYPE );
arrayConstructor = findConstructor( arrayClass, arrayDescriptorClass, Connection.class, Object.class );
structConstructor = findConstructor( structClass, structDescriptorClass, Connection.class, Object[].class );
}
private static ConnectionFinder connectionFinder = new DefaultConnectionFinder();
private static Constructor<?> findConstructor(Class clazz, Class<?>... arguments) {
try {
return clazz.getConstructor( arguments );
}
catch ( NoSuchMethodException e ) {
throw new HibernateException( "Error finding constructor for oracle.sql type.", e );
}
}
private static Class<?> findClass(String name) {
try {
return ReflectHelper.classForName( name );
}
catch ( ClassNotFoundException e ) {
throw new HibernateException( "Class 'oracle.sql.Datum' not found on class path" );
}
}
private static Object[] findDescriptorCreator(String className) {
try {
Class clazz = ReflectHelper.classForName( className );
Method m = clazz.getMethod(
"createDescriptor",
String.class,
Connection.class
);
return new Object[] { clazz, m };
}
catch ( ClassNotFoundException e ) {
throw new HibernateException( "Class 'StructDescriptor' not found on classpath" );
}
catch ( NoSuchMethodException e ) {
throw new HibernateException( "Class 'StructDescriptor' has no method 'createDescriptor(String,Connection)'" );
}
}
static ConnectionFinder getConnectionFinder() {
return connectionFinder;
}
static void setConnectionFinder(ConnectionFinder finder) {
connectionFinder = finder;
}
public Struct createStruct(SDOGeometry geom, Connection conn) throws SQLException {
Connection oracleConnection = null;
try {
oracleConnection = connectionFinder.find( conn );
}
catch ( FinderException e ) {
throw new HibernateException( "Problem finding Oracle Connection", e );
}
Object structDescriptor = createStructDescriptor( SDOGeometry.getTypeName(), oracleConnection );
Object[] attributes = createDatumArray( 5 );
attributes[0] = createNumber( geom.getGType().intValue() );
if ( geom.getSRID() > 0 ) {
attributes[1] = createNumber( geom.getSRID() );
}
else {
attributes[1] = null;
}
attributes[3] = createElemInfoArray( geom.getInfo(), oracleConnection );
attributes[4] = createOrdinatesArray( geom.getOrdinates(), oracleConnection );
return createStruct( structDescriptor, oracleConnection, attributes );
}
public Array createElemInfoArray(ElemInfo elemInfo, Connection conn) {
Object arrayDescriptor = createArrayDescriptor( ElemInfo.TYPE_NAME, conn );
return createArray( arrayDescriptor, conn, elemInfo.getElements() );
}
public Array createOrdinatesArray(Ordinates ordinates, Connection conn) throws SQLException {
Object arrayDescriptor = createArrayDescriptor( Ordinates.TYPE_NAME, conn );
return createArray( arrayDescriptor, conn, ordinates.getOrdinateArray() );
}
private Array createArray(Object descriptor, Connection conn, Object[] data) {
try {
return (Array) arrayConstructor.newInstance( descriptor, conn, data );
}
catch ( InstantiationException e ) {
throw new HibernateException( "Problem creating ARRAY.", e );
}
catch ( IllegalAccessException e ) {
throw new HibernateException( "Problem creating ARRAY.", e );
}
catch ( InvocationTargetException e ) {
throw new HibernateException( "Problem creating ARRAY.", e );
}
}
private Struct createStruct(Object descriptor, Connection conn, Object[] attributes) {
try {
return (Struct) structConstructor.newInstance( descriptor, conn, attributes );
}
catch ( InstantiationException e ) {
throw new HibernateException( "Problem creating STRUCT.", e );
}
catch ( IllegalAccessException e ) {
throw new HibernateException( "Problem creating STRUCT.", e );
}
catch ( InvocationTargetException e ) {
throw new HibernateException( "Problem creating STRUCT.", e );
}
}
private Object createStructDescriptor(String sqlType, Connection conn) {
try {
return structDescriptorCreator.invoke( null, sqlType, conn );
}
catch ( IllegalAccessException e ) {
throw new HibernateException( "Error creating oracle STRUCT", e );
}
catch ( InvocationTargetException e ) {
throw new HibernateException( "Error creating oracle STRUCT", e );
}
}
private Object createArrayDescriptor(String name, Connection conn) {
try {
return arrayDescriptorCreator.invoke( null, name, conn );
}
catch ( IllegalAccessException e ) {
throw new HibernateException( "Error creating oracle ARRAY", e );
}
catch ( InvocationTargetException e ) {
throw new HibernateException( "Error creating oracle ARRAY", e );
}
}
private Object[] createDatumArray(int size) {
return (Object[]) java.lang.reflect.Array.newInstance( datumClass, size );
}
private Object createNumber(int obj) {
try {
return numberConstructor.newInstance( obj );
}
catch ( InvocationTargetException e ) {
throw new HibernateException( "Error creating oracle NUMBER", e );
}
catch ( InstantiationException e ) {
throw new HibernateException( "Error creating oracle NUMBER", e );
}
catch ( IllegalAccessException e ) {
throw new HibernateException( "Error creating oracle NUMBER", e );
}
}
}

View File

@ -0,0 +1,591 @@
/*
* $Id: OracleSpatial10gDialect.java 309 2011-05-18 14:04:23Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.QueryException;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.spatial.GeometryType;
import org.hibernate.spatial.SpatialAnalysis;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialGeometrySqlTypeDescriptor;
import org.hibernate.spatial.SpatialRelation;
import org.hibernate.spatial.dialect.oracle.criterion.OracleSpatialAggregate;
import org.hibernate.spatial.helper.PropertyFileReader;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* Spatial Dialect for Oracle10g databases.
*
* @author Karel Maesen
*/
public class OracleSpatial10gDialect extends Oracle10gDialect implements
SpatialDialect, Serializable {
/**
* Implementation of the OGC astext function for HQL.
*/
private class AsTextFunction extends StandardSQLFunction {
private AsTextFunction() {
super("astext", StandardBasicTypes.STRING);
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
if (args.isEmpty()) {
throw new IllegalArgumentException(
"First Argument in arglist must be object "
+ "to which method is applied");
}
buf.append("TO_CHAR(SDO_UTIL.TO_WKTGEOMETRY(").append(args.get(0))
.append("))");
return buf.toString();
}
}
/**
* HQL Spatial relation function.
*/
private class SpatialRelateFunction extends StandardSQLFunction {
private final int relation;
private SpatialRelateFunction(final String name, final int relation) {
super(name, isOGCStrict() ? StandardBasicTypes.BOOLEAN
: new SDOBooleanType());
this.relation = relation;
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
if (args.size() < 2) {
throw new QueryException(
"Spatial relate functions require at least two arguments");
}
String srf;
return isOGCStrict() ?
getOGCSpatialRelateSQL((String) args.get(0),
(String) args.get(1), this.relation) :
getNativeSpatialRelateSQL((String) args.get(0),
(String) args.get(1), this.relation);
}
}
private class SpatialAnalysisFunction extends StandardSQLFunction {
private final int analysis;
private SpatialAnalysisFunction(String name, Type returnType,
int analysis) {
super(name, returnType);
this.analysis = analysis;
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return isOGCStrict() ? getSpatialAnalysisSQL(args, this.analysis,
false) : getNativeSpatialAnalysisSQL(args, analysis);
}
}
private class SpatialAggregationFunction extends StandardSQLFunction {
private final int aggregation;
private SpatialAggregationFunction(String name, Type returnType,
boolean isProjection, int aggregation) {
super(name, returnType);
this.aggregation = aggregation;
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return getNativeSpatialAggregateSQL((String) args.get(0),
this.aggregation);
}
}
public final static String SHORT_NAME = "oraclespatial";
private final static String CONNECTION_FINDER_PROPERTY = "CONNECTION-FINDER";
private final static Logger log = LoggerFactory
.getLogger(OracleSpatial10gDialect.class);
private String OGC_STRICT = "OGC_STRICT";
private Map<String, Boolean> features = new HashMap<String, Boolean>();
public OracleSpatial10gDialect() {
super();
// initialise features to default
features.put(OGC_STRICT, new Boolean(true));
// read configuration information from
// classpath
configure();
// register geometry type
registerColumnType(java.sql.Types.STRUCT, "MDSYS.SDO_GEOMETRY");
// registering OGC functions
// (spec_simplefeatures_sql_99-04.pdf)
// section 2.1.1.1
registerFunction("dimension", new GetDimensionFunction());
registerFunction("geometrytype", new GetGeometryTypeFunction());
registerFunction("srid", new SDOObjectProperty("SDO_SRID",
StandardBasicTypes.INTEGER));
registerFunction("envelope",
new StandardSQLFunction("SDO_GEOM.SDO_MBR", GeometryType.INSTANCE));
registerFunction("astext", new AsTextFunction());
registerFunction("asbinary", new StandardSQLFunction(
"SDO_UTIL.TO_WKBGEOMETRY", StandardBasicTypes.BINARY));
registerFunction("isempty", new WrappedOGCFunction("OGC_ISEMPTY",
StandardBasicTypes.BOOLEAN, new boolean[]{true}));
registerFunction("issimple", new WrappedOGCFunction("OGC_ISSIMPLE",
StandardBasicTypes.BOOLEAN, new boolean[]{true}));
registerFunction("boundary", new WrappedOGCFunction("OGC_BOUNDARY",
GeometryType.INSTANCE,
new boolean[]{true}));
// registerFunction("area", new AreaFunction());
// Register functions for spatial relation constructs
// section 2.1.1.2
registerFunction("overlaps", new SpatialRelateFunction("overlaps",
SpatialRelation.OVERLAPS));
registerFunction("intersects", new SpatialRelateFunction("intersects",
SpatialRelation.INTERSECTS));
registerFunction("contains", new SpatialRelateFunction("contains",
SpatialRelation.CONTAINS));
registerFunction("crosses", new SpatialRelateFunction("crosses",
SpatialRelation.CROSSES));
registerFunction("disjoint", new SpatialRelateFunction("disjoint",
SpatialRelation.DISJOINT));
registerFunction("equals", new SpatialRelateFunction("equals",
SpatialRelation.EQUALS));
registerFunction("touches", new SpatialRelateFunction("touches",
SpatialRelation.TOUCHES));
registerFunction("within", new SpatialRelateFunction("within",
SpatialRelation.WITHIN));
registerFunction("relate", new WrappedOGCFunction("OGC_RELATE",
StandardBasicTypes.BOOLEAN, new boolean[]{true, true, false}));
// Register spatial analysis functions.
// Section 2.1.1.3
registerFunction("distance", new SpatialAnalysisFunction("distance",
StandardBasicTypes.DOUBLE, SpatialAnalysis.DISTANCE));
registerFunction("buffer", new SpatialAnalysisFunction("buffer",
GeometryType.INSTANCE,
SpatialAnalysis.BUFFER));
registerFunction("convexhull", new SpatialAnalysisFunction(
"convexhull", GeometryType.INSTANCE,
SpatialAnalysis.CONVEXHULL));
registerFunction("difference", new SpatialAnalysisFunction(
"difference", GeometryType.INSTANCE,
SpatialAnalysis.DIFFERENCE));
registerFunction("intersection", new SpatialAnalysisFunction(
"intersection", GeometryType.INSTANCE,
SpatialAnalysis.INTERSECTION));
registerFunction("symdifference", new SpatialAnalysisFunction(
"symdifference", GeometryType.INSTANCE,
SpatialAnalysis.SYMDIFFERENCE));
registerFunction("geomunion", new SpatialAnalysisFunction("union",
GeometryType.INSTANCE,
SpatialAnalysis.UNION));
// we rename OGC union to geomunion because union is a reserved SQL
// keyword. (See also postgis documentation).
// portable spatial aggregate functions
registerFunction("extent", new SpatialAggregationFunction("extent",
GeometryType.INSTANCE, false,
OracleSpatialAggregate.EXTENT));
//other common functions
registerFunction("transform", new StandardSQLFunction("SDO_CS.TRANSFORM",
GeometryType.INSTANCE));
// Oracle specific Aggregate functions
registerFunction("centroid", new SpatialAggregationFunction("extent",
GeometryType.INSTANCE, false,
OracleSpatialAggregate.CENTROID));
registerFunction("concat_lines", new SpatialAggregationFunction(
"extent", GeometryType.INSTANCE, false,
OracleSpatialAggregate.CONCAT_LINES));
registerFunction("aggr_convexhull", new SpatialAggregationFunction(
"extent", GeometryType.INSTANCE, false,
OracleSpatialAggregate.CONVEXHULL));
registerFunction("aggr_union", new SpatialAggregationFunction("extent",
GeometryType.INSTANCE, false,
OracleSpatialAggregate.UNION));
registerFunction("lrs_concat", new SpatialAggregationFunction(
"lrsconcat", GeometryType.INSTANCE,
false, OracleSpatialAggregate.LRS_CONCAT));
}
@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
if ( sqlTypeDescriptor instanceof SpatialGeometrySqlTypeDescriptor ) {
return SDOGeometryTypeDescriptor.INSTANCE;
}
return super.remapSqlTypeDescriptor( sqlTypeDescriptor );
}
public String getNativeSpatialRelateSQL(String arg1, String arg2,
int spatialRelation) {
String mask = "";
boolean negate = false;
switch (spatialRelation) {
case SpatialRelation.INTERSECTS:
mask = "ANYINTERACT"; // OGC Compliance verified
break;
case SpatialRelation.CONTAINS:
mask = "CONTAINS+COVERS";
break;
case SpatialRelation.CROSSES:
throw new UnsupportedOperationException(
"Oracle Spatial does't have equivalent CROSSES relationship");
case SpatialRelation.DISJOINT:
mask = "ANYINTERACT";
negate = true;
break;
case SpatialRelation.EQUALS:
mask = "EQUAL";
break;
case SpatialRelation.OVERLAPS:
mask = "OVERLAPBDYDISJOINT+OVERLAPBDYINTERSECT";
break;
case SpatialRelation.TOUCHES:
mask = "TOUCH";
break;
case SpatialRelation.WITHIN:
mask = "INSIDE+COVEREDBY";
break;
default:
throw new IllegalArgumentException(
"undefined SpatialRelation passed (" + spatialRelation
+ ")");
}
StringBuffer buffer;
if (negate) {
buffer = new StringBuffer("CASE WHEN SDO_RELATE(");
} else {
buffer = new StringBuffer("SDO_RELATE(");
}
buffer.append(arg1);
buffer.append(",").append(arg2).append( ",'mask=" + mask + "') " );
if (negate) {
buffer.append(" = 'TRUE' THEN 'FALSE' ELSE 'TRUE' END");
}
return buffer.toString();
}
public String getOGCSpatialRelateSQL(String arg1, String arg2,
int spatialRelation) {
StringBuffer ogcFunction = new StringBuffer("MDSYS.");
switch (spatialRelation) {
case SpatialRelation.INTERSECTS:
ogcFunction.append("OGC_INTERSECTS");
break;
case SpatialRelation.CONTAINS:
ogcFunction.append("OGC_CONTAINS");
break;
case SpatialRelation.CROSSES:
ogcFunction.append("OGC_CROSS");
break;
case SpatialRelation.DISJOINT:
ogcFunction.append("OGC_DISJOINT");
break;
case SpatialRelation.EQUALS:
ogcFunction.append("OGC_EQUALS");
break;
case SpatialRelation.OVERLAPS:
ogcFunction.append("OGC_OVERLAP");
break;
case SpatialRelation.TOUCHES:
ogcFunction.append("OGC_TOUCH");
break;
case SpatialRelation.WITHIN:
ogcFunction.append("OGC_WITHIN");
break;
default:
throw new IllegalArgumentException("Unknown SpatialRelation ("
+ spatialRelation + ").");
}
ogcFunction.append("(").append("MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(")
.append(arg1).append("),").append(
"MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(").append(arg2)
.append(")").append(")");
return ogcFunction.toString();
}
public String getNativeSpatialAggregateSQL(String arg1, int aggregation) {
StringBuffer aggregateFunction = new StringBuffer();
SpatialAggregate sa = new SpatialAggregate(aggregation);
if (sa._aggregateSyntax == null) {
throw new IllegalArgumentException("Unknown Spatial Aggregation ("
+ aggregation + ").");
}
aggregateFunction.append(sa._aggregateSyntax);
aggregateFunction.append("(");
if (sa.isAggregateType()) {
aggregateFunction.append("SDOAGGRTYPE(");
}
aggregateFunction.append(arg1);
// TODO tolerance must by configurable
if (sa.isAggregateType()) {
aggregateFunction.append(", ").append(.001).append(")");
}
aggregateFunction.append(")");
return aggregateFunction.toString();
}
private StringBuffer wrapInSTGeometry(String geomColumn, StringBuffer toAdd) {
return toAdd.append("MDSYS.ST_GEOMETRY(").append(geomColumn)
.append(")");
}
public String getSpatialFilterExpression(String columnName) {
StringBuffer buffer = new StringBuffer("SDO_FILTER(");
// String pureColumnName =
// columnName.substring(columnName.lastIndexOf(".")+1);
// buffer.append("\"" + pureColumnName.toUpperCase() + "\"");
buffer.append(columnName);
buffer.append(",?) = 'TRUE' ");
return buffer.toString();
}
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
String sql = (isOGCStrict() ? (getOGCSpatialRelateSQL(columnName, "?",
spatialRelation) + " = 1") : (getNativeSpatialRelateSQL(
columnName, "?", spatialRelation) + "= 'TRUE'"));
sql += " and " + columnName + " is not null";
return sql;
}
public String getSpatialAnalysisSQL(List args, int spatialAnalysisFunction,
boolean useFilter) {
return isOGCStrict() ? getOGCSpatialAnalysisSQL(args,
spatialAnalysisFunction) : getNativeSpatialAnalysisSQL(args,
spatialAnalysisFunction);
}
public String getSpatialAggregateSQL(String columnName,
int spatialAggregateFunction) {
return getNativeSpatialAggregateSQL(
columnName,
spatialAggregateFunction
);
}
public String getDWithinSQL(String columnName) {
throw new UnsupportedOperationException("No DWithin in this dialect");
}
public String getHavingSridSQL(String columnName) {
return String.format( " (MDSYS.ST_GEOMETRY(%s).ST_SRID() = ?)", columnName );
}
public String getIsEmptySQL(String columnName, boolean isEmpty) {
return String.format(
"( MDSYS.ST_GEOMETRY(%s).ST_ISEMPTY() = %d )",
columnName,
isEmpty ? 1 : 0
);
}
private String getOGCSpatialAnalysisSQL(List args,
int spatialAnalysisFunction) {
boolean[] geomArgs;
StringBuffer ogcFunction = new StringBuffer("MDSYS.");
boolean isGeomReturn = true;
switch (spatialAnalysisFunction) {
case SpatialAnalysis.BUFFER:
ogcFunction.append("OGC_BUFFER");
geomArgs = new boolean[]{true, false};
break;
case SpatialAnalysis.CONVEXHULL:
ogcFunction.append("OGC_CONVEXHULL");
geomArgs = new boolean[]{true};
break;
case SpatialAnalysis.DIFFERENCE:
ogcFunction.append("OGC_DIFFERENCE");
geomArgs = new boolean[]{true, true};
break;
case SpatialAnalysis.DISTANCE:
ogcFunction.append("OGC_DISTANCE");
geomArgs = new boolean[]{true, true};
isGeomReturn = false;
break;
case SpatialAnalysis.INTERSECTION:
ogcFunction.append("OGC_INTERSECTION");
geomArgs = new boolean[]{true, true};
break;
case SpatialAnalysis.SYMDIFFERENCE:
ogcFunction.append("OGC_SYMMETRICDIFFERENCE");
geomArgs = new boolean[]{true, true};
break;
case SpatialAnalysis.UNION:
ogcFunction.append("OGC_UNION");
geomArgs = new boolean[]{true, true};
break;
default:
throw new IllegalArgumentException(
"Unknown SpatialAnalysisFunction ("
+ spatialAnalysisFunction + ").");
}
if (args.size() < geomArgs.length)
throw new QueryException(
"Insufficient arguments for spatial analysis function (function type: "
+ spatialAnalysisFunction + ").");
ogcFunction.append("(");
for (int i = 0; i < geomArgs.length; i++) {
if (i > 0)
ogcFunction.append(",");
if (geomArgs[i])
wrapInSTGeometry((String) args.get(i), ogcFunction);
else
ogcFunction.append(args.get(i));
}
ogcFunction.append(")");
if (isGeomReturn)
ogcFunction.append(".geom");
return ogcFunction.toString();
}
private String getNativeSpatialAnalysisSQL(List args, int spatialAnalysis) {
return getOGCSpatialAnalysisSQL( args, spatialAnalysis );
}
boolean isOGCStrict() {
return ((Boolean) this.features.get(OGC_STRICT)).booleanValue();
}
private void configure() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String propfileLoc = getClass().getCanonicalName() + ".properties";
URL propfile = loader.getResource(propfileLoc);
if (propfile != null) {
InputStream is = null;
log.info("properties file found: " + propfile);
try {
loader.getResource(getClass().getCanonicalName());
is = propfile.openStream();
PropertyFileReader reader = new PropertyFileReader(is);
Properties props = reader.getProperties();
// checking for connectionfinder
String ccn = props.getProperty(CONNECTION_FINDER_PROPERTY);
if (ccn != null) {
try {
Class clazz = Thread.currentThread()
.getContextClassLoader().loadClass(ccn);
ConnectionFinder cf = (ConnectionFinder) clazz
.newInstance();
OracleJDBCTypeFactory.setConnectionFinder(cf);
log.info("Setting ConnectionFinder to " + ccn);
} catch (ClassNotFoundException e) {
log.warn("Tried to set ConnectionFinder to " + ccn
+ ", but class not found.");
} catch (InstantiationException e) {
log.warn("Tried to set ConnectionFinder to " + ccn
+ ", but couldn't instantiate.");
} catch (IllegalAccessException e) {
log
.warn("Tried to set ConnectionFinder to "
+ ccn
+ ", but got IllegalAcessException on instantiation.");
}
}
} catch (IOException e) {
log.warn("Problem reading properties file " + e);
} finally {
try {
is.close();
} catch (Exception e) {
}
}
}
}
public boolean isTwoPhaseFiltering() {
return false;
}
public boolean supportsFiltering() {
return true;
}
public boolean supports(SpatialFunction function) {
return (getFunctions().get(function.toString()) != null);
}
}

View File

@ -0,0 +1,72 @@
package org.hibernate.spatial.dialect.oracle;
import java.sql.Array;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Jul 1, 2010
*/
class Ordinates {
static final String TYPE_NAME = "MDSYS.SDO_ORDINATE_ARRAY";
private Double[] ordinates;
public Ordinates(Double[] ordinates) {
this.ordinates = ordinates;
}
public Ordinates(Array array) {
if (array == null) {
this.ordinates = new Double[]{};
return;
}
try {
Number[] ords = (Number[]) array.getArray();
this.ordinates = new Double[ords.length];
for (int i = 0; i < ords.length; i++) {
this.ordinates[i] = ords[i] != null ? ords[i].doubleValue()
: Double.NaN;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Double[] getOrdinateArray() {
return this.ordinates;
}
public Double[] getOrdinatesArray(int startPosition, int endPosition) {
Double[] a = new Double[endPosition - startPosition];
System.arraycopy(this.ordinates, startPosition - 1, a, 0, a.length);
return a;
}
public Double[] getOrdinatesArray(int startPosition) {
Double[] a = new Double[this.ordinates.length - (startPosition - 1)];
System.arraycopy(this.ordinates, startPosition - 1, a, 0, a.length);
return a;
}
public String toString() {
return SDOGeometry.arrayToString(this.ordinates);
}
public void addOrdinates(Double[] ordinatesToAdd) {
Double[] newOrdinates = new Double[this.ordinates.length
+ ordinatesToAdd.length];
System.arraycopy(this.ordinates, 0, newOrdinates, 0,
this.ordinates.length);
System.arraycopy(ordinatesToAdd, 0, newOrdinates,
this.ordinates.length, ordinatesToAdd.length);
this.ordinates = newOrdinates;
}
// public ARRAY toOracleArray(Connection conn) throws SQLException {
// ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor(
// TYPE_NAME, conn);
// return new ARRAY(arrayDescriptor, conn, this.ordinates);
// }
}

View File

@ -0,0 +1,78 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.dialect.Dialect;
import org.hibernate.type.BooleanType;
class SDOBooleanType extends BooleanType {
private static final long serialVersionUID = 1L;
/**
* <p/>
* This type's name is <tt>sdo_boolean</tt>
*/
public String getName() {
return "sdo_boolean";
}
public Object get(ResultSet rs, String name) throws SQLException {
String value = rs.getString(name);
if (rs.wasNull()) {
return getDefaultValue();
} else if ("TRUE".equalsIgnoreCase(value)) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}
public void set(PreparedStatement st, Boolean value, int index)
throws SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
boolean bool = value.booleanValue();
st.setString(index, bool ? "TRUE" : "FALSE");
}
}
public String objectToSQLString(Boolean value, Dialect dialect) {
return value.booleanValue() ? "'TRUE'" : "'FALSE'";
}
// public int sqlType() {
// return Types.VARCHAR;
// }
}

View File

@ -0,0 +1,105 @@
package org.hibernate.spatial.dialect.oracle;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Jun 30, 2010
*/
class SDOGType {
private int dimension = 2;
private int lrsDimension = 0;
private TypeGeometry typeGeometry = TypeGeometry.UNKNOWN_GEOMETRY;
public SDOGType(int dimension, int lrsDimension,
TypeGeometry typeGeometry) {
setDimension(dimension);
setLrsDimension(lrsDimension);
setTypeGeometry(typeGeometry);
}
public int getDimension() {
return dimension;
}
public void setDimension(int dimension) {
if (dimension < 2 || dimension > 4) {
throw new IllegalArgumentException(
"Dimension can only be 2,3 or 4.");
}
this.dimension = dimension;
}
public TypeGeometry getTypeGeometry() {
return typeGeometry;
}
public void setTypeGeometry(TypeGeometry typeGeometry) {
this.typeGeometry = typeGeometry;
}
public int getLRSDimension() {
if (this.lrsDimension > 0) {
return this.lrsDimension;
} else if (this.lrsDimension == 0 && this.dimension == 4) {
return 4;
}
return 0;
}
public int getZDimension() {
if (this.dimension > 2) {
if (!isLRSGeometry()) {
return this.dimension;
} else {
return (getLRSDimension() < this.dimension ? 4 : 3);
}
}
return 0;
}
public boolean isLRSGeometry() {
return (this.lrsDimension > 0 || (this.lrsDimension == 0 && this.dimension == 4));
}
public void setLrsDimension(int lrsDimension) {
if (lrsDimension != 0 && lrsDimension > this.dimension) {
throw new IllegalArgumentException(
"lrsDimension must be 0 or lower or equal to dimenstion.");
}
this.lrsDimension = lrsDimension;
}
public int intValue() {
int v = this.dimension * 1000;
v += lrsDimension * 100;
v += typeGeometry.intValue();
return v;
}
public static SDOGType parse(int v) {
int dim = v / 1000;
v -= dim * 1000;
int lrsDim = v / 100;
v -= lrsDim * 100;
TypeGeometry typeGeometry = TypeGeometry.parse(v);
return new SDOGType(dim, lrsDim, typeGeometry);
}
public static SDOGType parse(Object datum) {
try {
int v = ((Number) datum).intValue();
return parse(v);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String toString() {
return Integer.toString(this.intValue());
}
}

View File

@ -0,0 +1,325 @@
package org.hibernate.spatial.dialect.oracle;
import java.sql.Array;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.spatial.helper.FinderException;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Jun 30, 2010
*/
class SDOGeometry {
private final static SQLTypeFactory TYPE_FACTORY = new OracleJDBCTypeFactory();
private static final String SQL_TYPE_NAME = "MDSYS.SDO_GEOMETRY";
private SDOGType gtype;
private int srid;
private SDOPoint point;
private ElemInfo info;
private Ordinates ordinates;
public SDOGeometry() {
}
public static String getTypeName() {
return SQL_TYPE_NAME;
}
static String arrayToString(Object array) {
if (array == null || java.lang.reflect.Array.getLength(array) == 0) {
return "()";
}
int length = java.lang.reflect.Array.getLength(array);
StringBuilder stb = new StringBuilder();
stb.append("(").append(java.lang.reflect.Array.get(array, 0));
for (int i = 1; i < length; i++) {
stb.append(",").append(java.lang.reflect.Array.get(array, i));
}
stb.append(")");
return stb.toString();
}
/**
* This joins an array of SDO_GEOMETRIES to a SDOGeometry of type
* COLLECTION
*
* @param SDOElements
* @return
*/
public static SDOGeometry join(SDOGeometry[] SDOElements) {
SDOGeometry SDOCollection = new SDOGeometry();
if (SDOElements == null || SDOElements.length == 0) {
SDOCollection.setGType(new SDOGType(2, 0,
TypeGeometry.COLLECTION));
} else {
SDOGeometry firstElement = SDOElements[0];
int dim = firstElement.getGType().getDimension();
int lrsDim = firstElement.getGType().getLRSDimension();
SDOCollection.setGType(new SDOGType(dim, lrsDim,
TypeGeometry.COLLECTION));
int ordinatesOffset = 1;
for (int i = 0; i < SDOElements.length; i++) {
ElemInfo element = SDOElements[i].getInfo();
Double[] ordinates = SDOElements[i].getOrdinates()
.getOrdinateArray();
if (element != null && element.getSize() > 0) {
int shift = ordinatesOffset
- element.getOrdinatesOffset(0);
shiftOrdinateOffset(element, shift);
SDOCollection.addElement(element);
SDOCollection.addOrdinates(ordinates);
ordinatesOffset += ordinates.length;
}
}
}
return SDOCollection;
}
public ElemInfo getInfo() {
return info;
}
public void setInfo(ElemInfo info) {
this.info = info;
}
public SDOGType getGType() {
return gtype;
}
public void setGType(SDOGType gtype) {
this.gtype = gtype;
}
public Ordinates getOrdinates() {
return ordinates;
}
public void setOrdinates(Ordinates ordinates) {
this.ordinates = ordinates;
}
public SDOPoint getPoint() {
return point;
}
public void setPoint(SDOPoint point) {
this.point = point;
}
public int getSRID() {
return srid;
}
public void setSRID(int srid) {
this.srid = srid;
}
public static SDOGeometry load(Struct struct) {
Object[] data;
try {
data = struct.getAttributes();
} catch (SQLException e) {
throw new RuntimeException(e);
}
SDOGeometry geom = new SDOGeometry();
geom.setGType(SDOGType.parse(data[0]));
geom.setSRID(data[1]);
if (data[2] != null) {
geom.setPoint(new SDOPoint((Struct) data[2]));
}
geom.setInfo(new ElemInfo((Array) data[3]));
geom.setOrdinates(new Ordinates((Array) data[4]));
return geom;
}
public static Struct store(SDOGeometry geom, Connection conn)
throws SQLException, FinderException {
return TYPE_FACTORY.createStruct(geom, conn);
}
private void setSRID(Object datum) {
if (datum == null) {
this.srid = 0;
return;
}
try {
this.srid = new Integer(((Number) datum).intValue());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public boolean isLRSGeometry() {
return gtype.isLRSGeometry();
}
public int getDimension() {
return gtype.getDimension();
}
public int getLRSDimension() {
return gtype.getLRSDimension();
}
public int getZDimension() {
return gtype.getZDimension();
}
/**
* Gets the number of elements or compound elements.
* <p/>
* Subelements of a compound element are not counted.
*
* @return the number of elements
*/
public int getNumElements() {
int cnt = 0;
int i = 0;
while (i < info.getSize()) {
if (info.getElementType(i).isCompound()) {
int numCompounds = info.getNumCompounds(i);
i += 1 + numCompounds;
} else {
i++;
}
cnt++;
}
return cnt;
}
public String toString() {
StringBuilder stb = new StringBuilder();
stb.append("(").append(gtype).append(",").append(srid).append(",")
.append(point).append(",").append(info).append(",").append(
ordinates).append(")");
return stb.toString();
}
public void addOrdinates(Double[] newOrdinates) {
if (this.ordinates == null) {
this.ordinates = new Ordinates(newOrdinates);
} else {
this.ordinates.addOrdinates(newOrdinates);
}
}
public void addElement(ElemInfo element) {
if (this.info == null) {
this.info = element;
} else {
this.info.addElement(element);
}
}
/**
* If this SDOGeometry is a COLLECTION, this method returns an array of
* the SDO_GEOMETRIES that make up the collection. If not a Collection,
* an array containing this SDOGeometry is returned.
*
* @return collection elements as individual SDO_GEOMETRIES
*/
public SDOGeometry[] getElementGeometries() {
if (getGType().getTypeGeometry() == TypeGeometry.COLLECTION) {
List<SDOGeometry> elements = new ArrayList<SDOGeometry>();
int i = 0;
while (i < this.getNumElements()) {
ElementType et = this.getInfo().getElementType(i);
int next = i + 1;
// if the element is an exterior ring, or a compound
// element, then this geometry spans multiple elements.
if (et.isExteriorRing()) { // then next element is the
// first non-interior ring
while (next < this.getNumElements()) {
if (!this.getInfo().getElementType(next)
.isInteriorRing()) {
break;
}
next++;
}
} else if (et.isCompound()) {
next = i + this.getInfo().getNumCompounds(i) + 1;
}
SDOGeometry elemGeom = new SDOGeometry();
SDOGType elemGtype = deriveGTYPE(this.getInfo()
.getElementType(i), this);
elemGeom.setGType(elemGtype);
elemGeom.setSRID(this.getSRID());
ElemInfo elemInfo = new ElemInfo(this.getInfo()
.getElement(i));
shiftOrdinateOffset(elemInfo, -elemInfo
.getOrdinatesOffset(0) + 1);
elemGeom.setInfo(elemInfo);
int startPosition = this.getInfo().getOrdinatesOffset(i);
Ordinates elemOrdinates = null;
if (next < this.getNumElements()) {
int endPosition = this.getInfo().getOrdinatesOffset(
next);
elemOrdinates = new Ordinates(this.getOrdinates()
.getOrdinatesArray(startPosition, endPosition));
} else {
elemOrdinates = new Ordinates(this.getOrdinates()
.getOrdinatesArray(startPosition));
}
elemGeom.setOrdinates(elemOrdinates);
elements.add(elemGeom);
i = next;
}
return elements.toArray(new SDOGeometry[elements.size()]);
} else {
return new SDOGeometry[]{this};
}
}
private static void shiftOrdinateOffset(ElemInfo elemInfo, int offset) {
for (int i = 0; i < elemInfo.getSize(); i++) {
int newOffset = elemInfo.getOrdinatesOffset(i) + offset;
elemInfo.setOrdinatesOffset(i, newOffset);
}
}
private static SDOGType deriveGTYPE(ElementType elementType,
SDOGeometry origGeom) {
switch (elementType) {
case POINT:
case ORIENTATION:
return new SDOGType(origGeom.getDimension(), origGeom
.getLRSDimension(), TypeGeometry.POINT);
case POINT_CLUSTER:
return new SDOGType(origGeom.getDimension(), origGeom
.getLRSDimension(), TypeGeometry.MULTIPOINT);
case LINE_ARC_SEGMENTS:
case LINE_STRAITH_SEGMENTS:
case COMPOUND_LINE:
return new SDOGType(origGeom.getDimension(), origGeom
.getLRSDimension(), TypeGeometry.LINE);
case COMPOUND_EXTERIOR_RING:
case EXTERIOR_RING_ARC_SEGMENTS:
case EXTERIOR_RING_CIRCLE:
case EXTERIOR_RING_RECT:
case EXTERIOR_RING_STRAIGHT_SEGMENTS:
return new SDOGType(origGeom.getDimension(), origGeom
.getLRSDimension(), TypeGeometry.POLYGON);
}
return null;
}
}

View File

@ -0,0 +1,39 @@
package org.hibernate.spatial.dialect.oracle;
import java.sql.Types;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/22/11
*/
public class SDOGeometryTypeDescriptor implements SqlTypeDescriptor {
public static SDOGeometryTypeDescriptor INSTANCE = new SDOGeometryTypeDescriptor();
@Override
public int getSqlType() {
return Types.STRUCT;
}
@Override
public boolean canBeRemapped() {
return false;
}
@Override
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
return (ValueBinder<X>) new SDOGeometryValueBinder();
}
@Override
public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
return (ValueExtractor<X>) new SDOGeometryValueExtractor();
}
}

View File

@ -0,0 +1,357 @@
package org.hibernate.spatial.dialect.oracle;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import com.vividsolutions.jts.algorithm.CGAlgorithms;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import org.hibernate.HibernateException;
import org.hibernate.spatial.HBSpatialExtension;
import org.hibernate.spatial.helper.FinderException;
import org.hibernate.spatial.mgeom.MCoordinate;
import org.hibernate.spatial.mgeom.MGeometryFactory;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.WrapperOptions;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/22/11
*/
public class SDOGeometryValueBinder implements ValueBinder<Geometry> {
@Override
public void bind(PreparedStatement st, Geometry value, int index, WrapperOptions options) throws SQLException {
if ( value == null ) {
st.setNull( index, Types.STRUCT, SDOGeometry.getTypeName());
}
else {
Geometry jtsGeom = (Geometry) value;
Object dbGeom = toNative( jtsGeom, st.getConnection() );
st.setObject( index, dbGeom );
}
}
public MGeometryFactory getGeometryFactory() {
return HBSpatialExtension.getDefaultGeomFactory();
}
private Object toNative(Geometry jtsGeom, Connection connection){
SDOGeometry geom = convertJTSGeometry(jtsGeom);
if (geom != null)
try {
return SDOGeometry.store(geom, connection);
} catch (SQLException e) {
throw new HibernateException(
"Problem during conversion from JTS to SDOGeometry", e);
} catch (FinderException e) {
throw new HibernateException(
"OracleConnection could not be retrieved for creating SDOGeometry STRUCT", e);
}
else {
throw new UnsupportedOperationException("Conversion of "
+ jtsGeom.getClass().getSimpleName()
+ " to Oracle STRUCT not supported");
}
}
private SDOGeometry convertJTSGeometry(Geometry jtsGeom) {
SDOGeometry geom = null;
if (jtsGeom instanceof Point ) {
geom = convertJTSPoint((Point) jtsGeom);
} else if (jtsGeom instanceof LineString ) {
geom = convertJTSLineString((LineString) jtsGeom);
} else if (jtsGeom instanceof Polygon ) {
geom = convertJTSPolygon((Polygon) jtsGeom);
} else if (jtsGeom instanceof MultiPoint ) {
geom = convertJTSMultiPoint((MultiPoint) jtsGeom);
} else if (jtsGeom instanceof MultiLineString ) {
geom = convertJTSMultiLineString((MultiLineString) jtsGeom);
} else if (jtsGeom instanceof MultiPolygon ) {
geom = convertJTSMultiPolygon((MultiPolygon) jtsGeom);
} else if (jtsGeom instanceof GeometryCollection ) {
geom = convertJTSGeometryCollection((GeometryCollection) jtsGeom);
}
return geom;
}
private SDOGeometry convertJTSGeometryCollection(
GeometryCollection collection) {
SDOGeometry[] SDOElements = new SDOGeometry[collection
.getNumGeometries()];
for (int i = 0; i < collection.getNumGeometries(); i++) {
Geometry geom = collection.getGeometryN(i);
SDOElements[i] = convertJTSGeometry(geom);
}
SDOGeometry ccollect = SDOGeometry.join(SDOElements);
ccollect.setSRID(collection.getSRID());
return ccollect;
}
private SDOGeometry convertJTSMultiPolygon(MultiPolygon multiPolygon) {
int dim = getCoordDimension(multiPolygon);
int lrsPos = getCoordinateLrsPosition(multiPolygon);
SDOGeometry geom = new SDOGeometry();
geom.setGType(new SDOGType(dim, lrsPos, TypeGeometry.MULTIPOLYGON));
geom.setSRID(multiPolygon.getSRID());
for (int i = 0; i < multiPolygon.getNumGeometries(); i++) {
try {
Polygon pg = (Polygon) multiPolygon.getGeometryN(i);
addPolygon(geom, pg);
} catch (Exception e) {
throw new RuntimeException(
"Found geometry that was not a geometry in MultiPolygon");
}
}
return geom;
}
private SDOGeometry convertJTSLineString(LineString lineString) {
int dim = getCoordDimension(lineString);
int lrsPos = getCoordinateLrsPosition(lineString);
boolean isLrs = lrsPos > 0;
Double[] ordinates = convertCoordinates(lineString.getCoordinates(),
dim, isLrs);
SDOGeometry geom = new SDOGeometry();
geom.setGType(new SDOGType(dim, lrsPos, TypeGeometry.LINE));
geom.setSRID(lineString.getSRID());
ElemInfo info = new ElemInfo(1);
info.setElement(0, 1, ElementType.LINE_STRAITH_SEGMENTS, 0);
geom.setInfo(info);
geom.setOrdinates(new Ordinates(ordinates));
return geom;
}
private SDOGeometry convertJTSMultiPoint(MultiPoint multiPoint) {
int dim = getCoordDimension(multiPoint);
int lrsDim = getCoordinateLrsPosition(multiPoint);
boolean isLrs = (lrsDim != 0);
SDOGeometry geom = new SDOGeometry();
geom.setGType(new SDOGType(dim, lrsDim, TypeGeometry.MULTIPOINT));
geom.setSRID(multiPoint.getSRID());
ElemInfo info = new ElemInfo(multiPoint.getNumPoints());
int oordinatesOffset = 1;
Double[] ordinates = new Double[]{};
for (int i = 0; i < multiPoint.getNumPoints(); i++) {
info.setElement(i, oordinatesOffset, ElementType.POINT, 0);
ordinates = convertAddCoordinates(ordinates, multiPoint
.getGeometryN(i).getCoordinates(), dim, isLrs);
oordinatesOffset = ordinates.length + 1;
}
geom.setInfo(info);
geom.setOrdinates(new Ordinates(ordinates));
return geom;
}
private SDOGeometry convertJTSPoint(Point jtsGeom) {
int dim = getCoordDimension(jtsGeom);
int lrsDim = getCoordinateLrsPosition(jtsGeom);
boolean isLrs = (lrsDim != 0);
Double[] coord = convertCoordinates(jtsGeom.getCoordinates(), dim,
isLrs);
SDOGeometry geom = new SDOGeometry();
geom.setGType(new SDOGType(dim, lrsDim, TypeGeometry.POINT));
geom.setSRID(jtsGeom.getSRID());
ElemInfo info = new ElemInfo(1);
info.setElement(0, 1, ElementType.POINT, 1);
geom.setInfo(info);
geom.setOrdinates(new Ordinates(coord));
return geom;
}
private SDOGeometry convertJTSPolygon(Polygon polygon) {
int dim = getCoordDimension(polygon);
int lrsPos = getCoordinateLrsPosition(polygon);
SDOGeometry geom = new SDOGeometry();
geom.setGType(new SDOGType(dim, lrsPos, TypeGeometry.POLYGON));
geom.setSRID(polygon.getSRID());
addPolygon(geom, polygon);
return geom;
}
private void addPolygon(SDOGeometry geom, Polygon polygon) {
int numInteriorRings = polygon.getNumInteriorRing();
ElemInfo info = new ElemInfo(numInteriorRings + 1);
int ordinatesPreviousOffset = 0;
if (geom.getOrdinates() != null) {
ordinatesPreviousOffset = geom.getOrdinates().getOrdinateArray().length;
}
int ordinatesOffset = ordinatesPreviousOffset + 1;
Double[] ordinates = new Double[]{};
for (int i = 0; i < info.getSize(); i++) {
ElementType et;
Coordinate[] coords;
if (i == 0) {
et = ElementType.EXTERIOR_RING_STRAIGHT_SEGMENTS;
coords = polygon.getExteriorRing().getCoordinates();
if (!CGAlgorithms.isCCW( coords )) {
coords = reverseRing(coords);
}
} else {
et = ElementType.INTERIOR_RING_STRAIGHT_SEGMENTS;
coords = polygon.getInteriorRingN(i - 1).getCoordinates();
if (CGAlgorithms.isCCW(coords)) {
coords = reverseRing(coords);
}
}
info.setElement(i, ordinatesOffset, et, 0);
ordinates = convertAddCoordinates(ordinates, coords, geom
.getDimension(), geom.isLRSGeometry());
ordinatesOffset = ordinatesPreviousOffset + ordinates.length + 1;
}
geom.addElement(info);
geom.addOrdinates(ordinates);
}
private SDOGeometry convertJTSMultiLineString(
MultiLineString multiLineString) {
int dim = getCoordDimension(multiLineString);
int lrsDim = getCoordinateLrsPosition(multiLineString);
boolean isLrs = (lrsDim != 0);
SDOGeometry geom = new SDOGeometry();
geom.setGType(new SDOGType(dim, lrsDim, TypeGeometry.MULTILINE));
geom.setSRID(multiLineString.getSRID());
ElemInfo info = new ElemInfo(multiLineString.getNumGeometries());
int oordinatesOffset = 1;
Double[] ordinates = new Double[]{};
for (int i = 0; i < multiLineString.getNumGeometries(); i++) {
info.setElement(i, oordinatesOffset,
ElementType.LINE_STRAITH_SEGMENTS, 0);
ordinates = convertAddCoordinates(ordinates, multiLineString
.getGeometryN(i).getCoordinates(), dim, isLrs);
oordinatesOffset = ordinates.length + 1;
}
geom.setInfo(info);
geom.setOrdinates(new Ordinates(ordinates));
return geom;
}
private Double[] convertAddCoordinates(Double[] ordinates,
Coordinate[] coordinates, int dim, boolean isLrs) {
Double[] no = convertCoordinates(coordinates, dim, isLrs);
Double[] newordinates = new Double[ordinates.length + no.length];
System.arraycopy(ordinates, 0, newordinates, 0, ordinates.length);
System.arraycopy(no, 0, newordinates, ordinates.length, no.length);
return newordinates;
}
/**
* Convert the coordinates to a double array for purposes of persisting them
* to the database. Note that Double.NaN values are to be converted to null
* values in the array.
*
* @param coordinates Coordinates to be converted to the array
* @param dim Coordinate dimension
* @param isLrs true if the coordinates contain measures
* @return
*/
private Double[] convertCoordinates(Coordinate[] coordinates, int dim,
boolean isLrs) {
if (dim > 4)
throw new IllegalArgumentException(
"Dim parameter value cannot be greater than 4");
Double[] converted = new Double[coordinates.length * dim];
for (int i = 0; i < coordinates.length; i++) {
MCoordinate c = MCoordinate.convertCoordinate(coordinates[i]);
// set the X and Y values
converted[i * dim] = toDouble(c.x);
converted[i * dim + 1] = toDouble(c.y);
if (dim == 3)
converted[i * dim + 2] = isLrs ? toDouble(c.m) : toDouble(c.z);
else if (dim == 4) {
converted[i * dim + 2] = toDouble(c.z);
converted[i * dim + 3] = toDouble(c.m);
}
}
return converted;
}
/**
* This method converts a double primitive to a Double wrapper instance, but
* treats a Double.NaN value as null.
*
* @param d the value to be converted
* @return A Double instance of d, Null if the parameter is Double.NaN
*/
private Double toDouble(double d) {
return Double.isNaN(d) ? null : d;
}
/**
* Return the dimension required for building the gType in the SDOGeometry
* object. Has support for LRS type geometries.
*
* @param geom and instance of the Geometry class from which the dimension is
* being extracted.
* @return number of dimensions for purposes of creating the
* SDOGeometry.SDOGType
*/
private int getCoordDimension(Geometry geom) {
// This is awkward, I have to create an MCoordinate to discover what the
// dimension is.
// This shall be cleaner if MCoordinate.getOrdinate(int ordinateIndex)
// is moved to the
// Coordinate class
MCoordinate c = MCoordinate.convertCoordinate(geom.getCoordinate());
int d = 0;
if (c != null) {
if (!Double.isNaN(c.x))
d++;
if (!Double.isNaN(c.y))
d++;
if (!Double.isNaN(c.z))
d++;
if (!Double.isNaN(c.m))
d++;
}
return d;
}
/**
* Returns the lrs measure position for purposes of building the gType for
* an oracle geometry. At this point and time, I'll have to assume that the
* measure is always put at the end of the ordinate tuple, even though it
* technically wouldn't have to. This method bases its decision on whether
* the first coordinate has a measure value, as measure are required for the
* very first and last measure in a CoordinateSequence. If there is no
* measure value, 0 is returned.
*
* @param geom and instance of the Geometry class from which the lrs position
* is being extracted.
* @return the lrs position for the SDOGeometry.SDOGType
*/
private int getCoordinateLrsPosition(Geometry geom) {
MCoordinate c = MCoordinate.convertCoordinate( geom.getCoordinate() );
int measurePos = 0;
if (c != null && !Double.isNaN(c.m)) {
measurePos = (Double.isNaN(c.z)) ? 3 : 4;
}
return measurePos;
}
// reverses ordinates in a coordinate array in-place
private Coordinate[] reverseRing(Coordinate[] ar) {
for (int i = 0; i < ar.length / 2; i++) {
Coordinate cs = ar[i];
ar[i] = ar[ar.length - 1 - i];
ar[ar.length - 1 - i] = cs;
}
return ar;
}
}

View File

@ -0,0 +1,522 @@
package org.hibernate.spatial.dialect.oracle;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import org.hibernate.HibernateException;
import org.hibernate.spatial.Circle;
import org.hibernate.spatial.HBSpatialExtension;
import org.hibernate.spatial.mgeom.MCoordinate;
import org.hibernate.spatial.mgeom.MGeometryFactory;
import org.hibernate.spatial.mgeom.MLineString;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/22/11
*/
public class SDOGeometryValueExtractor implements ValueExtractor<Geometry> {
@Override
public Geometry extract(ResultSet rs, String name, WrapperOptions options)
throws SQLException {
Object geomObj = rs.getObject( name );
return toJTS( geomObj );
}
public MGeometryFactory getGeometryFactory() {
return HBSpatialExtension.getDefaultGeomFactory();
}
public Geometry toJTS(Object struct) {
if ( struct == null ) {
return null;
}
SDOGeometry SDOGeom = SDOGeometry.load( (Struct) struct );
return convert2JTS( SDOGeom );
}
private Geometry convert2JTS(SDOGeometry SDOGeom) {
int dim = SDOGeom.getGType().getDimension();
int lrsDim = SDOGeom.getGType().getLRSDimension();
Geometry result = null;
switch ( SDOGeom.getGType().getTypeGeometry() ) {
case POINT:
result = convertSDOPoint( SDOGeom );
break;
case LINE:
result = convertSDOLine( dim, lrsDim, SDOGeom );
break;
case POLYGON:
result = convertSDOPolygon( dim, lrsDim, SDOGeom );
break;
case MULTIPOINT:
result = convertSDOMultiPoint( dim, lrsDim, SDOGeom );
break;
case MULTILINE:
result = convertSDOMultiLine( dim, lrsDim, SDOGeom );
break;
case MULTIPOLYGON:
result = convertSDOMultiPolygon( dim, lrsDim, SDOGeom );
break;
case COLLECTION:
result = convertSDOCollection( dim, lrsDim, SDOGeom );
break;
default:
throw new IllegalArgumentException(
"Type not supported: "
+ SDOGeom.getGType().getTypeGeometry()
);
}
result.setSRID( SDOGeom.getSRID() );
return result;
}
private Geometry convertSDOCollection(int dim, int lrsDim,
SDOGeometry SDOGeom) {
List<Geometry> geometries = new ArrayList<Geometry>();
for ( SDOGeometry elemGeom : SDOGeom.getElementGeometries() ) {
geometries.add( convert2JTS( elemGeom ) );
}
Geometry[] geomArray = new Geometry[geometries.size()];
return getGeometryFactory().createGeometryCollection(
geometries.toArray( geomArray )
);
}
private Point convertSDOPoint(SDOGeometry SDOGeom) {
Double[] ordinates = SDOGeom.getOrdinates().getOrdinateArray();
if ( ordinates.length == 0 ) {
if ( SDOGeom.getDimension() == 2 ) {
ordinates = new Double[] {
SDOGeom.getPoint().x,
SDOGeom.getPoint().y
};
}
else {
ordinates = new Double[] {
SDOGeom.getPoint().x,
SDOGeom.getPoint().y, SDOGeom.getPoint().z
};
}
}
CoordinateSequence cs = convertOrdinateArray( ordinates, SDOGeom );
Point point = getGeometryFactory().createPoint( cs );
return point;
}
private MultiPoint convertSDOMultiPoint(int dim, int lrsDim,
SDOGeometry SDOGeom) {
Double[] ordinates = SDOGeom.getOrdinates().getOrdinateArray();
CoordinateSequence cs = convertOrdinateArray( ordinates, SDOGeom );
MultiPoint multipoint = getGeometryFactory().createMultiPoint( cs );
return multipoint;
}
private LineString convertSDOLine(int dim, int lrsDim, SDOGeometry SDOGeom) {
boolean lrs = SDOGeom.isLRSGeometry();
ElemInfo info = SDOGeom.getInfo();
CoordinateSequence cs = null;
int i = 0;
while ( i < info.getSize() ) {
if ( info.getElementType( i ).isCompound() ) {
int numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
i += 1 + numCompounds;
}
else {
cs = add( cs, getElementCSeq( i, SDOGeom, false ) );
i++;
}
}
LineString ls = lrs ? getGeometryFactory().createMLineString( cs )
: getGeometryFactory().createLineString( cs );
return ls;
}
private MultiLineString convertSDOMultiLine(int dim, int lrsDim,
SDOGeometry SDOGeom) {
boolean lrs = SDOGeom.isLRSGeometry();
ElemInfo info = SDOGeom.getInfo();
LineString[] lines = lrs ? new MLineString[SDOGeom.getInfo().getSize()]
: new LineString[SDOGeom.getInfo().getSize()];
int i = 0;
while ( i < info.getSize() ) {
CoordinateSequence cs = null;
if ( info.getElementType( i ).isCompound() ) {
int numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
LineString line = lrs ? getGeometryFactory().createMLineString(
cs
) : getGeometryFactory().createLineString( cs );
lines[i] = line;
i += 1 + numCompounds;
}
else {
cs = add( cs, getElementCSeq( i, SDOGeom, false ) );
LineString line = lrs ? getGeometryFactory().createMLineString(
cs
) : getGeometryFactory().createLineString( cs );
lines[i] = line;
i++;
}
}
MultiLineString mls = lrs ? getGeometryFactory()
.createMultiMLineString( (MLineString[]) lines )
: getGeometryFactory().createMultiLineString( lines );
return mls;
}
private Geometry convertSDOPolygon(int dim, int lrsDim, SDOGeometry SDOGeom) {
LinearRing shell = null;
LinearRing[] holes = new LinearRing[SDOGeom.getNumElements() - 1];
ElemInfo info = SDOGeom.getInfo();
int i = 0;
int idxInteriorRings = 0;
while ( i < info.getSize() ) {
CoordinateSequence cs = null;
int numCompounds = 0;
if ( info.getElementType( i ).isCompound() ) {
numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
}
else {
cs = add( cs, getElementCSeq( i, SDOGeom, false ) );
}
if ( info.getElementType( i ).isInteriorRing() ) {
holes[idxInteriorRings] = getGeometryFactory()
.createLinearRing( cs );
idxInteriorRings++;
}
else {
shell = getGeometryFactory().createLinearRing( cs );
}
i += 1 + numCompounds;
}
return getGeometryFactory().createPolygon( shell, holes );
}
private MultiPolygon convertSDOMultiPolygon(int dim, int lrsDim,
SDOGeometry SDOGeom) {
List<LinearRing> holes = new ArrayList<LinearRing>();
List<Polygon> polygons = new ArrayList<Polygon>();
ElemInfo info = SDOGeom.getInfo();
LinearRing shell = null;
int i = 0;
while ( i < info.getSize() ) {
CoordinateSequence cs = null;
int numCompounds = 0;
if ( info.getElementType( i ).isCompound() ) {
numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
}
else {
cs = add( cs, getElementCSeq( i, SDOGeom, false ) );
}
if ( info.getElementType( i ).isInteriorRing() ) {
LinearRing lr = getGeometryFactory().createLinearRing( cs );
holes.add( lr );
}
else {
if ( shell != null ) {
Polygon polygon = getGeometryFactory().createPolygon(
shell,
holes.toArray( new LinearRing[holes.size()] )
);
polygons.add( polygon );
shell = null;
}
shell = getGeometryFactory().createLinearRing( cs );
holes = new ArrayList<LinearRing>();
}
i += 1 + numCompounds;
}
if ( shell != null ) {
Polygon polygon = getGeometryFactory().createPolygon(
shell,
holes.toArray( new LinearRing[holes.size()] )
);
polygons.add( polygon );
}
MultiPolygon multiPolygon = getGeometryFactory().createMultiPolygon(
polygons.toArray( new Polygon[polygons.size()] )
);
return multiPolygon;
}
/**
* Gets the CoordinateSequence corresponding to a compound element.
*
* @param idxFirst the first sub-element of the compound element
* @param idxLast the last sub-element of the compound element
* @param SDOGeom the SDOGeometry that holds the compound element.
*
* @return
*/
private CoordinateSequence getCompoundCSeq(int idxFirst, int idxLast,
SDOGeometry SDOGeom) {
CoordinateSequence cs = null;
for ( int i = idxFirst; i <= idxLast; i++ ) {
// pop off the last element as it is added with the next
// coordinate sequence
if ( cs != null && cs.size() > 0 ) {
Coordinate[] coordinates = cs.toCoordinateArray();
Coordinate[] newCoordinates = new Coordinate[coordinates.length - 1];
System.arraycopy(
coordinates, 0, newCoordinates, 0,
coordinates.length - 1
);
cs = getGeometryFactory().getCoordinateSequenceFactory()
.create( newCoordinates );
}
cs = add( cs, getElementCSeq( i, SDOGeom, ( i < idxLast ) ) );
}
return cs;
}
/**
* Gets the CoordinateSequence corresponding to an element.
*
* @param i
* @param SDOGeom
*
* @return
*/
private CoordinateSequence getElementCSeq(int i, SDOGeometry SDOGeom,
boolean hasNextSE) {
ElementType type = SDOGeom.getInfo().getElementType( i );
Double[] elemOrdinates = extractOrdinatesOfElement(
i, SDOGeom,
hasNextSE
);
CoordinateSequence cs;
if ( type.isStraightSegment() ) {
cs = convertOrdinateArray( elemOrdinates, SDOGeom );
}
else if ( type.isArcSegment() || type.isCircle() ) {
Coordinate[] linearized = linearize(
elemOrdinates, SDOGeom
.getDimension(), SDOGeom.isLRSGeometry(), type.isCircle()
);
cs = getGeometryFactory().getCoordinateSequenceFactory().create(
linearized
);
}
else if ( type.isRect() ) {
cs = convertOrdinateArray( elemOrdinates, SDOGeom );
Coordinate ll = cs.getCoordinate( 0 );
Coordinate ur = cs.getCoordinate( 1 );
Coordinate lr = new Coordinate( ur.x, ll.y );
Coordinate ul = new Coordinate( ll.x, ur.y );
if ( type.isExteriorRing() ) {
cs = getGeometryFactory().getCoordinateSequenceFactory()
.create( new Coordinate[] { ll, lr, ur, ul, ll } );
}
else {
cs = getGeometryFactory().getCoordinateSequenceFactory()
.create( new Coordinate[] { ll, ul, ur, lr, ll } );
}
}
else {
throw new RuntimeException(
"Unexpected Element type in compound: "
+ type
);
}
return cs;
}
private CoordinateSequence add(CoordinateSequence seq1,
CoordinateSequence seq2) {
if ( seq1 == null ) {
return seq2;
}
if ( seq2 == null ) {
return seq1;
}
Coordinate[] c1 = seq1.toCoordinateArray();
Coordinate[] c2 = seq2.toCoordinateArray();
Coordinate[] c3 = new Coordinate[c1.length + c2.length];
System.arraycopy( c1, 0, c3, 0, c1.length );
System.arraycopy( c2, 0, c3, c1.length, c2.length );
return getGeometryFactory().getCoordinateSequenceFactory().create( c3 );
}
private Double[] extractOrdinatesOfElement(int element,
SDOGeometry SDOGeom, boolean hasNextSE) {
int start = SDOGeom.getInfo().getOrdinatesOffset( element );
if ( element < SDOGeom.getInfo().getSize() - 1 ) {
int end = SDOGeom.getInfo().getOrdinatesOffset( element + 1 );
// if this is a subelement of a compound geometry,
// the last point is the first point of
// the next subelement.
if ( hasNextSE ) {
end += SDOGeom.getDimension();
}
return SDOGeom.getOrdinates().getOrdinatesArray( start, end );
}
else {
return SDOGeom.getOrdinates().getOrdinatesArray( start );
}
}
private CoordinateSequence convertOrdinateArray(Double[] oordinates,
SDOGeometry SDOGeom) {
int dim = SDOGeom.getDimension();
Coordinate[] coordinates = new Coordinate[oordinates.length / dim];
int zDim = SDOGeom.getZDimension() - 1;
int lrsDim = SDOGeom.getLRSDimension() - 1;
for ( int i = 0; i < coordinates.length; i++ ) {
if ( dim == 2 ) {
coordinates[i] = new Coordinate(
oordinates[i * dim],
oordinates[i * dim + 1]
);
}
else if ( dim == 3 ) {
if ( SDOGeom.isLRSGeometry() ) {
coordinates[i] = MCoordinate.create2dWithMeasure(
oordinates[i * dim], // X
oordinates[i * dim + 1], // Y
oordinates[i * dim + lrsDim]
); // M
}
else {
coordinates[i] = new Coordinate(
oordinates[i * dim], // X
oordinates[i * dim + 1], // Y
oordinates[i * dim + zDim]
); // Z
}
}
else if ( dim == 4 ) {
// This must be an LRS Geometry
if ( !SDOGeom.isLRSGeometry() ) {
throw new HibernateException(
"4 dimensional Geometries must be LRS geometry"
);
}
coordinates[i] = MCoordinate.create3dWithMeasure(
oordinates[i
* dim], // X
oordinates[i * dim + 1], // Y
oordinates[i * dim + zDim], // Z
oordinates[i * dim + lrsDim]
); // M
}
}
return getGeometryFactory().getCoordinateSequenceFactory().create(
coordinates
);
}
/**
* Linearizes arcs and circles.
*
* @param arcOrdinates arc or circle coordinates
* @param dim coordinate dimension
* @param lrs whether this is an lrs geometry
* @param entireCirlce whether the whole arc should be linearized
*
* @return linearized interpolation of arcs or circle
*/
private Coordinate[] linearize(Double[] arcOrdinates, int dim, boolean lrs,
boolean entireCirlce) {
Coordinate[] linearizedCoords = new Coordinate[0];
// CoordDim is the dimension that includes only non-measure (X,Y,Z)
// ordinates in its value
int coordDim = lrs ? dim - 1 : dim;
// this only works with 2-Dimensional geometries, since we use
// JGeometry linearization;
if ( coordDim != 2 ) {
throw new IllegalArgumentException(
"Can only linearize 2D arc segments, but geometry is "
+ dim + "D."
);
}
int numOrd = dim;
while ( numOrd < arcOrdinates.length ) {
numOrd = numOrd - dim;
double x1 = arcOrdinates[numOrd++];
double y1 = arcOrdinates[numOrd++];
double m1 = lrs ? arcOrdinates[numOrd++] : Double.NaN;
double x2 = arcOrdinates[numOrd++];
double y2 = arcOrdinates[numOrd++];
double m2 = lrs ? arcOrdinates[numOrd++] : Double.NaN;
double x3 = arcOrdinates[numOrd++];
double y3 = arcOrdinates[numOrd++];
double m3 = lrs ? arcOrdinates[numOrd++] : Double.NaN;
Coordinate[] coords;
if ( entireCirlce ) {
coords = Circle.linearizeCircle( x1, y1, x2, y2, x3, y3 );
}
else {
coords = Circle.linearizeArc( x1, y1, x2, y2, x3, y3 );
}
// if this is an LRS geometry, fill the measure values into
// the linearized array
if ( lrs ) {
MCoordinate[] mcoord = new MCoordinate[coords.length];
int lastIndex = coords.length - 1;
mcoord[0] = MCoordinate.create2dWithMeasure( x1, y1, m1 );
mcoord[lastIndex] = MCoordinate.create2dWithMeasure( x3, y3, m3 );
// convert the middle coordinates to MCoordinate
for ( int i = 1; i < lastIndex; i++ ) {
mcoord[i] = MCoordinate.convertCoordinate( coords[i] );
// if we happen to split on the middle measure, then
// assign it
if ( Double.compare( mcoord[i].x, x2 ) == 0
&& Double.compare( mcoord[i].y, y2 ) == 0 ) {
mcoord[i].m = m2;
}
}
coords = mcoord;
}
// if this is not the first arcsegment, the first linearized
// point is already in linearizedArc, so disregard this.
int resultBegin = 1;
if ( linearizedCoords.length == 0 ) {
resultBegin = 0;
}
int destPos = linearizedCoords.length;
Coordinate[] tmpCoords = new Coordinate[linearizedCoords.length
+ coords.length - resultBegin];
System.arraycopy(
linearizedCoords, 0, tmpCoords, 0,
linearizedCoords.length
);
System.arraycopy(
coords, resultBegin, tmpCoords, destPos,
coords.length - resultBegin
);
linearizedCoords = tmpCoords;
}
return linearizedCoords;
}
}

View File

@ -0,0 +1,109 @@
/*
* $Id: SDOObjectMethod.java 268 2010-10-28 19:16:54Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.util.List;
import org.hibernate.QueryException;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.Type;
/**
* Special SQLFunction implementation for Oracle object methods
*
* @author Karel Maesen
*/
class SDOObjectMethod implements SQLFunction {
private final Type type;
private final String name;
public SDOObjectMethod(String name, Type type) {
this.type = type;
this.name = name;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#getReturnType(org.hibernate.type.Type,
* org.hibernate.engine.Mapping)
*/
public Type getReturnType(Type columnType, Mapping mapping)
throws QueryException {
return type == null ? columnType : type;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#hasArguments()
*/
public boolean hasArguments() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#hasParenthesesIfNoArguments()
*/
public boolean hasParenthesesIfNoArguments() {
return true;
}
public String getName() {
return this.name;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#render(java.util.List,
* org.hibernate.engine.SessionFactoryImplementor)
*/
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException {
StringBuffer buf = new StringBuffer();
if (args.isEmpty())
throw new QueryException(
"First Argument in arglist must be object to which method is applied");
buf.append(args.get(0)).append(".").append(name).append('(');
for (int i = 1; i < args.size(); i++) {
buf.append(args.get(i));
if (i < args.size() - 1) {
buf.append(", ");
}
}
return buf.append(')').toString();
}
}

View File

@ -0,0 +1,104 @@
/*
* $Id: SDOObjectProperty.java 268 2010-10-28 19:16:54Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.util.List;
import org.hibernate.QueryException;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.Type;
/**
* Special function for accessing a member variable of an Oracle Object
*
* @author Karel Maesen
*/
class SDOObjectProperty implements SQLFunction {
private final Type type;
private final String name;
public SDOObjectProperty(String name, Type type) {
this.type = type;
this.name = name;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#getReturnType(org.hibernate.type.Type,
* org.hibernate.engine.Mapping)
*/
public Type getReturnType(Type columnType, Mapping mapping)
throws QueryException {
return type == null ? columnType : type;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#hasArguments()
*/
public boolean hasArguments() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#hasParenthesesIfNoArguments()
*/
public boolean hasParenthesesIfNoArguments() {
return false;
}
public String getName() {
return this.name;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.dialect.function.SQLFunction#render(java.util.List,
* org.hibernate.engine.SessionFactoryImplementor)
*/
public String render(Type firstArgtype, List args, SessionFactoryImplementor factory)
throws QueryException {
StringBuffer buf = new StringBuffer();
if (args.isEmpty())
throw new QueryException(
"First Argument in arglist must be object of which property is queried");
buf.append(args.get(0)).append(".").append(name);
return buf.toString();
}
}

View File

@ -0,0 +1,37 @@
package org.hibernate.spatial.dialect.oracle;
import java.sql.SQLException;
import java.sql.Struct;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Jul 1, 2010
*/
class SDOPoint {
public double x = 0.0;
public double y = 0.0;
public double z = Double.NaN;
public SDOPoint(Struct struct) {
try {
Object[] data = struct.getAttributes();
this.x = ((Number) data[0]).doubleValue();
this.y = ((Number) data[1]).doubleValue();
if (data[2] != null) {
this.z = ((Number) data[1]).doubleValue();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public String toString() {
StringBuilder stb = new StringBuilder();
stb.append("(").append(x).append(",").append(y).append(",").append(
z).append(")");
return stb.toString();
}
}

View File

@ -0,0 +1,91 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import org.hibernate.spatial.dialect.oracle.criterion.OracleSpatialAggregate;
/**
* Provides Aggregate type spatial function interpretation
*/
class SpatialAggregate {
boolean _aggregateType;
String _aggregateSyntax;
private final String SDO_AGGR = "SDO_AGGR_";
SpatialAggregate() {
}
SpatialAggregate(int aggregation) {
String specificAggrSyntax;
switch (aggregation) {
case org.hibernate.spatial.SpatialAggregate.EXTENT:
specificAggrSyntax = "MBR";
_aggregateType = false;
break;
case OracleSpatialAggregate.LRS_CONCAT:
specificAggrSyntax = "LRS_CONCAT";
_aggregateType = true;
break;
case OracleSpatialAggregate.CENTROID:
specificAggrSyntax = "CENTROID";
_aggregateType = true;
break;
case OracleSpatialAggregate.CONCAT_LINES:
specificAggrSyntax = "CONCAT_LINES";
_aggregateType = false;
break;
case OracleSpatialAggregate.UNION:
specificAggrSyntax = "UNION";
_aggregateType = true;
break;
case OracleSpatialAggregate.CONVEXHULL:
specificAggrSyntax = "CONVEXHULL";
_aggregateType = true;
break;
default:
specificAggrSyntax = null;
break;
}
if (specificAggrSyntax != null) {
_aggregateSyntax = SDO_AGGR + specificAggrSyntax;
}
}
public boolean isAggregateType() {
return _aggregateType;
}
public String getAggregateSyntax() {
return _aggregateSyntax;
}
}

View File

@ -0,0 +1,20 @@
package org.hibernate.spatial.dialect.oracle;
import java.sql.Array;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Struct;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Jul 3, 2010
*/
interface SQLTypeFactory {
Struct createStruct(SDOGeometry geom, Connection conn) throws SQLException;
Array createElemInfoArray(ElemInfo elemInfo, Connection conn) throws SQLException;
Array createOrdinatesArray(Ordinates ordinates, Connection conn) throws SQLException;
}

View File

@ -0,0 +1,32 @@
package org.hibernate.spatial.dialect.oracle;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Jul 1, 2010
*/
enum TypeGeometry {
UNKNOWN_GEOMETRY(0), POINT(1), LINE(2), POLYGON(3), COLLECTION(4), MULTIPOINT(
5), MULTILINE(6), MULTIPOLYGON(7), SOLID(8), MULTISOLID(9);
private int gtype = 0;
TypeGeometry(int gtype) {
this.gtype = gtype;
}
int intValue() {
return this.gtype;
}
static TypeGeometry parse(int v) {
for (TypeGeometry gt : values()) {
if (gt.intValue() == v) {
return gt;
}
}
throw new RuntimeException("Value " + v
+ " isn't a valid TypeGeometry value");
}
}

View File

@ -0,0 +1,77 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.util.List;
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.Type;
/**
* An HQL function that is implemented using Oracle's OGC compliance
* package.
*/
class WrappedOGCFunction extends StandardSQLFunction {
private final boolean[] geomArrays;
/**
* @param name function name
* @param type return type of the function
* @param geomArrays indicates which argument places are occupied by
* sdo_geometries
*/
WrappedOGCFunction(final String name, final Type type,
final boolean[] geomArrays) {
super(name, type);
this.geomArrays = geomArrays;
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
buf.append("MDSYS.").append(getName()).append("(");
for (int i = 0; i < args.size(); i++) {
if (i > 0) {
buf.append(",");
}
if (geomArrays[i]) {
buf.append("MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(").append(
args.get(i)).append(")");
} else {
buf.append(args.get(i));
}
}
buf.append(")");
return (getType().getReturnedClass() == Geometry.class) ? buf
.append(".geom").toString() : buf.toString();
}
}

View File

@ -0,0 +1,48 @@
/**
* $Id: OracleSpatialAggregate.java 103 2008-08-15 10:45:29Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle.criterion;
import org.hibernate.spatial.SpatialAggregate;
/**
* Defines types of OracleSpatialAggregate
*/
public interface OracleSpatialAggregate extends SpatialAggregate {
public static int LRS_CONCAT = 100;
public static int CENTROID = 101;
public static int CONCAT_LINES = 102;
public static int UNION = 103;
public static int CONVEXHULL = 104;
}

View File

@ -0,0 +1,86 @@
/**
* $Id: OracleSpatialProjection.java 268 2010-10-28 19:16:54Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle.criterion;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.SimpleProjection;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.type.Type;
/**
* Template class for Spatial Projections
*
* @author Tom Acree
*/
public class OracleSpatialProjection extends SimpleProjection {
private static final long serialVersionUID = 1L;
private final String propertyName;
private final int aggregate;
public OracleSpatialProjection(int aggregate, String propertyName) {
this.propertyName = propertyName;
this.aggregate = aggregate;
}
public String toSqlString(Criteria criteria, int position,
CriteriaQuery criteriaQuery) throws HibernateException {
SessionFactoryImplementor factory = criteriaQuery.getFactory();
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria,
this.propertyName);
Dialect dialect = factory.getDialect();
if (dialect instanceof SpatialDialect) {
SpatialDialect seDialect = (SpatialDialect) dialect;
return new StringBuffer(seDialect.getSpatialAggregateSQL(
columns[0], this.aggregate)).append(" y").append(position)
.append("_").toString();
} else {
throw new IllegalStateException(
"Dialect must be spatially enabled dialect");
}
}
public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
return new Type[]{criteriaQuery.getType(criteria, this.propertyName)};
}
public String toString() {
return aggregate + "(" + propertyName + ")";
}
}

View File

@ -0,0 +1,60 @@
/**
* $Id: OracleSpatialProjections.java 67 2007-12-16 16:41:55Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle.criterion;
/**
* Factory class for SpationProjection functions *
*
* @author Tom Acree
*/
public final class OracleSpatialProjections {
private OracleSpatialProjections() {
}
public static OracleSpatialProjection concatLrs(String propertyName) {
return new OracleSpatialProjection(OracleSpatialAggregate.LRS_CONCAT,
propertyName);
}
public static OracleSpatialProjection centroid(String propertyName) {
return new OracleSpatialProjection(OracleSpatialAggregate.CENTROID,
propertyName);
}
public static OracleSpatialProjection concatLines(String propertyName) {
return new OracleSpatialProjection(OracleSpatialAggregate.CONCAT_LINES,
propertyName);
}
public static OracleSpatialProjection projection(int projection,
String propertyName) {
return new OracleSpatialProjection(projection, propertyName);
}
}

View File

@ -0,0 +1,204 @@
/**
* $Id: OracleSpatialRestrictions.java 268 2010-10-28 19:16:54Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle.criterion;
import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.engine.spi.TypedValue;
/**
* A static factory class for creating <code>Criterion</code> instances that
* correspond to Oracle Spatial "native" spatial operators.
*
* @author Karel Maesen
*/
public class OracleSpatialRestrictions {
@SuppressWarnings("serial")
public static Criterion SDOFilter(String propertyName, Geometry geom,
SDOParameterMap param) {
return new OracleSpatialCriterion(propertyName, geom, param) {
@Override
public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, this.propertyName);
StringBuilder sql = new StringBuilder("SDO_FILTER(");
sql.append(columns[0]).append(",").append("?");
if (param != null && !param.isEmpty()) {
sql.append(",").append(param.toQuotedString());
}
sql.append(") = 'TRUE'");
return sql.toString();
}
};
}
@SuppressWarnings("serial")
public static Criterion SDOFilter(String propertyName, Geometry geom,
Double minResolution, Double maxResolution) {
if (minResolution == null && maxResolution == null) {
return SDOFilter(propertyName, geom, null);
} else {
SDOParameterMap param = new SDOParameterMap();
param.setMinResolution(minResolution);
param.setMaxResolution(maxResolution);
return SDOFilter(propertyName, geom, param);
}
}
@SuppressWarnings("serial")
public static Criterion SDONN(String propertyName, Geometry geom,
Double distance, Integer numResults, String unit) {
if (distance == null && numResults == null && unit == null) {
return SDONN(propertyName, geom, null);
} else {
SDOParameterMap param = new SDOParameterMap();
param.setDistance(distance);
param.setSdoNumRes(numResults);
param.setUnit(unit);
return SDONN(propertyName, geom, param);
}
}
@SuppressWarnings("serial")
public static Criterion SDONN(String propertyName, Geometry geom,
SDOParameterMap param) {
return new OracleSpatialCriterion(propertyName, geom, param) {
@Override
public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, this.propertyName);
StringBuilder sql = new StringBuilder("SDO_NN(");
sql.append(columns[0]).append(",").append("?");
if (param != null && !param.isEmpty()) {
sql.append(",").append(param.toQuotedString());
}
sql.append(") = 'TRUE'");
return sql.toString();
}
};
}
@SuppressWarnings("serial")
public static Criterion SDORelate(String propertyName, Geometry geom,
SDOParameterMap param) {
return new OracleSpatialCriterion(propertyName, geom, param) {
@Override
public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, this.propertyName);
StringBuilder sql = new StringBuilder("SDO_RELATE(");
sql.append(columns[0]).append(",").append("?");
if (param != null && !param.isEmpty()) {
sql.append(",").append(param.toQuotedString());
}
sql.append(") = 'TRUE'");
return sql.toString();
}
};
}
@SuppressWarnings("serial")
public static Criterion SDORelate(String propertyName, Geometry geom,
RelationshipMask[] mask, Double minResolution, Double maxResolution) {
SDOParameterMap param = new SDOParameterMap();
param.setMask(RelationshipMask.booleanCombination(mask));
param.setMinResolution(minResolution);
param.setMaxResolution(maxResolution);
return SDORelate(propertyName, geom, param);
}
@SuppressWarnings("serial")
public static Criterion SDOWithinDistance(String propertyName,
Geometry geom, SDOParameterMap param) {
return new OracleSpatialCriterion(propertyName, geom, param) {
@Override
public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, this.propertyName);
StringBuilder sql = new StringBuilder("SDO_WITHIN_DISTANCE(");
sql.append(columns[0]).append(",").append("?");
if (param != null && !param.isEmpty()) {
sql.append(",").append(param.toQuotedString());
}
sql.append(") = 'TRUE'");
return sql.toString();
}
};
}
public static Criterion SDOWithinDistance(String propertyName,
Geometry geom, Double distance, SDOParameterMap param) {
if (param == null) {
param = new SDOParameterMap();
}
param.setDistance(distance);
return SDOWithinDistance(propertyName, geom, param);
}
}
abstract class OracleSpatialCriterion implements Criterion {
protected String propertyName;
protected Geometry value;
protected SDOParameterMap param;
public OracleSpatialCriterion(String propertyName, Geometry value,
SDOParameterMap param) {
this.propertyName = propertyName;
this.value = value;
this.param = param;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.criterion.Criterion#getTypedValues(org.hibernate.Criteria,
* org.hibernate.criterion.CriteriaQuery)
*/
public TypedValue[] getTypedValues(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[]{criteriaQuery.getTypedValue(criteria,
propertyName, value)};
}
abstract public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException;
}

View File

@ -0,0 +1,45 @@
/**
* $Id: RelationshipMask.java 103 2008-08-15 10:45:29Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
* Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle.criterion;
public enum RelationshipMask {
TOUCH, OVERLAPBYDISJOINT, OVERLAPBYINTERSECT, EQUAL, INSIDE, COVEREDBY, CONTAINS, COVERS, ANYINTERACT, ON;
public static String booleanCombination(RelationshipMask[] masks) {
String strMask = null;
for (RelationshipMask relationshipMask : masks) {
if (strMask == null) {
strMask = relationshipMask.toString();
} else {
strMask += "+" + relationshipMask.toString();
}
}
return strMask;
}
}

View File

@ -0,0 +1,192 @@
/**
* $Id: SDOParameterMap.java 67 2007-12-16 16:41:55Z maesenka $
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007 Geovise BVBA
*
* This work was partially supported by the European Commission,
* under the 6th Framework Programme, contract IST-2-004688-STP.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle.criterion;
import java.util.HashMap;
import java.util.Map;
/**
* This class represents the parameters that can be passed into Oracle's Spatial
* Operators
*
* @author Karel Maesen
*
*/
public class SDOParameterMap {
public static final String DISTANCE = "distance";
public static final String SDO_BATCH_SIZE = "sdo_batch_size";
public static final String SDO_NUM_RES = "sdo_num_res";
public static final String UNIT = "unit";
public static final String MIN_RESOLUTION = "min_resolution";
public static final String MAX_RESOLUTION = "max_resolution";
public static final String MASK = "mask";
public static final String QUERYTYPE = "querytype";
private Map<String, Object> params = new HashMap<String, Object>();
public SDOParameterMap() {
}
public boolean isEmpty() {
return this.params.isEmpty();
}
public void setDistance(Double distance) {
if (distance != null)
params.put(DISTANCE, distance);
}
public Double getDistance() {
return (Double) params.get(DISTANCE);
}
public void removeDistance() {
params.remove(DISTANCE);
}
public void setSdoBatchSize(Integer size) {
if (size != null)
params.put(SDO_BATCH_SIZE, size);
}
public Integer getSdoBatchSize() {
return (Integer) params.get(SDO_BATCH_SIZE);
}
public void removeSdoBatchSize() {
params.remove(SDO_BATCH_SIZE);
}
public void setSdoNumRes(Integer size) {
if (size != null)
params.put(SDO_NUM_RES, size);
}
public Integer getSdoNumRes() {
return (Integer) params.get(SDO_NUM_RES);
}
public void removeSdoNumRes() {
params.remove(SDO_NUM_RES);
}
public void setUnit(String unit) {
if (unit != null)
this.params.put(UNIT, unit);
}
public String getUnit() {
return (String) this.params.get(UNIT);
}
public void removeUnit() {
this.params.remove(UNIT);
}
public void setMaxResolution(Double res) {
if (res != null)
params.put(MAX_RESOLUTION, res);
}
public Double getMaxResolution() {
return (Double) params.get(MAX_RESOLUTION);
}
public void removeMaxResolution() {
params.remove(MAX_RESOLUTION);
}
public void setMinResolution(Double res) {
if (res != null)
params.put(MIN_RESOLUTION, res);
}
public Double getMinResolution() {
return (Double) params.get(MIN_RESOLUTION);
}
public void removeMinResolution() {
params.remove(MIN_RESOLUTION);
}
public void setMask(String mask) {
if (mask != null)
this.params.put(MASK, mask);
}
public String getMask() {
return (String) this.params.get(MASK);
}
public void removeMask() {
this.params.remove(MASK);
}
public void setQueryType(String queryType) {
if (queryType != null)
this.params.put(QUERYTYPE, queryType);
}
public void setQueryTypeToFilter() {
this.params.put(QUERYTYPE, "FILTER");
}
public String getQueryType() {
return (String) this.params.get(QUERYTYPE);
}
public void removeQueryType() {
this.params.remove(QUERYTYPE);
}
public String toQuotedString() {
StringBuilder stb = new StringBuilder();
if (params.isEmpty()) {
return "";
}
stb.append('\'');
for (String paramName : params.keySet()) {
if (params.get(paramName) == null)
continue;
stb.append(paramName).append("=").append(params.get(paramName))
.append(" ");
}
stb.deleteCharAt(stb.length() - 1);
stb.append('\'');
return stb.toString();
}
}

View File

@ -0,0 +1,8 @@
package org.hibernate.spatial.dialect.sqlserver;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/23/11
*/
public class SqlServer2008GeometryValueBinder {
}

View File

@ -0,0 +1,8 @@
package org.hibernate.spatial.dialect.sqlserver;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/23/11
*/
public class SqlServer2008GeometryValueExtractor {
}

View File

@ -3,6 +3,7 @@ package org.hibernate.spatial.integration;
import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Configuration;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.integrator.spi.Integrator; import org.hibernate.integrator.spi.Integrator;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry; import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.hibernate.spatial.GeometryType; import org.hibernate.spatial.GeometryType;
@ -17,6 +18,11 @@ public class SpatialIntegrator implements Integrator {
sessionFactory.getTypeResolver().registerTypeOverride( GeometryType.INSTANCE ); sessionFactory.getTypeResolver().registerTypeOverride( GeometryType.INSTANCE );
} }
@Override
public void integrate(MetadataImplementor metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
metadata.getTypeResolver().registerTypeOverride( GeometryType.INSTANCE );
}
@Override @Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
//do nothing. //do nothing.

View File

@ -91,7 +91,6 @@ public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCa
} }
public String getBaseForMappings() { public String getBaseForMappings() {
// return "org/hibernatespatial/test/";
return ""; return "";
} }

View File

@ -56,9 +56,9 @@ public class TestSupportFactories {
// "org.hibernatespatial.mysql.MySQLSpatialInnoDBDialect".equals(canonicalName)) { // "org.hibernatespatial.mysql.MySQLSpatialInnoDBDialect".equals(canonicalName)) {
// return "org.hibernatespatial.mysql.MySQLTestSupport"; // return "org.hibernatespatial.mysql.MySQLTestSupport";
// } // }
// if ("org.hibernatespatial.oracle.OracleSpatial10gDialect".equals(canonicalName)) { if ( "org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect".equals( canonicalName ) ) {
// return "org.hibernatespatial.oracle.OracleSDOTestSupport"; return "org.hibernate.spatial.dialect.oracle.OracleSDOTestSupport";
// } }
throw new IllegalArgumentException( "Dialect not known in test suite" ); throw new IllegalArgumentException( "Dialect not known in test suite" );
} }

View File

@ -0,0 +1,234 @@
package org.hibernatespatial.oracle;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
/**
* This class hides the actual Connection implementation class.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: Jun 30, 2010
*/
public class JDBCConnectionProxy implements Connection {
private final Connection delegate;
public JDBCConnectionProxy(Connection conn) {
this.delegate = conn;
}
public <T> T unwrap(Class<T> iface) throws SQLException {
return delegate.unwrap( iface );
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return delegate.isWrapperFor( iface );
}
public Statement createStatement() throws SQLException {
return delegate.createStatement();
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
return delegate.prepareStatement( sql );
}
public CallableStatement prepareCall(String sql) throws SQLException {
return delegate.prepareCall( sql );
}
public String nativeSQL(String sql) throws SQLException {
return delegate.nativeSQL( sql );
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
delegate.setAutoCommit( autoCommit );
}
public boolean getAutoCommit() throws SQLException {
return delegate.getAutoCommit();
}
public void commit() throws SQLException {
delegate.commit();
}
public void rollback() throws SQLException {
delegate.rollback();
}
public void close() throws SQLException {
delegate.close();
}
public boolean isClosed() throws SQLException {
return delegate.isClosed();
}
public DatabaseMetaData getMetaData() throws SQLException {
return delegate.getMetaData();
}
public void setReadOnly(boolean readOnly) throws SQLException {
delegate.setReadOnly( readOnly );
}
public boolean isReadOnly() throws SQLException {
return delegate.isReadOnly();
}
public void setCatalog(String catalog) throws SQLException {
delegate.setCatalog( catalog );
}
public String getCatalog() throws SQLException {
return delegate.getCatalog();
}
public void setTransactionIsolation(int level) throws SQLException {
delegate.setTransactionIsolation( level );
}
public int getTransactionIsolation() throws SQLException {
return delegate.getTransactionIsolation();
}
public SQLWarning getWarnings() throws SQLException {
return delegate.getWarnings();
}
public void clearWarnings() throws SQLException {
delegate.clearWarnings();
}
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return delegate.createStatement( resultSetType, resultSetConcurrency );
}
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
return delegate.prepareStatement( sql, resultSetType, resultSetConcurrency );
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return delegate.prepareCall( sql, resultSetType, resultSetConcurrency );
}
public Map<String, Class<?>> getTypeMap() throws SQLException {
return delegate.getTypeMap();
}
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
delegate.setTypeMap( map );
}
public void setHoldability(int holdability) throws SQLException {
delegate.setHoldability( holdability );
}
public int getHoldability() throws SQLException {
return delegate.getHoldability();
}
public Savepoint setSavepoint() throws SQLException {
return delegate.setSavepoint();
}
public Savepoint setSavepoint(String name) throws SQLException {
return delegate.setSavepoint( name );
}
public void rollback(Savepoint savepoint) throws SQLException {
delegate.rollback( savepoint );
}
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
delegate.releaseSavepoint( savepoint );
}
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
return delegate.createStatement( resultSetType, resultSetConcurrency, resultSetHoldability );
}
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
return delegate.prepareStatement( sql, resultSetType, resultSetConcurrency, resultSetHoldability );
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
return delegate.prepareCall( sql, resultSetType, resultSetConcurrency, resultSetHoldability );
}
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return delegate.prepareStatement( sql, autoGeneratedKeys );
}
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return delegate.prepareStatement( sql, columnIndexes );
}
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return delegate.prepareStatement( sql, columnNames );
}
public Clob createClob() throws SQLException {
return delegate.createClob();
}
public Blob createBlob() throws SQLException {
return delegate.createBlob();
}
public NClob createNClob() throws SQLException {
return delegate.createNClob();
}
public SQLXML createSQLXML() throws SQLException {
return delegate.createSQLXML();
}
public boolean isValid(int timeout) throws SQLException {
return delegate.isValid( timeout );
}
public void setClientInfo(String name, String value) throws SQLClientInfoException {
delegate.setClientInfo( name, value );
}
public void setClientInfo(Properties properties) throws SQLClientInfoException {
delegate.setClientInfo( properties );
}
public String getClientInfo(String name) throws SQLException {
return delegate.getClientInfo( name );
}
public Properties getClientInfo() throws SQLException {
return delegate.getClientInfo();
}
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return delegate.createArrayOf( typeName, elements );
}
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return delegate.createStruct( typeName, attributes );
}
}

View File

@ -0,0 +1,37 @@
package org.hibernate.spatial.dialect.oracle;
import org.hibernate.cfg.Configuration;
import org.hibernate.spatial.test.AbstractExpectationsFactory;
import org.hibernate.spatial.test.DataSourceUtils;
import org.hibernate.spatial.test.SQLExpressionTemplate;
import org.hibernate.spatial.test.TestData;
import org.hibernate.spatial.test.TestSupport;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: Oct 22, 2010
*/
public class OracleSDOTestSupport extends TestSupport {
@Override
public TestData createTestData(BaseCoreFunctionalTestCase testcase) {
return TestData.fromFile( "test-sdo-geometry-data-set-2D.xml", new SDOTestDataReader() );
}
@Override
public AbstractExpectationsFactory createExpectationsFactory(DataSourceUtils dataSourceUtils) {
return new SDOGeometryExpectationsFactory( dataSourceUtils );
}
@Override
public SQLExpressionTemplate getSQLExpressionTemplate() {
return new SDOGeometryExpressionTemplate();
}
@Override
public DataSourceUtils createDataSourceUtil(Configuration configuration) {
this.configuration = configuration;
return new SDODataSourceUtils( driver(), url(), user(), passwd(), getSQLExpressionTemplate() );
}
}

View File

@ -0,0 +1,74 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.sql.SQLException;
import org.hibernate.spatial.test.DataSourceUtils;
import org.hibernate.spatial.test.SQLExpressionTemplate;
public class SDODataSourceUtils extends DataSourceUtils {
public SDODataSourceUtils(String jdbcDriver, String jdbcUrl, String jdbcUser, String jdbcPass, SQLExpressionTemplate sqlExpressionTemplate) {
super( jdbcDriver, jdbcUrl, jdbcUser, jdbcPass, sqlExpressionTemplate );
}
@Override
public void afterCreateSchema() {
super.afterCreateSchema();
try {
setGeomMetaDataTo2D();
createIndex();
}
catch ( SQLException e ) {
throw new RuntimeException( e );
}
}
private void createIndex() throws SQLException {
String sql = "create index idx_spatial_geomtest on geomtest (geom) indextype is mdsys.spatial_index";
executeStatement( sql );
}
private void setGeomMetaDataTo2D() throws SQLException {
String sql1 = "delete from user_sdo_geom_metadata where TABLE_NAME = 'GEOMTEST'";
String sql2 = "insert into user_sdo_geom_metadata values (" +
" 'GEOMTEST'," +
" 'geom'," +
" SDO_DIM_ARRAY(" +
" SDO_DIM_ELEMENT('X', -180, 180, 0.00001)," +
" SDO_DIM_ELEMENT('Y', -90, 90, 0.00001)" +
" )," +
" 4326)";
executeStatement( sql1 );
executeStatement( sql2 );
}
}

View File

@ -0,0 +1,270 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import org.hibernate.spatial.test.AbstractExpectationsFactory;
import org.hibernate.spatial.test.DataSourceUtils;
import org.hibernate.spatial.test.NativeSQLStatement;
/**
* Expectations factory for Oracle 10g (SDOGeometry).
*
* @Author Karel Maesen, Geovise BVBA
*/
public class SDOGeometryExpectationsFactory extends AbstractExpectationsFactory {
private final SDOGeometryValueExtractor decoder = new SDOGeometryValueExtractor();
public SDOGeometryExpectationsFactory(DataSourceUtils dataSourceUtils) {
super( dataSourceUtils );
}
@Override
protected NativeSQLStatement createNativeTouchesStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Touch(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Touch(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeOverlapsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Overlap(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Overlap(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeRelateStatement(Geometry geom, String matrix) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Relate(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326), '" + matrix + "') from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Relate(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326), '" + matrix + "') = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeDwithinStatement(Point geom, double distance) {
throw new UnsupportedOperationException();
}
@Override
protected NativeSQLStatement createNativeIntersectsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Intersects(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Intersects(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeFilterStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, 1 from GEOMTEST t where SDO_FILTER(t.GEOM, MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326).GEOM) = 'TRUE' ",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeDistanceStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Distance(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeDimensionSQL() {
return createNativeSQLStatement(
"select ID, MDSYS.OGC_DIMENSION(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM( T.GEOM)) FROM GEOMTEST T"
);
}
@Override
protected NativeSQLStatement createNativeBufferStatement(Double distance) {
return createNativeSQLStatement(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Buffer(?).GEOM from GEOMTEST T where t.GEOM.SDO_SRID = 4326",
new Double[] { distance }
);
}
@Override
protected NativeSQLStatement createNativeConvexHullStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Union(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)).ST_ConvexHull().GEOM from GEOMTEST T where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeIntersectionStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Intersection(MDSYS.ST_GEOMETRY.FROM_WKT(?,4326)).GEOM FROM GEOMTEST t where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeDifferenceStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Difference(MDSYS.ST_GEOMETRY.FROM_WKT(?,4326)).GEOM FROM GEOMTEST t where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeSymDifferenceStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_SymmetricDifference(MDSYS.ST_GEOMETRY.FROM_WKT(?,4326)).GEOM FROM GEOMTEST t where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeGeomUnionStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Union(MDSYS.ST_GEOMETRY.FROM_WKT(?,4326)).GEOM FROM GEOMTEST t where t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeAsTextStatement() {
return createNativeSQLStatement( "select t.ID, t.GEOM.GET_WKT() FROM GEOMTEST T" );
}
@Override
protected NativeSQLStatement createNativeSridStatement() {
return createNativeSQLStatement( "SELECT t.ID, t.GEOM.SDO_SRID FROM GEOMTEST t" );
}
@Override
protected NativeSQLStatement createNativeIsSimpleStatement() {
return createNativeSQLStatement(
"SELECT t.ID, MDSYS.OGC_ISSIMPLE(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)) FROM GEOMTEST t where MDSYS.OGC_ISSIMPLE(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)) = 1"
);
}
@Override
protected NativeSQLStatement createNativeIsEmptyStatement() {
return createNativeSQLStatement(
"SELECT t.ID, MDSYS.OGC_ISEMPTY(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)) FROM GEOMTEST t"
);
}
@Override
protected NativeSQLStatement createNativeIsNotEmptyStatement() {
return createNativeSQLStatement(
"SELECT t.ID, CASE MDSYS.OGC_ISEMPTY(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)) WHEN 0 THEN 1 ELSE 0 END FROM GEOMTEST t"
);
}
@Override
protected NativeSQLStatement createNativeBoundaryStatement() {
return createNativeSQLStatement(
"SELECT t.ID, MDSYS.OGC_BOUNDARY(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)).GEOM FROM GEOMTEST t"
);
}
@Override
protected NativeSQLStatement createNativeEnvelopeStatement() {
return createNativeSQLStatement(
"SELECT t.ID, MDSYS.OGC_ENVELOPE(MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM)).GEOM FROM GEOMTEST t"
);
}
@Override
protected NativeSQLStatement createNativeAsBinaryStatement() {
return createNativeSQLStatement( "select t.ID, t.GEOM.GET_WKB() FROM GEOMTEST T" );
}
@Override
protected NativeSQLStatement createNativeGeometryTypeStatement() {
return createNativeSQLStatement(
"select t.id, CASE t.geom.Get_GType() WHEN 1 THEN 'POINT' WHEN 2 THEN 'LINESTRING' WHEN 3 THEN 'POLYGON' WHEN 5 THEN 'MULTIPOINT' WHEN 6 THEN 'MULTILINE' WHEN 7 THEN 'MULTIPOLYGON' END from GEOMTEST t"
);
}
@Override
protected NativeSQLStatement createNativeWithinStatement(Geometry testPolygon) {
return createNativeSQLStatementAllWKTParams(
"select t.id, mdsys.OGC_WITHIN( MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM), MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where mdsys.OGC_WITHIN( MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM), MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
testPolygon.toText()
);
}
@Override
protected NativeSQLStatement createNativeEqualsStatement(Geometry testPolygon) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Equals(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Equals(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
testPolygon.toText()
);
}
@Override
protected NativeSQLStatement createNativeCrossesStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Cross(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Cross(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeContainsStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Contains(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Contains(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeDisjointStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Disjoint(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) from GEOMTEST T where MDSYS.ST_GEOMETRY.FROM_SDO_GEOM(t.GEOM).ST_Disjoint(MDSYS.ST_GEOMETRY.FROM_WKT(?, 4326)) = 1 and t.GEOM.SDO_SRID = 4326",
geom.toText()
);
}
@Override
protected NativeSQLStatement createNativeTransformStatement(int epsg) {
return createNativeSQLStatement(
"select t.id, MDSYS.SDO_CS.transform(t.geom," + epsg + ") from GeomTest t where t.geom.SDO_SRID = 4326"
);
}
@Override
protected NativeSQLStatement createNativeHavingSRIDStatement(int srid) {
return createNativeSQLStatement( "select t.id, 1 from GeomTest t where t.geom.SDO_SRID = " + srid );
}
@Override
protected Geometry decode(Object o) {
return decoder.toJTS( o );
}
}

View File

@ -0,0 +1,39 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import org.hibernate.spatial.test.SQLExpressionTemplate;
import org.hibernate.spatial.test.TestDataElement;
public class SDOGeometryExpressionTemplate implements SQLExpressionTemplate {
final String SQL_TEMPLATE = "insert into geomtest values (%d, '%s', %s)";
public String toInsertSql(TestDataElement testDataElement) {
SDOTestDataElement sdoTestDataElement = (SDOTestDataElement) testDataElement;
return String.format( SQL_TEMPLATE, sdoTestDataElement.id, sdoTestDataElement.type, sdoTestDataElement.sdo );
}
}

View File

@ -0,0 +1,47 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import org.hibernate.spatial.test.TestDataElement;
/**
* A specialised subclass for SDOGeometry test objects
* <p/>
* Oracle 10g WKT support is limited to 2D geometries, and there is
* no method of specifying SRID. That is why we here add the equivalent SDO expression
* that can be used by the TestData
*/
public class SDOTestDataElement extends TestDataElement {
public final String sdo;
public SDOTestDataElement(int id, String type, String wkt, int srid, String sdo) {
super( id, type, wkt, srid );
this.sdo = sdo;
}
}

View File

@ -0,0 +1,50 @@
/*
* $Id:$
*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for geographic data.
*
* Copyright © 2007-2010 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, visit: http://www.hibernatespatial.org/
*/
package org.hibernate.spatial.dialect.oracle;
import java.util.List;
import org.dom4j.Element;
import org.hibernate.spatial.test.TestDataElement;
import org.hibernate.spatial.test.TestDataReader;
public class SDOTestDataReader extends TestDataReader {
@Override
protected void addDataElement(Element element, List<TestDataElement> testDataElements) {
int id = Integer.valueOf( element.selectSingleNode( "id" ).getText() );
String type = element.selectSingleNode( "type" ).getText();
String wkt = element.selectSingleNode( "wkt" ).getText();
int srid = Integer.valueOf( element.selectSingleNode( "srid" ).getText() );
String sdo = element.selectSingleNode( "sdo" ).getText();
TestDataElement testDataElement = new SDOTestDataElement( id, type, wkt, srid, sdo );
testDataElements.add( testDataElement );
}
}

View File

@ -21,11 +21,19 @@
# 51 Franklin Street, Fifth Floor # 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301 USA # Boston, MA 02110-1301 USA
# #
hibernate.dialect org.hibernate.spatial.dialect.postgis.PostgisDialect
hibernate.connection.driver_class org.postgresql.Driver #hibernate.dialect org.hibernate.spatial.dialect.postgis.PostgisDialect
hibernate.connection.url jdbc:postgresql://localhost:5432:hibbrtru #hibernate.connection.driver_class org.postgresql.Driver
hibernate.connection.username hibbrtru #hibernate.connection.url jdbc:postgresql://localhost:5432:hibbrtru
hibernate.connection.password hibbrtru #hibernate.connection.username hibbrtru
#hibernate.connection.password hibbrtru
hibernate.dialect org.hibernate.spatial.dialect.oracle.OracleSpatial10gDialect
hibernate.connection.driver_class oracle.jdbc.driver.OracleDriver
hibernate.connection.url jdbc:oracle:thin:@oracle.geovise.com/ORCL
hibernate.connection.username hbs
hibernate.connection.password hbs
hibernate.connection.pool_size 5 hibernate.connection.pool_size 5

View File

@ -0,0 +1,27 @@
#
# $Id: org.hibernatespatial.oracle.OracleSpatial10gDialect.properties 268 2010-10-28 19:16:54Z maesenka $
#
# This file is part of Hibernate Spatial, an extension to the
# hibernate ORM solution for geographic data.
#
# Copyright © 2007-2010 Geovise BVBA
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# For more information, visit: http://www.hibernatespatial.org/
#
OGC_STRICT=true
CONNECTION-FINDER=org.hibernate.spatial.dialect.oracle.DefaultConnectionFinder

View File

@ -0,0 +1,282 @@
<!--
~ $Id:$
~
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for geographic data.
~
~ Copyright © 2007-2010 Geovise BVBA
~
~ This library is free software; you can redistribute it and/or
~ modify it under the terms of the GNU Lesser General Public
~ License as published by the Free Software Foundation; either
~ version 2.1 of the License, or (at your option) any later version.
~
~ This library is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this library; if not, write to the Free Software
~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
~
~ For more information, visit: http://www.hibernatespatial.org/
-->
<!--
Special test data set for testing HQL/SpatialRestrictions in Oracle Spatial 10g (SDOGeometry).
The OGC functions only work on 2D geometries, there must be an index, and all SRIDs must be equal
-->
<TestData>
<Element>
<id>1</id>
<type>POINT</type>
<sdo>SDO_GEOMETRY(2001, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10.0, 5.0))</sdo>
<wkt>POINT(10 5)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>2</id>
<type>POINT</type>
<sdo>SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(52.25, 2.53, NULL), NULL, NULL)</sdo>
<wkt>POINT(52.25 2.53)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>5</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0, 20.0 15.0)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2002, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 20.0, 15.0))</sdo>
</Element>
<Element>
<id>6</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2002, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 20.0, 15.0, 30.3,
22.4, 10.0, 30.0 ))
</sdo>
</Element>
<Element>
<id>11</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0))</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2006, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1,5,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 20.0,
15.0,25.0,30.0, 30.0,20.0))
</sdo>
</Element>
<Element>
<id>12</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0), (40.0 20.0, 42.0 18.0, 43.0 16.0, 40 14.0))
</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2006, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1,9,2,1),
SDO_ORDINATE_ARRAY(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))
</sdo>
</Element>
<Element>
<id>16</id>
<type>POLYGON</type>
<wkt>POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0) )</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARRAY(0,0,0,10,10,10,10,0,0,0))
</sdo>
</Element>
<Element>
<id>18</id>
<type>POLYGON</type>
<wkt>POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 5, 5 5,5 2, 2 2))</wkt>
<sdo>SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1, 11, 2003, 1), SDO_ORDINATE_ARRAY(0, 0, 0,
10, 10, 10, 10, 0, 0, 0, 2, 2, 2, 5, 5, 5, 5, 2, 2, 2))
</sdo>
<srid>4326</srid>
</Element>
<Element>
<id>19</id>
<type>POLYGON</type>
<wkt>POLYGON( (110 110, 110 120, 120 120, 120 110, 110 110) )</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARRAY(110,110,110,120,120,120,120,110,110,110))
</sdo>
</Element>
<Element>
<id>20</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100, 120 140, 130 134, 105 100)) )</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2007, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1, 9, 1003, 1), SDO_ORDINATE_ARRAY(10, 20, 30,
40, 44, 50, 10, 20, 105, 100, 120, 140, 130, 134, 105, 100))
</sdo>
</Element>
<Element>
<id>22</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON(( (0 0, 0 50, 50 50, 50 0, 0 0), (10 10, 10 20, 20 20, 20 10, 10 10) ),((105 100, 120 140, 130
134, 105 100)))
</wkt>
<sdo>SDO_GEOMETRY(2007, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1, 11, 2003, 1, 21, 1003, 1),
SDO_ORDINATE_ARRAY(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))
</sdo>
<srid>4326</srid>
</Element>
<Element>
<id>25</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2, 25 5, 30 3)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2005, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(21,2,25,5,30,3))</sdo>
</Element>
<Element>
<id>26</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2005, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(21,2))</sdo>
</Element>
<!--
<Element>
<id>30</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>31</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0)))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>32</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0),(1 1, 2 1, 2 2, 1 2,
1 1)))
</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>33</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION( MULTIPOINT(21 2, 25 5, 30 3), MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100,
120 140, 130 134, 105 100)) ), MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0)))
</wkt>
<srid>4326</srid>
</Element>
-->
<!-- storing empty geometries is unsupported in the current version -->
<!--
<Element>
<id>34</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), POINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>35</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>36</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), GEOMETRYCOLLECTION EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>37</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), POLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>38</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTILINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>39</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTIPOINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>40</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTIPOLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>50</id>
<type>POINT</type>
<wkt>POINT EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>51</id>
<type>LINESTRING</type>
<wkt>LINESTRING EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>52</id>
<type>POLYGON</type>
<wkt>POLYGON EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>53</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>54</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>55</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>56</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION EMPTY</wkt>
<srid>4326</srid>
</Element>
-->
</TestData>

View File

@ -0,0 +1,401 @@
<!--
~ $Id:$
~
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for geographic data.
~
~ Copyright © 2007-2010 Geovise BVBA
~
~ This library is free software; you can redistribute it and/or
~ modify it under the terms of the GNU Lesser General Public
~ License as published by the Free Software Foundation; either
~ version 2.1 of the License, or (at your option) any later version.
~
~ This library is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this library; if not, write to the Free Software
~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
~
~ For more information, visit: http://www.hibernatespatial.org/
-->
<!--
Special test data set for testing store/retrieve in Oracle Spatial 10g (SDOGeometry)
-->
<TestData>
<Element>
<id>1</id>
<type>POINT</type>
<sdo>SDO_GEOMETRY(2001, 0, SDO_POINT_TYPE(10, 5, NULL), NULL, NULL)</sdo>
<wkt>POINT(10 5)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>2</id>
<type>POINT</type>
<sdo>SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(52.25, 2.53, NULL), NULL, NULL)</sdo>
<wkt>POINT(52.25 2.53)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>3</id>
<type>POINT</type>
<sdo>SDO_GEOMETRY(3001, 31370, SDO_POINT_TYPE(150000, 200000, 500), NULL, NULL)</sdo>
<wkt>POINT(150000 200000 500)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>4</id>
<type>POINT</type>
<sdo>SDO_GEOMETRY(4401, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10.0, 2.0, 1.0, 3.0))</sdo>
<wkt>POINT(10.0 2.0 1.0 3.0)</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>5</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0, 20.0 15.0)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2002, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 20.0, 15.0))</sdo>
</Element>
<Element>
<id>6</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2002, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 20.0, 15.0, 30.3,
22.4, 10.0, 30.0 ))
</sdo>
</Element>
<Element>
<id>7</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0 0.0, 20.0 15.0 3.0)</wkt>
<sdo>SDO_GEOMETRY(3002, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 0.0, 20.0, 15, 3.0
))
</sdo>
<srid>4326</srid>
</Element>
<Element>
<id>8</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0 0.0 0.0, 20.0 15.0 3.0 1.0)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(4402, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 0.0, 0.0, 20.0,
15, 3.0, 1.0))
</sdo>
</Element>
<Element>
<id>9</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0 1, 20.0 15.0 2, 30.3 22.4 5, 10 30.0 2)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(3002, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 1.0,20.0, 15, 2.0,
30.3, 22.4, 5.0, 10.0, 30.0, 2.0))
</sdo>
</Element>
<Element>
<id>10</id>
<type>LINESTRING</type>
<wkt>LINESTRING(10.0 5.0 1 1, 20.0 15.0 2 3, 30.3 22.4 5 10, 10 30.0 2 12)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(4402, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(10.0,5.0,1,1, 20.0, 15.0, 2,
3, 30.3, 22.4, 5, 10, 10, 30.0, 2, 12))
</sdo>
</Element>
<Element>
<id>11</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0))</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2006, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1,5,2,1), SDO_ORDINATE_ARRAY(10.0, 5.0, 20.0,
15.0,25.0,30.0, 30.0,20.0))
</sdo>
</Element>
<Element>
<id>12</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0, 20.0 15.0, 30.3 22.4, 10 30.0), (40.0 20.0, 42.0 18.0, 43.0 16.0, 40 14.0))
</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2006, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1,9,2,1),
SDO_ORDINATE_ARRAY(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))
</sdo>
</Element>
<Element>
<id>13</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0 1.0, 20.0 15.0 2.0, 30.3 22.4 1.0, 10 30.0 1.0),(40.0 20.0 0.0, 42.0 18.0 1.0,
43.0 16.0 2.0, 40 14.0 3.0))
</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(3006, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1,13,2,1),
SDO_ORDINATE_ARRAY(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))
</sdo>
</Element>
<Element>
<id>14</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0 1.0 0.0, 20.0 15.0 2.0 0.0, 30.3 22.4 1.0 1.0, 10 30.0 1.0 2.0),(40.0 20.0 0.0
3.0, 42.0 18.0 1.0 4.0, 43.0 16.0 2.0 5.0, 40 14.0 3.0 6.0))
</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(4406, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1,17,2,1),
SDO_ORDINATE_ARRAY(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))
</sdo>
</Element>
<Element>
<id>15</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING((10.0 5.0 1.0 0.0, 20.0 15.0 2.0 0.0, 30.3 22.4 1.0 1.0, 10 30.0 1.0 2.0))</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(4406, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,2,1),
SDO_ORDINATE_ARRAY(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))
</sdo>
</Element>
<Element>
<id>16</id>
<type>POLYGON</type>
<wkt>POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0) )</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARRAY(0,0,0,10,10,10,10,0,0,0))
</sdo>
</Element>
<Element>
<id>17</id>
<type>POLYGON</type>
<wkt>POLYGON( (0 0 0, 0 10 1, 10 10 1, 10 0 1, 0 0 0) )</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(3003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARRAY(0,0,0,0,10,1,10,10,1,10,0,1,0,0,0))
</sdo>
</Element>
<Element>
<id>18</id>
<type>POLYGON</type>
<wkt>POLYGON( (0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 2 5, 5 5,5 2, 2 2))</wkt>
<sdo>SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1, 11, 2003, 1), SDO_ORDINATE_ARRAY(0, 0, 0,
10, 10, 10, 10, 0, 0, 0, 2, 2, 2, 5, 5, 5, 5, 2, 2, 2))
</sdo>
<srid>4326</srid>
</Element>
<Element>
<id>19</id>
<type>POLYGON</type>
<wkt>POLYGON( (110 110, 110 120, 120 120, 120 110, 110 110) )</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARRAY(110,110,110,120,120,120,120,110,110,110))
</sdo>
</Element>
<Element>
<id>20</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100, 120 140, 130 134, 105 100)) )</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2007, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1, 9, 1003, 1), SDO_ORDINATE_ARRAY(10, 20, 30,
40, 44, 50, 10, 20, 105, 100, 120, 140, 130, 134, 105, 100))
</sdo>
</Element>
<Element>
<id>21</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON( ((10 20 1, 30 40 2, 44 50 2, 10 20 1)), ((105 100 0, 120 140 10, 130 134 20, 105 100 0)) )
</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(3007, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1, 13, 1003, 1),
SDO_ORDINATE_ARRAY(10,20,1,30,40,2,44,50,2,10,20,1,105,100,0,120,140,10,130,134,20,105,100,0))
</sdo>
</Element>
<Element>
<id>22</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON(( (0 0, 0 50, 50 50, 50 0, 0 0), (10 10, 10 20, 20 20, 20 10, 10 10) ),((105 100, 120 140, 130
134, 105 100)))
</wkt>
<sdo>SDO_GEOMETRY(2007, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1, 11, 2003, 1, 21, 1003, 1),
SDO_ORDINATE_ARRAY(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))
</sdo>
<srid>4326</srid>
</Element>
<Element>
<id>25</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2, 25 5, 30 3)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2005, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(21,2,25,5,30,3))</sdo>
</Element>
<Element>
<id>26</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(2005, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(21,2))</sdo>
</Element>
<Element>
<id>27</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2 1, 25 5 2, 30 3 5)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(3005, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(21,2,1,25,5,2,30,3,5))</sdo>
</Element>
<Element>
<id>28</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT(21 2 1 0, 25 5 2 4, 30 3 5 2)</wkt>
<srid>4326</srid>
<sdo>SDO_GEOMETRY(4405, 4326, NULL, SDO_ELEM_INFO_ARRAY(1,1,1),
SDO_ORDINATE_ARRAY(21,2,1,0,25,5,2,4,30,3,5,2))
</sdo>
</Element>
<!--
<Element>
<id>30</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>31</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0)))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>32</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING(4 2, 5 3), POLYGON((0 0, 3 0, 3 3,0 3, 0 0),(1 1, 2 1, 2 2, 1 2,
1 1)))
</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>33</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION( MULTIPOINT(21 2, 25 5, 30 3), MULTIPOLYGON( ((10 20, 30 40, 44 50, 10 20)), ((105 100,
120 140, 130 134, 105 100)) ), MULTILINESTRING((10.0 5.0, 20.0 15.0),( 25.0 30.0, 30.0 20.0)))
</wkt>
<srid>4326</srid>
</Element>
-->
<!-- storing empty geometries is unsupported in the current version -->
<!--
<Element>
<id>34</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), POINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>35</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), LINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>36</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), GEOMETRYCOLLECTION EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>37</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), POLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>38</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTILINESTRING EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>39</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTIPOINT EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>40</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION(POINT(4 0), MULTIPOLYGON EMPTY, LINESTRING(4 2, 5 3))</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>50</id>
<type>POINT</type>
<wkt>POINT EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>51</id>
<type>LINESTRING</type>
<wkt>LINESTRING EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>52</id>
<type>POLYGON</type>
<wkt>POLYGON EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>53</id>
<type>MULTIPOINT</type>
<wkt>MULTIPOINT EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>54</id>
<type>MULTILINESTRING</type>
<wkt>MULTILINESTRING EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>55</id>
<type>MULTIPOLYGON</type>
<wkt>MULTIPOLYGON EMPTY</wkt>
<srid>4326</srid>
</Element>
<Element>
<id>56</id>
<type>GEOMETRYCOLLECTION</type>
<wkt>GEOMETRYCOLLECTION EMPTY</wkt>
<srid>4326</srid>
</Element>
-->
</TestData>