HHH-6512 - Refactors Oracle support.
This commit is contained in:
parent
dbfeb16e43
commit
2738d0f5c7
|
@ -26,7 +26,6 @@ dependencies {
|
|||
compile(project(':hibernate-core'))
|
||||
compile([group: 'postgresql', name: 'postgresql', version: '8.4-701.jdbc4'])
|
||||
compile([group: 'org.geolatte', name: 'geolatte-geom', version: '1.0-SNAPSHOT'])
|
||||
// compile([group: 'com.vividsolutions', name: 'jts', version: '1.12'])
|
||||
|
||||
compile(libraries.dom4j) {
|
||||
transitive = false
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package org.hibernate.spatial.dialect.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>
|
||||
* <p>Implementations should be thread-safe, and have a default (no-args) constructor.</p>
|
||||
*
|
||||
* @author Karel Maesen
|
||||
*/
|
||||
public interface ConnectionFinder extends
|
||||
FinderStrategy<Connection, Connection> {
|
||||
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package org.hibernate.spatial.dialect.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 static final Class<?> ORACLE_CONNECTION_CLASS;
|
||||
|
||||
static {
|
||||
try {
|
||||
ORACLE_CONNECTION_CLASS = Class.forName( "oracle.jdbc.driver.OracleConnection" );
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
throw new HibernateException( "Can't find Oracle JDBC Driver on classpath." );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection find(Connection con) throws FinderException {
|
||||
if ( con == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( ORACLE_CONNECTION_CLASS.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 );
|
||||
final 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."
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.dialect.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[] elemInfo) {
|
||||
this.triplets = elemInfo;
|
||||
}
|
||||
|
||||
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) {
|
||||
final int etype = this.triplets[i * 3 + 1].intValue();
|
||||
final int interp = this.triplets[i * 3 + 2].intValue();
|
||||
return ElementType.parseType( etype, interp );
|
||||
}
|
||||
|
||||
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) {
|
||||
final 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() ) {
|
||||
final 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.dialect.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;
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.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, ...).
|
||||
* <p/>
|
||||
* 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 final Class<?> datumClass;
|
||||
private final Method structDescriptorCreator;
|
||||
private final Method arrayDescriptorCreator;
|
||||
private final Constructor<?> numberConstructor;
|
||||
private final Constructor<?> arrayConstructor;
|
||||
private final Constructor<?> structConstructor;
|
||||
private final ConnectionFinder connectionFinder;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param connectionFinder the {@code ConnectionFinder} the use for retrieving the {@code OracleConnection} instance.
|
||||
*/
|
||||
public OracleJDBCTypeFactory(ConnectionFinder connectionFinder) {
|
||||
if ( connectionFinder == null ) {
|
||||
throw new HibernateException( "ConnectionFinder cannot be null" );
|
||||
}
|
||||
this.connectionFinder = connectionFinder;
|
||||
Object[] obj = findDescriptorCreator( "oracle.sql.StructDescriptor" );
|
||||
Class<?> structDescriptorClass = (Class<?>) obj[0];
|
||||
structDescriptorCreator = (Method) obj[1];
|
||||
obj = findDescriptorCreator( "oracle.sql.ArrayDescriptor" );
|
||||
Class<?> arrayDescriptorClass = (Class<?>) obj[0];
|
||||
arrayDescriptorCreator = (Method) obj[1];
|
||||
datumClass = findClass( "oracle.sql.Datum" );
|
||||
Class<?> numberClass = findClass( "oracle.sql.NUMBER" );
|
||||
Class<?> arrayClass = findClass( "oracle.sql.ARRAY" );
|
||||
Class<?> 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 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 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 Object[] findDescriptorCreator(String className) {
|
||||
try {
|
||||
final Class clazz = ReflectHelper.classForName( className );
|
||||
final 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)'" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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 );
|
||||
}
|
||||
|
||||
final Object structDescriptor = createStructDescriptor( SDOGeometry.getTypeName(), oracleConnection );
|
||||
final 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 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array createElemInfoArray(ElemInfo elemInfo, Connection conn) {
|
||||
final Object arrayDescriptor = createArrayDescriptor( ElemInfo.TYPE_NAME, conn );
|
||||
return createArray( arrayDescriptor, conn, elemInfo.getElements() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array createOrdinatesArray(Ordinates ordinates, Connection conn) throws SQLException {
|
||||
final 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 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,545 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package org.hibernate.spatial.dialect.oracle;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.dialect.Oracle10gDialect;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.spi.TypeContributions;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.spatial.GeolatteGeometryType;
|
||||
import org.hibernate.spatial.HibernateSpatialConfiguration;
|
||||
import org.hibernate.spatial.JTSGeometryType;
|
||||
import org.hibernate.spatial.SpatialAnalysis;
|
||||
import org.hibernate.spatial.SpatialDialect;
|
||||
import org.hibernate.spatial.SpatialFunction;
|
||||
import org.hibernate.spatial.SpatialRelation;
|
||||
import org.hibernate.spatial.dialect.oracle.criterion.OracleSpatialAggregate;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Spatial Dialect for Oracle10g databases.
|
||||
*
|
||||
* @author Karel Maesen
|
||||
*/
|
||||
public class OracleSpatial10gDialect extends Oracle10gDialect implements
|
||||
SpatialDialect, Serializable {
|
||||
|
||||
private final boolean isOgcStrict;
|
||||
private final ConnectionFinder connectionFinder;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs the dialect with a default configuration
|
||||
*/
|
||||
public OracleSpatial10gDialect() {
|
||||
this( new HibernateSpatialConfiguration() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the dialect with the specified configuration
|
||||
*
|
||||
* @param config the {@code HibernateSpatialConfiguration} that configures this dialect.
|
||||
*/
|
||||
public OracleSpatial10gDialect(HibernateSpatialConfiguration config) {
|
||||
super();
|
||||
this.isOgcStrict = config.isOgcStrictMode();
|
||||
final ConnectionFinder finder = config.getConnectionFinder();
|
||||
this.connectionFinder = finder == null ? new DefaultConnectionFinder() : finder;
|
||||
|
||||
|
||||
// register geometry type
|
||||
registerColumnType( 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" ) );
|
||||
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", 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", SpatialAnalysis.BUFFER ) );
|
||||
registerFunction( "convexhull", new SpatialAnalysisFunction( "convexhull", SpatialAnalysis.CONVEXHULL ) );
|
||||
registerFunction( "difference", new SpatialAnalysisFunction( "difference", SpatialAnalysis.DIFFERENCE ) );
|
||||
registerFunction( "intersection", new SpatialAnalysisFunction( "intersection", SpatialAnalysis.INTERSECTION ) );
|
||||
registerFunction(
|
||||
"symdifference",
|
||||
new SpatialAnalysisFunction( "symdifference", SpatialAnalysis.SYMDIFFERENCE )
|
||||
);
|
||||
registerFunction( "geomunion", new SpatialAnalysisFunction( "union", 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", false, OracleSpatialAggregate.EXTENT ) );
|
||||
|
||||
//other common functions
|
||||
|
||||
registerFunction( "transform", new StandardSQLFunction( "SDO_CS.TRANSFORM" ) );
|
||||
|
||||
// Oracle specific Aggregate functions
|
||||
registerFunction(
|
||||
"centroid",
|
||||
new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.CENTROID )
|
||||
);
|
||||
registerFunction(
|
||||
"concat_lines",
|
||||
new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.CONCAT_LINES )
|
||||
);
|
||||
registerFunction(
|
||||
"aggr_convexhull",
|
||||
new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.CONVEXHULL )
|
||||
);
|
||||
registerFunction(
|
||||
"aggr_union",
|
||||
new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.UNION )
|
||||
);
|
||||
registerFunction(
|
||||
"lrs_concat",
|
||||
new SpatialAggregationFunction( "lrsconcat", false, OracleSpatialAggregate.LRS_CONCAT )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
super.contributeTypes(
|
||||
typeContributions,
|
||||
serviceRegistry
|
||||
);
|
||||
|
||||
final SDOGeometryTypeDescriptor sdoGeometryTypeDescriptor = new SDOGeometryTypeDescriptor(
|
||||
new OracleJDBCTypeFactory(
|
||||
this.connectionFinder
|
||||
)
|
||||
);
|
||||
|
||||
typeContributions.contributeType( new GeolatteGeometryType( sdoGeometryTypeDescriptor ) );
|
||||
typeContributions.contributeType( new JTSGeometryType( sdoGeometryTypeDescriptor ) );
|
||||
|
||||
}
|
||||
|
||||
String getNativeSpatialRelateSQL(String arg1, String arg2, int spatialRelation) {
|
||||
String mask = "";
|
||||
boolean negate = false;
|
||||
switch ( spatialRelation ) {
|
||||
case SpatialRelation.INTERSECTS:
|
||||
mask = "ANYINTERACT";
|
||||
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
|
||||
+ ")"
|
||||
);
|
||||
}
|
||||
final StringBuffer buffer = new StringBuffer( "CASE SDO_RELATE(" ).append( arg1 )
|
||||
.append( "," )
|
||||
.append( arg2 )
|
||||
.append( ",'mask=" + mask + "') " );
|
||||
if ( !negate ) {
|
||||
buffer.append( " WHEN 'TRUE' THEN 1 ELSE 0 END" );
|
||||
}
|
||||
else {
|
||||
buffer.append( " WHEN 'TRUE' THEN 0 ELSE 1 END" );
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
String getOGCSpatialRelateSQL(String arg1, String arg2, int spatialRelation) {
|
||||
final 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();
|
||||
|
||||
}
|
||||
|
||||
String getNativeSpatialAggregateSQL(String arg1, int aggregation) {
|
||||
final StringBuffer aggregateFunction = new StringBuffer();
|
||||
final SpatialAggregate sa = new SpatialAggregate( aggregation );
|
||||
|
||||
if ( sa.getAggregateSyntax() == null ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unknown Spatial Aggregation ("
|
||||
+ aggregation + ")."
|
||||
);
|
||||
}
|
||||
|
||||
aggregateFunction.append( sa.getAggregateSyntax() );
|
||||
|
||||
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( ")" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpatialFilterExpression(String columnName) {
|
||||
final StringBuffer buffer = new StringBuffer( "SDO_FILTER(" );
|
||||
buffer.append( columnName );
|
||||
buffer.append( ",?) = 'TRUE' " );
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
|
||||
String sql = ( isOGCStrict() ?
|
||||
getOGCSpatialRelateSQL( columnName, "?", spatialRelation ) :
|
||||
getNativeSpatialRelateSQL( columnName, "?", spatialRelation ) ) + " = 1";
|
||||
sql += " and " + columnName + " is not null";
|
||||
return sql;
|
||||
}
|
||||
|
||||
String getSpatialAnalysisSQL(List args, int spatialAnalysisFunction, boolean useFilter) {
|
||||
return isOGCStrict() ? getOGCSpatialAnalysisSQL( args, spatialAnalysisFunction ) : getNativeSpatialAnalysisSQL(
|
||||
args,
|
||||
spatialAnalysisFunction
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpatialAggregateSQL(String columnName, int spatialAggregateFunction) {
|
||||
return getNativeSpatialAggregateSQL( columnName, spatialAggregateFunction );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDWithinSQL(String columnName) {
|
||||
return "SDO_WITHIN_DISTANCE (" + columnName + ",?, ?) = 'TRUE' ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHavingSridSQL(String columnName) {
|
||||
return String.format( " (MDSYS.ST_GEOMETRY(%s).ST_SRID() = ?)", columnName );
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
final 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 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports whether this dialect is in OGC_STRICT mode or not.
|
||||
*
|
||||
* This method is for testing purposes.
|
||||
*
|
||||
* @return true if in OGC_STRICT mode, false otherwise
|
||||
*/
|
||||
public boolean isOGCStrict() {
|
||||
return isOgcStrict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the ConnectionFinder used by this Dialect (or rather its associated TypeDescriptor).
|
||||
*
|
||||
* This method is mainly used for testing purposes.
|
||||
*
|
||||
* @return the ConnectionFinder in use
|
||||
*/
|
||||
public ConnectionFinder getConnectionFinder() {
|
||||
return connectionFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFiltering() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(SpatialFunction function) {
|
||||
return ( getFunctions().get( function.toString() ) != null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the OGC astext function for HQL.
|
||||
*/
|
||||
private static class AsTextFunction extends StandardSQLFunction {
|
||||
|
||||
private AsTextFunction() {
|
||||
super( "astext", StandardBasicTypes.STRING );
|
||||
}
|
||||
|
||||
public String render(Type firstArgumentType, final List args, final SessionFactoryImplementor factory) {
|
||||
final 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"
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private SpatialAnalysisFunction(String name, int analysis) {
|
||||
this( name, null, analysis );
|
||||
}
|
||||
|
||||
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
|
||||
return isOGCStrict() ? getSpatialAnalysisSQL(
|
||||
args, this.analysis,
|
||||
false
|
||||
) : getNativeSpatialAnalysisSQL( args, analysis );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SpatialAggregationFunction extends StandardSQLFunction {
|
||||
|
||||
private final int aggregation;
|
||||
|
||||
private SpatialAggregationFunction(String name, boolean isProjection, int aggregation) {
|
||||
super( name );
|
||||
this.aggregation = aggregation;
|
||||
}
|
||||
|
||||
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
|
||||
return getNativeSpatialAggregateSQL(
|
||||
(String) args.get( 0 ),
|
||||
this.aggregation
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.dialect.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 {
|
||||
final 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) {
|
||||
final Double[] a = new Double[endPosition - startPosition];
|
||||
System.arraycopy( this.ordinates, startPosition - 1, a, 0, a.length );
|
||||
return a;
|
||||
}
|
||||
|
||||
public Double[] getOrdinatesArray(int startPosition) {
|
||||
final 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) {
|
||||
final 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.dialect.oracle;
|
||||
|
||||
/**
|
||||
* @author Karel Maesen, Geovise BVBA
|
||||
* creation-date: Jun 30, 2010
|
||||
*/
|
||||
class SDOGType {
|
||||
|
||||
private int dimension = 2;
|
||||
|
||||
private int lrsDimension;
|
||||
|
||||
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) {
|
||||
final int dim = v / 1000;
|
||||
v -= dim * 1000;
|
||||
final int lrsDim = v / 100;
|
||||
v -= lrsDim * 100;
|
||||
final TypeGeometry typeGeometry = TypeGeometry.parse( v );
|
||||
return new SDOGType( dim, lrsDim, typeGeometry );
|
||||
}
|
||||
|
||||
public static SDOGType parse(Object datum) {
|
||||
|
||||
try {
|
||||
final int v = ( (Number) datum ).intValue();
|
||||
return parse( v );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Integer.toString( this.intValue() );
|
||||
}
|
||||
}
|
|
@ -1,347 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.dialect.oracle;
|
||||
|
||||
import java.sql.Array;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Struct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Karel Maesen, Geovise BVBA
|
||||
* creation-date: Jun 30, 2010
|
||||
*/
|
||||
|
||||
class SDOGeometry {
|
||||
|
||||
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 "()";
|
||||
}
|
||||
final int length = java.lang.reflect.Array.getLength( array );
|
||||
final 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 The SDO_geometries to join into an SDO Geometry Collection
|
||||
*
|
||||
* @return The SDO Collection Geometry
|
||||
*/
|
||||
public static SDOGeometry join(SDOGeometry[] sdoElements) {
|
||||
final SDOGeometry sdoCollection = new SDOGeometry();
|
||||
if ( sdoElements == null || sdoElements.length == 0 ) {
|
||||
sdoCollection.setGType( new SDOGType( 2, 0, TypeGeometry.COLLECTION ) );
|
||||
}
|
||||
else {
|
||||
final SDOGeometry firstElement = sdoElements[0];
|
||||
final int dim = firstElement.getGType().getDimension();
|
||||
final int lrsDim = firstElement.getGType().getLRSDimension();
|
||||
sdoCollection.setGType( new SDOGType( dim, lrsDim, TypeGeometry.COLLECTION ) );
|
||||
int ordinatesOffset = 1;
|
||||
for ( int i = 0; i < sdoElements.length; i++ ) {
|
||||
final ElemInfo element = sdoElements[i].getInfo();
|
||||
final Double[] ordinates = sdoElements[i].getOrdinates().getOrdinateArray();
|
||||
if ( element != null && element.getSize() > 0 ) {
|
||||
final int shift = ordinatesOffset - element.getOrdinatesOffset( 0 );
|
||||
shiftOrdinateOffset( element, shift );
|
||||
sdoCollection.addElement( element );
|
||||
sdoCollection.addOrdinates( ordinates );
|
||||
ordinatesOffset += ordinates.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sdoCollection;
|
||||
}
|
||||
|
||||
private static void shiftOrdinateOffset(ElemInfo elemInfo, int offset) {
|
||||
for ( int i = 0; i < elemInfo.getSize(); i++ ) {
|
||||
final 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
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static SDOGeometry load(Struct struct) {
|
||||
|
||||
Object[] data;
|
||||
try {
|
||||
data = struct.getAttributes();
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
|
||||
final 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 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;
|
||||
}
|
||||
|
||||
private void setSRID(Object datum) {
|
||||
if ( datum == null ) {
|
||||
this.srid = 0;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.srid = ( (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() ) {
|
||||
final int numCompounds = info.getNumCompounds( i );
|
||||
i += 1 + numCompounds;
|
||||
}
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
final 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 ) {
|
||||
final List<SDOGeometry> elements = new ArrayList<SDOGeometry>();
|
||||
int i = 0;
|
||||
while ( i < this.getNumElements() ) {
|
||||
final 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;
|
||||
}
|
||||
final SDOGeometry elemGeom = new SDOGeometry();
|
||||
final SDOGType elemGtype = deriveGTYPE( this.getInfo().getElementType( i ), this );
|
||||
elemGeom.setGType( elemGtype );
|
||||
elemGeom.setSRID( this.getSRID() );
|
||||
final ElemInfo elemInfo = new ElemInfo( this.getInfo().getElement( i ) );
|
||||
shiftOrdinateOffset( elemInfo, -elemInfo.getOrdinatesOffset( 0 ) + 1 );
|
||||
elemGeom.setInfo( elemInfo );
|
||||
final int startPosition = this.getInfo().getOrdinatesOffset( i );
|
||||
Ordinates elemOrdinates = null;
|
||||
if ( next < this.getNumElements() ) {
|
||||
final 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 };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,7 @@ package org.hibernate.spatial.dialect.oracle;
|
|||
|
||||
import java.sql.Types;
|
||||
|
||||
import org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory;
|
||||
import org.hibernate.type.descriptor.ValueBinder;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
|
|
@ -21,22 +21,10 @@
|
|||
|
||||
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.geolatte.geom.Geometry;
|
||||
import org.geolatte.geom.codec.db.oracle.Encoders;
|
||||
import org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory;
|
||||
import org.geolatte.geom.codec.db.oracle.SDOGeometry;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.spatial.helper.FinderException;
|
||||
import org.hibernate.type.descriptor.ValueBinder;
|
||||
|
@ -44,12 +32,18 @@ import org.hibernate.type.descriptor.WrapperOptions;
|
|||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
* @author Karel Maesen, Geovise BVBA
|
||||
* creation-date: 8/22/11
|
||||
*/
|
||||
class SDOGeometryValueBinder<J> implements ValueBinder<J> {
|
||||
|
||||
private static final String SQL_TYPE_NAME = "MDSYS.SDO_GEOMETRY";
|
||||
|
||||
private final OracleJDBCTypeFactory typeFactory;
|
||||
private final JavaTypeDescriptor<J> javaTypeDescriptor;
|
||||
|
@ -62,11 +56,11 @@ class SDOGeometryValueBinder<J> implements ValueBinder<J> {
|
|||
@Override
|
||||
public void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException {
|
||||
if ( value == null ) {
|
||||
st.setNull( index, Types.STRUCT, SDOGeometry.getTypeName() );
|
||||
st.setNull( index, Types.STRUCT, SQL_TYPE_NAME );
|
||||
}
|
||||
else {
|
||||
final Geometry jtsGeom = javaTypeDescriptor.unwrap( value, Geometry.class, options );
|
||||
final Object dbGeom = toNative( jtsGeom, st.getConnection() );
|
||||
final Geometry geometry = javaTypeDescriptor.unwrap( value, Geometry.class, options );
|
||||
final Object dbGeom = toNative( geometry, st.getConnection() );
|
||||
st.setObject( index, dbGeom );
|
||||
}
|
||||
}
|
||||
|
@ -75,345 +69,20 @@ class SDOGeometryValueBinder<J> implements ValueBinder<J> {
|
|||
return typeFactory.createStruct( geom, conn );
|
||||
}
|
||||
|
||||
private Object toNative(Geometry jtsGeom, Connection connection) {
|
||||
final SDOGeometry geom = convertJTSGeometry( jtsGeom );
|
||||
if ( geom != null ) {
|
||||
try {
|
||||
return 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) {
|
||||
final SDOGeometry[] sdoElements = new SDOGeometry[collection.getNumGeometries()];
|
||||
for ( int i = 0; i < collection.getNumGeometries(); i++ ) {
|
||||
final Geometry geom = collection.getGeometryN( i );
|
||||
sdoElements[i] = convertJTSGeometry( geom );
|
||||
}
|
||||
final SDOGeometry ccollect = SDOGeometry.join( sdoElements );
|
||||
ccollect.setSRID( collection.getSRID() );
|
||||
return ccollect;
|
||||
}
|
||||
|
||||
private SDOGeometry convertJTSMultiPolygon(MultiPolygon multiPolygon) {
|
||||
final int dim = getCoordDimension( multiPolygon );
|
||||
final int lrsPos = getCoordinateLrsPosition( multiPolygon );
|
||||
final 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 {
|
||||
final 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) {
|
||||
final int dim = getCoordDimension( lineString );
|
||||
final int lrsPos = getCoordinateLrsPosition( lineString );
|
||||
final boolean isLrs = lrsPos > 0;
|
||||
final Double[] ordinates = convertCoordinates( lineString.getCoordinates(), dim, isLrs );
|
||||
final SDOGeometry geom = new SDOGeometry();
|
||||
geom.setGType( new SDOGType( dim, lrsPos, TypeGeometry.LINE ) );
|
||||
geom.setSRID( lineString.getSRID() );
|
||||
final 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) {
|
||||
final int dim = getCoordDimension( multiPoint );
|
||||
final int lrsDim = getCoordinateLrsPosition( multiPoint );
|
||||
final boolean isLrs = ( lrsDim != 0 );
|
||||
final SDOGeometry geom = new SDOGeometry();
|
||||
geom.setGType( new SDOGType( dim, lrsDim, TypeGeometry.MULTIPOINT ) );
|
||||
geom.setSRID( multiPoint.getSRID() );
|
||||
final 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) {
|
||||
final int dim = getCoordDimension( jtsGeom );
|
||||
final int lrsDim = getCoordinateLrsPosition( jtsGeom );
|
||||
final boolean isLrs = ( lrsDim != 0 );
|
||||
|
||||
final Double[] coord = convertCoordinates( jtsGeom.getCoordinates(), dim, isLrs );
|
||||
final SDOGeometry geom = new SDOGeometry();
|
||||
geom.setGType( new SDOGType( dim, lrsDim, TypeGeometry.POINT ) );
|
||||
geom.setSRID( jtsGeom.getSRID() );
|
||||
final 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) {
|
||||
final int dim = getCoordDimension( polygon );
|
||||
final int lrsPos = getCoordinateLrsPosition( polygon );
|
||||
final 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) {
|
||||
final int numInteriorRings = polygon.getNumInteriorRing();
|
||||
final 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) {
|
||||
final int dim = getCoordDimension( multiLineString );
|
||||
final int lrsDim = getCoordinateLrsPosition( multiLineString );
|
||||
final boolean isLrs = ( lrsDim != 0 );
|
||||
final SDOGeometry geom = new SDOGeometry();
|
||||
geom.setGType( new SDOGType( dim, lrsDim, TypeGeometry.MULTILINE ) );
|
||||
geom.setSRID( multiLineString.getSRID() );
|
||||
final 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) {
|
||||
final Double[] no = convertCoordinates( coordinates, dim, isLrs );
|
||||
final 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 ( isLrs ) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
if ( dim > 4 ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Dim parameter value cannot be greater than 4"
|
||||
);
|
||||
}
|
||||
final Double[] converted = new Double[coordinates.length * dim];
|
||||
for ( int i = 0; i < coordinates.length; i++ ) {
|
||||
final Coordinate c = 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] = 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
|
||||
final Coordinate c = 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) {
|
||||
final 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++ ) {
|
||||
final Coordinate cs = ar[i];
|
||||
ar[i] = ar[ar.length - 1 - i];
|
||||
ar[ar.length - 1 - i] = cs;
|
||||
}
|
||||
return ar;
|
||||
}
|
||||
private Object toNative(Geometry geom, Connection connection) {
|
||||
final SDOGeometry sdoGeom = Encoders.encode(geom);
|
||||
if (geom != null) {
|
||||
try {
|
||||
return store(sdoGeom, 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 " + geom.getClass().getSimpleName() + " to Oracle STRUCT not supported");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,22 +25,11 @@ import java.sql.CallableStatement;
|
|||
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.GeometryFactory;
|
||||
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.spatial.jts.Circle;
|
||||
import org.geolatte.geom.Geometry;
|
||||
import org.geolatte.geom.codec.db.oracle.Decoders;
|
||||
import org.geolatte.geom.codec.db.oracle.SDOGeometry;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.BasicExtractor;
|
||||
|
@ -57,9 +46,6 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
|||
*/
|
||||
public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
|
||||
|
||||
private static GeometryFactory geometryFactory = new GeometryFactory();
|
||||
|
||||
|
||||
/**
|
||||
* Creates instance
|
||||
*
|
||||
|
@ -73,25 +59,19 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
|
|||
@Override
|
||||
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
|
||||
final Object geomObj = rs.getObject( name );
|
||||
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
|
||||
return getJavaDescriptor().wrap( convert(geomObj), options );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
|
||||
final Object geomObj = statement.getObject( index );
|
||||
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
|
||||
return getJavaDescriptor().wrap( convert(geomObj), options );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
|
||||
final Object geomObj = statement.getObject( name );
|
||||
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
|
||||
}
|
||||
|
||||
//TODO Clean up below this point
|
||||
|
||||
protected GeometryFactory getGeometryFactory() {
|
||||
return geometryFactory;
|
||||
return getJavaDescriptor().wrap( convert(geomObj), options );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,455 +81,16 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
|
|||
*
|
||||
* @return The JTS Geometry value
|
||||
*/
|
||||
public Geometry toJTS(Object struct) {
|
||||
public Geometry convert(Object struct) {
|
||||
if ( struct == null ) {
|
||||
return null;
|
||||
}
|
||||
final SDOGeometry sdogeom = SDOGeometry.load( (Struct) struct );
|
||||
return convert2JTS( sdogeom );
|
||||
return toGeomerty(sdogeom);
|
||||
}
|
||||
|
||||
private Geometry convert2JTS(SDOGeometry sdoGeom) {
|
||||
final int dim = sdoGeom.getGType().getDimension();
|
||||
final 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) {
|
||||
final List<Geometry> geometries = new ArrayList<Geometry>();
|
||||
for ( SDOGeometry elemGeom : sdoGeom.getElementGeometries() ) {
|
||||
geometries.add( convert2JTS( elemGeom ) );
|
||||
}
|
||||
final 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
|
||||
};
|
||||
}
|
||||
}
|
||||
final CoordinateSequence cs = convertOrdinateArray( ordinates, sdoGeom );
|
||||
return getGeometryFactory().createPoint( cs );
|
||||
}
|
||||
|
||||
private MultiPoint convertSDOMultiPoint(int dim, int lrsDim, SDOGeometry sdoGeom) {
|
||||
final Double[] ordinates = sdoGeom.getOrdinates().getOrdinateArray();
|
||||
final CoordinateSequence cs = convertOrdinateArray( ordinates, sdoGeom );
|
||||
final MultiPoint multipoint = getGeometryFactory().createMultiPoint( cs );
|
||||
return multipoint;
|
||||
}
|
||||
|
||||
private LineString convertSDOLine(int dim, int lrsDim, SDOGeometry sdoGeom) {
|
||||
final boolean lrs = sdoGeom.isLRSGeometry();
|
||||
final ElemInfo info = sdoGeom.getInfo();
|
||||
CoordinateSequence cs = null;
|
||||
|
||||
int i = 0;
|
||||
while ( i < info.getSize() ) {
|
||||
if ( info.getElementType( i ).isCompound() ) {
|
||||
final 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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( lrs ) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
else {
|
||||
return getGeometryFactory().createLineString( cs );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private MultiLineString convertSDOMultiLine(int dim, int lrsDim, SDOGeometry sdoGeom) {
|
||||
final boolean lrs = sdoGeom.isLRSGeometry();
|
||||
if ( lrs ) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
final ElemInfo info = sdoGeom.getInfo();
|
||||
final LineString[] lines = new LineString[sdoGeom.getInfo().getSize()];
|
||||
int i = 0;
|
||||
while ( i < info.getSize() ) {
|
||||
CoordinateSequence cs = null;
|
||||
if ( info.getElementType( i ).isCompound() ) {
|
||||
final int numCompounds = info.getNumCompounds( i );
|
||||
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, sdoGeom ) );
|
||||
final LineString line = getGeometryFactory().createLineString( cs );
|
||||
lines[i] = line;
|
||||
i += 1 + numCompounds;
|
||||
}
|
||||
else {
|
||||
cs = add( cs, getElementCSeq( i, sdoGeom, false ) );
|
||||
final LineString line = getGeometryFactory().createLineString( cs );
|
||||
lines[i] = line;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return getGeometryFactory().createMultiLineString( lines );
|
||||
}
|
||||
|
||||
private Geometry convertSDOPolygon(int dim, int lrsDim, SDOGeometry sdoGeom) {
|
||||
LinearRing shell = null;
|
||||
final LinearRing[] holes = new LinearRing[sdoGeom.getNumElements() - 1];
|
||||
final 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>();
|
||||
final List<Polygon> polygons = new ArrayList<Polygon>();
|
||||
final 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() ) {
|
||||
final LinearRing lr = getGeometryFactory().createLinearRing( cs );
|
||||
holes.add( lr );
|
||||
}
|
||||
else {
|
||||
if ( shell != null ) {
|
||||
final 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 ) {
|
||||
final Polygon polygon = getGeometryFactory().createPolygon(
|
||||
shell,
|
||||
holes.toArray( new LinearRing[holes.size()] )
|
||||
);
|
||||
polygons.add( polygon );
|
||||
}
|
||||
return getGeometryFactory().createMultiPolygon( polygons.toArray( new Polygon[polygons.size()] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ) {
|
||||
final Coordinate[] coordinates = cs.toCoordinateArray();
|
||||
final 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) {
|
||||
final ElementType type = sdoGeom.getInfo().getElementType( i );
|
||||
final Double[] elemOrdinates = extractOrdinatesOfElement( i, sdoGeom, hasNextSE );
|
||||
CoordinateSequence cs;
|
||||
if ( type.isStraightSegment() ) {
|
||||
cs = convertOrdinateArray( elemOrdinates, sdoGeom );
|
||||
}
|
||||
else if ( type.isArcSegment() || type.isCircle() ) {
|
||||
final Coordinate[] linearized = linearize(
|
||||
elemOrdinates,
|
||||
sdoGeom.getDimension(),
|
||||
sdoGeom.isLRSGeometry(),
|
||||
type.isCircle()
|
||||
);
|
||||
cs = getGeometryFactory().getCoordinateSequenceFactory().create( linearized );
|
||||
}
|
||||
else if ( type.isRect() ) {
|
||||
cs = convertOrdinateArray( elemOrdinates, sdoGeom );
|
||||
final Coordinate ll = cs.getCoordinate( 0 );
|
||||
final Coordinate ur = cs.getCoordinate( 1 );
|
||||
final Coordinate lr = new Coordinate( ur.x, ll.y );
|
||||
final 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;
|
||||
}
|
||||
final Coordinate[] c1 = seq1.toCoordinateArray();
|
||||
final Coordinate[] c2 = seq2.toCoordinateArray();
|
||||
final 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) {
|
||||
final 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) {
|
||||
final int dim = sdoGeom.getDimension();
|
||||
final Coordinate[] coordinates = new Coordinate[oordinates.length / dim];
|
||||
final int zDim = sdoGeom.getZDimension() - 1;
|
||||
// final 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() ) {
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
// coordinates[i] = MCoordinate.create2dWithMeasure(
|
||||
// oordinates[i * dim], // X
|
||||
// oordinates[i * dim + 1], // Y
|
||||
// oordinates[i * dim + lrsDim]
|
||||
// ); // M
|
||||
}
|
||||
else {
|
||||
coordinates[i] = new Coordinate(
|
||||
//X
|
||||
oordinates[i * dim],
|
||||
//Y
|
||||
oordinates[i * dim + 1],
|
||||
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
|
||||
final 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;
|
||||
final double x1 = arcOrdinates[numOrd++];
|
||||
final double y1 = arcOrdinates[numOrd++];
|
||||
final double m1 = lrs ? arcOrdinates[numOrd++] : Double.NaN;
|
||||
final double x2 = arcOrdinates[numOrd++];
|
||||
final double y2 = arcOrdinates[numOrd++];
|
||||
final double m2 = lrs ? arcOrdinates[numOrd++] : Double.NaN;
|
||||
final double x3 = arcOrdinates[numOrd++];
|
||||
final double y3 = arcOrdinates[numOrd++];
|
||||
final 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 ) {
|
||||
throw new UnsupportedOperationException();
|
||||
// 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;
|
||||
}
|
||||
|
||||
final int destPos = linearizedCoords.length;
|
||||
final 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;
|
||||
}
|
||||
private Geometry toGeomerty(SDOGeometry sdoGeom) {
|
||||
return Decoders.decode(sdoGeom);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.dialect.oracle;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Struct;
|
||||
|
||||
/**
|
||||
* @author Karel Maesen, Geovise BVBA
|
||||
* creation-date: Jul 1, 2010
|
||||
*/
|
||||
class SDOPoint {
|
||||
public double x;
|
||||
|
||||
public double y;
|
||||
|
||||
public double z = Double.NaN;
|
||||
|
||||
public SDOPoint(Struct struct) {
|
||||
try {
|
||||
final 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() {
|
||||
final StringBuilder stb = new StringBuilder();
|
||||
stb.append( "(" ).append( x ).append( "," ).append( y ).append( "," ).append(
|
||||
z
|
||||
).append( ")" );
|
||||
return stb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.dialect.oracle;
|
||||
|
||||
import java.sql.Array;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Struct;
|
||||
|
||||
//TODO -- remove this interface..
|
||||
|
||||
/**
|
||||
* @author Karel Maesen, Geovise BVBA
|
||||
* creation-date: Jul 3, 2010
|
||||
*/
|
||||
interface SQLTypeFactory {
|
||||
|
||||
/**
|
||||
* Creates a {@code Struct} representing the specified geometry, using the specified Connection.
|
||||
*
|
||||
* @param geom The {@code SDOGeometry} object
|
||||
* @param conn The Oracle {@code Connection} used to create the {@code Struct}
|
||||
* @return The {@code Struct} representation of the specified SDO Geometry
|
||||
* @throws SQLException If a Struct object cannot be created.
|
||||
*/
|
||||
public abstract Struct createStruct(SDOGeometry geom, Connection conn) throws SQLException;
|
||||
|
||||
public abstract Array createElemInfoArray(ElemInfo elemInfo, Connection conn) throws SQLException;
|
||||
|
||||
public abstract Array createOrdinatesArray(Ordinates ordinates, Connection conn) throws SQLException;
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* This file is part of Hibernate Spatial, an extension to the
|
||||
* hibernate ORM solution for spatial (geographic) data.
|
||||
*
|
||||
* Copyright © 2007-2012 Geovise BVBA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.hibernate.spatial.dialect.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;
|
||||
|
||||
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"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -266,6 +266,6 @@ public class SDOGeometryExpectationsFactory extends AbstractExpectationsFactory
|
|||
|
||||
@Override
|
||||
protected Geometry decode(Object o) {
|
||||
return decoder.toJTS( o );
|
||||
return decoder.convert(o);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue