HHH-6512 - Refactors Oracle support.
This commit is contained in:
parent
dbfeb16e43
commit
2738d0f5c7
|
@ -26,7 +26,6 @@ dependencies {
|
||||||
compile(project(':hibernate-core'))
|
compile(project(':hibernate-core'))
|
||||||
compile([group: 'postgresql', name: 'postgresql', version: '8.4-701.jdbc4'])
|
compile([group: 'postgresql', name: 'postgresql', version: '8.4-701.jdbc4'])
|
||||||
compile([group: 'org.geolatte', name: 'geolatte-geom', version: '1.0-SNAPSHOT'])
|
compile([group: 'org.geolatte', name: 'geolatte-geom', version: '1.0-SNAPSHOT'])
|
||||||
// compile([group: 'com.vividsolutions', name: 'jts', version: '1.12'])
|
|
||||||
|
|
||||||
compile(libraries.dom4j) {
|
compile(libraries.dom4j) {
|
||||||
transitive = false
|
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 java.sql.Types;
|
||||||
|
|
||||||
|
import org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory;
|
||||||
import org.hibernate.type.descriptor.ValueBinder;
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
|
@ -21,22 +21,10 @@
|
||||||
|
|
||||||
package org.hibernate.spatial.dialect.oracle;
|
package org.hibernate.spatial.dialect.oracle;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import org.geolatte.geom.Geometry;
|
||||||
import java.sql.PreparedStatement;
|
import org.geolatte.geom.codec.db.oracle.Encoders;
|
||||||
import java.sql.SQLException;
|
import org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory;
|
||||||
import java.sql.Types;
|
import org.geolatte.geom.codec.db.oracle.SDOGeometry;
|
||||||
|
|
||||||
import com.vividsolutions.jts.algorithm.CGAlgorithms;
|
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
|
||||||
import com.vividsolutions.jts.geom.GeometryCollection;
|
|
||||||
import com.vividsolutions.jts.geom.LineString;
|
|
||||||
import com.vividsolutions.jts.geom.MultiLineString;
|
|
||||||
import com.vividsolutions.jts.geom.MultiPoint;
|
|
||||||
import com.vividsolutions.jts.geom.MultiPolygon;
|
|
||||||
import com.vividsolutions.jts.geom.Point;
|
|
||||||
import com.vividsolutions.jts.geom.Polygon;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.spatial.helper.FinderException;
|
import org.hibernate.spatial.helper.FinderException;
|
||||||
import org.hibernate.type.descriptor.ValueBinder;
|
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.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
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
|
* @author Karel Maesen, Geovise BVBA
|
||||||
* creation-date: 8/22/11
|
* creation-date: 8/22/11
|
||||||
*/
|
*/
|
||||||
class SDOGeometryValueBinder<J> implements ValueBinder<J> {
|
class SDOGeometryValueBinder<J> implements ValueBinder<J> {
|
||||||
|
|
||||||
|
private static final String SQL_TYPE_NAME = "MDSYS.SDO_GEOMETRY";
|
||||||
|
|
||||||
private final OracleJDBCTypeFactory typeFactory;
|
private final OracleJDBCTypeFactory typeFactory;
|
||||||
private final JavaTypeDescriptor<J> javaTypeDescriptor;
|
private final JavaTypeDescriptor<J> javaTypeDescriptor;
|
||||||
|
@ -62,11 +56,11 @@ class SDOGeometryValueBinder<J> implements ValueBinder<J> {
|
||||||
@Override
|
@Override
|
||||||
public void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException {
|
public void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException {
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
st.setNull( index, Types.STRUCT, SDOGeometry.getTypeName() );
|
st.setNull( index, Types.STRUCT, SQL_TYPE_NAME );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final Geometry jtsGeom = javaTypeDescriptor.unwrap( value, Geometry.class, options );
|
final Geometry geometry = javaTypeDescriptor.unwrap( value, Geometry.class, options );
|
||||||
final Object dbGeom = toNative( jtsGeom, st.getConnection() );
|
final Object dbGeom = toNative( geometry, st.getConnection() );
|
||||||
st.setObject( index, dbGeom );
|
st.setObject( index, dbGeom );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,345 +69,20 @@ class SDOGeometryValueBinder<J> implements ValueBinder<J> {
|
||||||
return typeFactory.createStruct( geom, conn );
|
return typeFactory.createStruct( geom, conn );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object toNative(Geometry jtsGeom, Connection connection) {
|
private Object toNative(Geometry geom, Connection connection) {
|
||||||
final SDOGeometry geom = convertJTSGeometry( jtsGeom );
|
final SDOGeometry sdoGeom = Encoders.encode(geom);
|
||||||
if (geom != null) {
|
if (geom != null) {
|
||||||
try {
|
try {
|
||||||
return store( geom, connection );
|
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);
|
||||||
}
|
}
|
||||||
catch ( SQLException e ) {
|
} else {
|
||||||
throw new HibernateException(
|
throw new UnsupportedOperationException("Conversion of " + geom.getClass().getSimpleName() + " to Oracle STRUCT not supported");
|
||||||
"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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,22 +25,11 @@ import java.sql.CallableStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Struct;
|
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.WrapperOptions;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.sql.BasicExtractor;
|
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> {
|
public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
|
||||||
|
|
||||||
private static GeometryFactory geometryFactory = new GeometryFactory();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates instance
|
* Creates instance
|
||||||
*
|
*
|
||||||
|
@ -73,25 +59,19 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
|
||||||
@Override
|
@Override
|
||||||
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
|
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
|
||||||
final Object geomObj = rs.getObject( name );
|
final Object geomObj = rs.getObject( name );
|
||||||
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
|
return getJavaDescriptor().wrap( convert(geomObj), options );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
|
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
|
||||||
final Object geomObj = statement.getObject( index );
|
final Object geomObj = statement.getObject( index );
|
||||||
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
|
return getJavaDescriptor().wrap( convert(geomObj), options );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
|
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
|
||||||
final Object geomObj = statement.getObject( name );
|
final Object geomObj = statement.getObject( name );
|
||||||
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
|
return getJavaDescriptor().wrap( convert(geomObj), options );
|
||||||
}
|
|
||||||
|
|
||||||
//TODO Clean up below this point
|
|
||||||
|
|
||||||
protected GeometryFactory getGeometryFactory() {
|
|
||||||
return geometryFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,455 +81,16 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
|
||||||
*
|
*
|
||||||
* @return The JTS Geometry value
|
* @return The JTS Geometry value
|
||||||
*/
|
*/
|
||||||
public Geometry toJTS(Object struct) {
|
public Geometry convert(Object struct) {
|
||||||
if ( struct == null ) {
|
if ( struct == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final SDOGeometry sdogeom = SDOGeometry.load( (Struct) struct );
|
final SDOGeometry sdogeom = SDOGeometry.load( (Struct) struct );
|
||||||
return convert2JTS( sdogeom );
|
return toGeomerty(sdogeom);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Geometry convert2JTS(SDOGeometry sdoGeom) {
|
private Geometry toGeomerty(SDOGeometry sdoGeom) {
|
||||||
final int dim = sdoGeom.getGType().getDimension();
|
return Decoders.decode(sdoGeom);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
@Override
|
||||||
protected Geometry decode(Object o) {
|
protected Geometry decode(Object o) {
|
||||||
return decoder.toJTS( o );
|
return decoder.convert(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue