HHH-6509 - Improves how SpatialFunctionalTestCase extends BasecoreFunctionalTestCase.

This commit is contained in:
Karel Maesen 2013-05-06 22:26:28 +02:00 committed by Steve Ebersole
parent d226ef36f2
commit 6e91485549
82 changed files with 2388 additions and 1756 deletions

View File

@ -1,7 +1,7 @@
This file is part of Hibernate Spatial, an extension to the
hibernate ORM solution for spatial (geographic) data.
Copyright © 2007-2012 Geovise BVBA
Copyright © 2007-2013 Geovise BVBA
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public

View File

@ -20,7 +20,9 @@
*/
apply plugin: 'java'
apply plugin: org.hibernate.build.gradle.testing.matrix.MatrixTestingPlugin
apply plugin: 'hibernate-matrix-testing'
//apply plugin: org.hibernate.build.gradle.testing.matrix.MatrixTestingPlugin
dependencies {
compile(project(':hibernate-core'))

View File

@ -1,3 +1,24 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2013 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;
import org.geolatte.geom.Geometry;
@ -8,16 +29,23 @@ import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
/**
* Descriptor for geolatte-geom {@code Geometry}s.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 10/12/12
*/
public class GeolatteGeometryJavaTypeDescriptor extends AbstractTypeDescriptor<Geometry> {
/**
* an instance of this descriptor
*/
public static final GeolatteGeometryJavaTypeDescriptor INSTANCE = new GeolatteGeometryJavaTypeDescriptor();
public static final GeolatteGeometryJavaTypeDescriptor INSTANCE = new GeolatteGeometryJavaTypeDescriptor( Geometry.class );
public GeolatteGeometryJavaTypeDescriptor(Class<Geometry> type) {
super( type );
/**
* Initialize a type descriptor for the geolatte-geom {@code Geometry} type.
*/
public GeolatteGeometryJavaTypeDescriptor() {
super( Geometry.class );
}
@Override

View File

@ -1,3 +1,24 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2013 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;
import org.geolatte.geom.Geometry;
@ -13,11 +34,22 @@ import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* a {@code Type} that maps between the database geometry type and geolatte-geom {@code Geometry}.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 10/12/12
*/
public class GeolatteGeometryType extends AbstractSingleColumnStandardBasicType<Geometry> implements Spatial {
/**
* Constructs an instance with the specified {@code SqlTypeDescriptor}
*
* @param sqlTypeDescriptor The Descriptor for the type used by the database for geometries.
*/
public GeolatteGeometryType(SqlTypeDescriptor sqlTypeDescriptor) {
super( sqlTypeDescriptor, GeolatteGeometryJavaTypeDescriptor.INSTANCE );
}
@Override
public String[] getRegistrationKeys() {
return new String[] {
@ -33,10 +65,6 @@ public class GeolatteGeometryType extends AbstractSingleColumnStandardBasicType<
};
}
public GeolatteGeometryType(SqlTypeDescriptor sqlTypeDescriptor) {
super( sqlTypeDescriptor, GeolatteGeometryJavaTypeDescriptor.INSTANCE );
}
@Override
public String getName() {
return "geolatte_geometry";

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -31,16 +31,23 @@ import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Descriptor for JTS {@code Geometry}s.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 7/27/11
*/
public class JTSGeometryJavaTypeDescriptor extends AbstractTypeDescriptor<Geometry> {
/**
* An instance of this descriptor
*/
public static final JavaTypeDescriptor<Geometry> INSTANCE = new JTSGeometryJavaTypeDescriptor();
public static final JavaTypeDescriptor<Geometry> INSTANCE = new JTSGeometryJavaTypeDescriptor( Geometry.class );
public JTSGeometryJavaTypeDescriptor(Class<Geometry> type) {
super( type );
/**
* Initialize a type descriptor for the geolatte-geom {@code Geometry} type.
*/
public JTSGeometryJavaTypeDescriptor() {
super( Geometry.class );
}
@Override
@ -50,7 +57,7 @@ public class JTSGeometryJavaTypeDescriptor extends AbstractTypeDescriptor<Geomet
@Override
public Geometry fromString(String string) {
WKTReader reader = new WKTReader();
final WKTReader reader = new WKTReader();
try {
return reader.read( string );
}

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -26,12 +26,21 @@ import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* A {@link org.hibernate.type.BasicType BasicType} for JTS <code>Geometry</code>s.
* A {@code Type} that maps between the database geometry type and JTS {@code Geometry}.
*
* @author Karel Maesen
*/
public class JTSGeometryType extends AbstractSingleColumnStandardBasicType<Geometry> implements Spatial {
/**
* Constructs an instance with the specified {@code SqlTypeDescriptor}
*
* @param sqlTypeDescriptor The descriptor for the type used by the database for geometries.
*/
public JTSGeometryType(SqlTypeDescriptor sqlTypeDescriptor) {
super( sqlTypeDescriptor, JTSGeometryJavaTypeDescriptor.INSTANCE );
}
@Override
public String[] getRegistrationKeys() {
return new String[] {
@ -47,9 +56,6 @@ public class JTSGeometryType extends AbstractSingleColumnStandardBasicType<Geome
};
}
public JTSGeometryType(SqlTypeDescriptor sqlTypeDescriptor) {
super( sqlTypeDescriptor, JTSGeometryJavaTypeDescriptor.INSTANCE );
}
@Override
public String getName() {

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -25,8 +25,9 @@ import org.jboss.logging.BasicLogger;
import org.jboss.logging.MessageLogger;
/**
* The logger interface for the Hibernate Spatial module.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 1/14/12
*/
@MessageLogger(projectCode = "HS")
public interface Log extends BasicLogger {

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -25,17 +25,24 @@ import org.jboss.logging.Logger;
/**
* A static factory for <code>Log</code>s.
* <p/>
* <p>The implementation is based on the hibernate-ogm LoggerFactory class.</p>
*
* The implementation is based on the hibernate-ogm LoggerFactory class.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 1/14/12
*/
public class LogFactory {
private LogFactory(){}
/**
* Creates a new logger for the class that invokes this method.
*
* @return A new logger for the invoking class.
*/
public static Log make() {
Throwable t = new Throwable();
StackTraceElement directCaller = t.getStackTrace()[1];
final Throwable t = new Throwable();
final StackTraceElement directCaller = t.getStackTrace()[1];
return Logger.getMessageLogger( Log.class, directCaller.getClassName() );
}

View File

@ -1,3 +1,24 @@
/*
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2013 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;
/**

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -27,6 +27,9 @@ package org.hibernate.spatial;
*/
public interface SpatialAggregate {
/**
* Enum value for extent aggregation.
*/
public static final int EXTENT = 1;
}

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -27,18 +27,39 @@ package org.hibernate.spatial;
*/
public interface SpatialAnalysis {
/**
* The distance function
*/
public static int DISTANCE = 1;
/**
* The buffer function
*/
public static int BUFFER = 2;
/**
* The convexhull function
*/
public static int CONVEXHULL = 3;
/**
* The intersection function
*/
public static int INTERSECTION = 4;
/**
* The union function
*/
public static int UNION = 5;
/**
* The difference function
*/
public static int DIFFERENCE = 6;
/**
* The symmetric difference function
*/
public static int SYMDIFFERENCE = 7;
}

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -40,7 +40,7 @@ public interface SpatialDialect extends Serializable {
* @param spatialRelation The type of spatial relation (as defined in
* <code>SpatialRelation</code>).
*
* @return SQL fragment for use in the SQL WHERE-clause.
* @return SQL fragment {@code SpatialRelateExpression}
*/
public String getSpatialRelateSQL(String columnName, int spatialRelation);
@ -49,36 +49,38 @@ public interface SpatialDialect extends Serializable {
* <code>org.hibernate.spatial.criterion.SpatialFilterExpression</code>s
* into prepared statements.
*
* @param columnName- the name of the geometry-typed column to which the filter is
* be applied.
* @param columnName The name of the geometry-typed column to which the filter is
* be applied
*
* @return
* @return Rhe SQL fragment for the {@code SpatialFilterExpression}
*/
public String getSpatialFilterExpression(String columnName);
/**
* @param columnName the name of the Geometry property
* @param aggregation the type of <code>SpatialAggregate</code>
* Returns the SQL fragment for the specfied Spatial aggregate expression.
*
* @return the SQL fragment for the projection
* @param columnName The name of the Geometry property
* @param aggregation The type of <code>SpatialAggregate</code>
*
* @return The SQL fragment for the projection
*/
public String getSpatialAggregateSQL(String columnName, int aggregation);
/**
* Returns the SQL fragment when parsing a <code>DWithinExpression</code>.
* Returns The SQL fragment when parsing a <code>DWithinExpression</code>.
*
* @param columnName the geometry column to test against
* @param columnName The geometry column to test against
*
* @return
* @return The SQL fragment when parsing a <code>DWithinExpression</code>.
*/
public String getDWithinSQL(String columnName);
/**
* Returns the SQL fragment when parsing an <code>HavingSridExpression</code>.
*
* @param columnName the geometry column to test against
* @param columnName The geometry column to test against
*
* @return
* @return The SQL fragment for an <code>HavingSridExpression</code>.
*/
public String getHavingSridSQL(String columnName);
@ -87,17 +89,18 @@ public interface SpatialDialect extends Serializable {
* Returns the SQL fragment when parsing a <code>IsEmptyExpression</code> or
* <code>IsNotEmpty</code> expression.
*
* @param columnName the geometry column
* @param isEmpty whether the geometry is tested for empty or non-empty
* @param columnName The geometry column
* @param isEmpty Whether the geometry is tested for empty or non-empty
*
* @return
* @return The SQL fragment for the isempty function
*/
public String getIsEmptySQL(String columnName, boolean isEmpty);
/**
* Returns true if this <code>SpatialDialect</code> supports a specific filtering function.
* <p/>
* This is intended to signal DB-support for fast window queries, or MBR-overlap queries
* <p> This is intended to signal DB-support for fast window queries, or MBR-overlap queries.</p>
*
* @return True if filtering is supported
*/
public boolean supportsFiltering();
@ -106,7 +109,7 @@ public interface SpatialDialect extends Serializable {
*
* @param function <code>SpatialFunction</code>
*
* @return true if this <code>SpatialDialect</code> supports the spatial function specified by the function parameter.
* @return True if this <code>SpatialDialect</code> supports the spatial function specified by the function parameter.
*/
public boolean supports(SpatialFunction function);

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -24,41 +24,156 @@ package org.hibernate.spatial;
/**
* Spatial functions that users generally expect in a database.
*
* <p>The javadoc contains references to these specifications.</p>
* <ul>
* <li>OpenGIS Simple Features Specification for SQL, rev. 1.1 (OGC 99-049)</li>
* </ul>
*
* @author Karel Maesen, Geovise BVBA
* creation-date: Oct 7, 2010
*/
public enum SpatialFunction {
/**
* The dimension function, cfr. OGC 99-049, s2.1.1.1
*/
dimension( "SFS 1.1" ),
geometrytype( "SFS 1.1" ),
srid( "SFS 1.1" ),
envelope( "SFS 1.1" ),
astext( "SFS 1.1" ),
asbinary( "SFS 1.1" ),
isempty( "SFS 1.1" ),
issimple( "SFS 1.1" ),
boundary( "SFS 1.1" ),
equals( "SFS 1.1" ),
disjoint( "SFS 1.1" ),
intersects( "SFS 1.1" ),
touches( "SFS 1.1" ),
crosses( "SFS 1.1" ),
within( "SFS 1.1" ),
contains( "SFS 1.1" ),
overlaps( "SFS 1.1" ),
relate( "SFS 1.1" ),
distance( "SFS 1.1" ),
buffer( "SFS 1.1" ),
convexhull( "SFS 1.1" ),
intersection( "SFS 1.1" ),
geomunion( "SFS 1.1" ), //is actually UNION but this conflicts with SQL UNION construct
difference( "SFS 1.1" ),
symdifference( "SFS 1.1" ),
//the distance within function - dwithin(geom, geom, distance) : boolean)
dwithin( "common" ),
//the transform function - transform(geom, epsg-code): geometry
transform( "common" );
/**
* The geometryType function, cfr. OGC 99-049, s2.1.1.1
*/
geometrytype( "SFS 1.1" ),
/**
* The SRID function, cfr. OGC 99-049, s2.1.1.1
*/
srid( "SFS 1.1" ),
/**
* The envelope function, cfr. OGC 99-049, s2.1.1.1
*/
envelope( "SFS 1.1" ),
/**
* The asText function, cfr. OGC 99-049, s2.1.1.1
*/
astext( "SFS 1.1" ),
/**
* The asBinary function, cfr. OGC 99-049, s2.1.1.1
*/
asbinary( "SFS 1.1" ),
/**
* The isEmpty function, cfr. OGC 99-049, s2.1.1.1
*/
isempty( "SFS 1.1" ),
/**
* The isSimple function, cfr. OGC 99-049, s2.1.1.1
*/
issimple( "SFS 1.1" ),
/**
* The boundery function, cfr. OGC 99-049, s2.1.1.1
*/
boundary( "SFS 1.1" ),
/**
* The equals function, cfr. OGC 99-049, s2.1.1.2
*/
equals( "SFS 1.1" ),
/**
* The disjoint function, cfr. OGC 99-049, s2.1.1.2
*/
disjoint( "SFS 1.1" ),
/**
* The intersects function, cfr. OGC 99-049, s2.1.1.2
*/
intersects( "SFS 1.1" ),
/**
* The touches function, cfr. OGC 99-049, s2.1.1.2
*/
touches( "SFS 1.1" ),
/**
* The crosses function, cfr. OGC 99-049, s2.1.1.2
*/
crosses( "SFS 1.1" ),
/**
* The within function, cfr. OGC 99-049, s2.1.1.2
*/
within( "SFS 1.1" ),
/**
* The contains function, cfr. OGC 99-049, s2.1.1.2
*/
contains( "SFS 1.1" ),
/**
* The overlaps function, cfr. OGC 99-049, s2.1.1.2
*/
overlaps( "SFS 1.1" ),
/**
* The relate function, cfr. OGC 99-049, s2.1.1.2
*/
relate( "SFS 1.1" ),
/**
* The distance function, cfr. OGC 99-049, s2.1.1.3
*/
distance( "SFS 1.1" ),
/**
* The buffer function, cfr. OGC 99-049, s2.1.1.3
*/
buffer( "SFS 1.1" ),
/**
* The convexHull function, cfr. OGC 99-049, s2.1.1.3
*/
convexhull( "SFS 1.1" ),
/**
* The intersection function, cfr. OGC 99-049, s2.1.1.3
*/
intersection( "SFS 1.1" ),
/**
* The union function, cfr. OGC 99-049, s2.1.1.3
*/
geomunion( "SFS 1.1" ),
/**
* The difference function, cfr. OGC 99-049, s2.1.1.3
*/
difference( "SFS 1.1" ),
/**
* The symDifference function, cfr. OGC 99-049, s2.1.1.3
*/
symdifference( "SFS 1.1" ),
/**
* the distance within function
*
* <p>The semantics are those of Postgis function ST_Dwithin (geom1, geom2, distance) : boolean. It returns true
* if geom1 and geom2 are within the specified distance of one another (in units of the spatial reference system).</p>
*/
dwithin( "common" ),
/**
* the transform function
*
* <p>The semantics are those of the Postgis function ST_Transform(geometry, srid) : geometry. It returns new geometry
* with its coordinates transformed to the spatial reference system referenced by the srid parameter.
*/
transform( "common" );
private final String description;
SpatialFunction(String specification) {

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -21,30 +21,60 @@
package org.hibernate.spatial;
/**
* These spatial relations are all defined in "OpenGIS Simple Feature
* Specification for SQL, Rev. 1.1" of the Open Geospatial Consortium (OGC).
* Enumerates the supported spatial relations.
*
* <p>Most of these relations are defined in "OpenGIS Simple Features Specification for SQL, rev. 1.1 (OGC 99-049),
* section 2.1.13.3. "</p>
*
* @author Karel Maesen
*/
public interface SpatialRelation {
/**
* The geometries are spatially equal to each other.
*/
public static int EQUALS = 0;
/**
* The geometries are spatially dijoint
*/
public static int DISJOINT = 1;
/**
* The geometries touch
*/
public static int TOUCHES = 2;
/**
* The geometries cross
*/
public static int CROSSES = 3;
/**
* The first geometry is spatially within the second
*/
public static int WITHIN = 4;
/**
* The geometries spatially overlap
*/
public static int OVERLAPS = 5;
/**
* The first geometry spatially contains the second
*/
public static int CONTAINS = 6;
/**
* The first geometry intersects the second
*/
public static int INTERSECTS = 7;
@Deprecated
/**
* The bounding box of the first geometry intersects the bounding box of the second
*
* <p>This relation is not defined in OGC 99-049, it corresponds to the Postgis '&&' operator.</p>
*/
public static int FILTER = 8;
}

View File

@ -33,6 +33,8 @@ import org.hibernate.spatial.SpatialFunction;
import org.hibernate.type.StandardBasicTypes;
/**
* A {@code Criterion} constraining a geometry property to be within a specified distance of a search geometry.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/1/11
*/
@ -43,19 +45,31 @@ public class DWithinExpression implements Criterion {
private final Geometry geometry;
private final double distance;
/**
* Constructs an instance
*
* @param propertyName The name of the property being constrained
* @param geometry The search geometry
* @param distance The search distance (in units of the spatial reference system of the search geometry)
*/
public DWithinExpression(String propertyName, Geometry geometry, double distance) {
this.propertyName = propertyName;
this.geometry = geometry;
this.distance = distance;
}
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String column = ExpressionUtil.findColumn( propertyName, criteria, criteriaQuery );
SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect( criteriaQuery, SpatialFunction.dwithin );
final String column = ExpressionUtil.findColumn( propertyName, criteria, criteriaQuery );
final SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect(
criteriaQuery,
SpatialFunction.dwithin
);
return spatialDialect.getDWithinSQL( column );
}
@Override
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] {
criteriaQuery.getTypedValue( criteria, propertyName, geometry ),

View File

@ -36,20 +36,47 @@ import org.hibernate.spatial.SpatialFunction;
*/
public class ExpressionUtil {
/**
* private constructor prevents instantiation of this utility class
*/
private ExpressionUtil() {
}
/**
* Determines the {@code SpatialDialect} for the specified {@code CriteriaQuery}, and checks if the
* specified function is supported.
*
* @param criteriaQuery The {@code CriteriaQuery} for which the dialect is sought
* @param function The function for which to check support
*
* @return The {@code SpatialDialect} associated with the specified {@code CriteriaQuery}
*
* @throws HibernateException If the dialect for the specified {@code CriteriaQuery} is not a {@code SpatialDialect}.
* or the specified {@code SpatialFunction} is not supported by the dialect.
*/
public static SpatialDialect getSpatialDialect(CriteriaQuery criteriaQuery, SpatialFunction function) {
Dialect dialect = criteriaQuery.getFactory().getDialect();
final Dialect dialect = criteriaQuery.getFactory().getDialect();
if ( !( dialect instanceof SpatialDialect ) ) {
throw new HibernateException( "A spatial expression requires a spatial dialect." );
}
SpatialDialect spatialDialect = (SpatialDialect) dialect;
final SpatialDialect spatialDialect = (SpatialDialect) dialect;
if ( !spatialDialect.supports( function ) ) {
throw new HibernateException( function + " function not supported by this dialect" );
}
return spatialDialect;
}
/**
* Determines the column name corresponding to the specified property path.
*
* @param propertyName The property path
* @param criteria The criteria
* @param criteriaQuery The criteria query
* @return The column name
* @throws HibernateException If the property could not be resolved, or more than one column is mapped by the property path.
*/
public static String findColumn(String propertyName, Criteria criteria, CriteriaQuery criteriaQuery) {
String[] columns = criteriaQuery.findColumns( propertyName, criteria );
final String[] columns = criteriaQuery.findColumns( propertyName, criteria );
if ( columns.length != 1 ) {
throw new HibernateException( "Spatial Expression may only be used with single-column properties" );
}

View File

@ -31,25 +31,35 @@ import org.hibernate.spatial.SpatialFunction;
import org.hibernate.type.StandardBasicTypes;
/**
* A {@code Criterion} constraining a geometry property to have a specified SRID.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/9/11
*
*/
public class HavingSridExpression implements Criterion {
private final String propertyName;
private final int srid;
/**
* Constructs an instance for the specified property and srid
*
* @param propertyName The name of the property being constrained
* @param srid The srid
*/
public HavingSridExpression(String propertyName, int srid) {
this.propertyName = propertyName;
this.srid = srid;
}
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String column = ExpressionUtil.findColumn( propertyName, criteria, criteriaQuery );
SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect( criteriaQuery, SpatialFunction.srid );
final String column = ExpressionUtil.findColumn( propertyName, criteria, criteriaQuery );
final SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect( criteriaQuery, SpatialFunction.srid );
return spatialDialect.getHavingSridSQL( column );
}
@Override
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] {
new TypedValue( StandardBasicTypes.INTEGER, srid )

View File

@ -30,27 +30,37 @@ import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction;
/**
* A {@code Criterion} constraining a geometry property to be (non-)empty.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/15/11
*
*/
public class IsEmptyExpression implements Criterion {
private final static TypedValue[] NO_VALUES = new TypedValue[0];
private static final TypedValue[] NO_VALUES = new TypedValue[0];
private final String propertyName;
private final boolean isEmpty;
/**
* Constructs an instance for the specified property
*
* @param propertyName The name of the property being constrained
* @param isEmpty Whether to constrain the property to be empty or non-empty
*/
public IsEmptyExpression(String propertyName, boolean isEmpty) {
this.propertyName = propertyName;
this.isEmpty = isEmpty;
}
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String column = ExpressionUtil.findColumn( propertyName, criteria, criteriaQuery );
SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect( criteriaQuery, SpatialFunction.isempty );
final String column = ExpressionUtil.findColumn( propertyName, criteria, criteriaQuery );
final SpatialDialect spatialDialect = ExpressionUtil.getSpatialDialect( criteriaQuery, SpatialFunction.isempty );
return spatialDialect.getIsEmptySQL( column, isEmpty );
}
@Override
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return NO_VALUES;
}

View File

@ -34,59 +34,60 @@ import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.jts.EnvelopeAdapter;
/**
* An implementation for a simple spatial filter. This <code>Criterion</code>
* restricts the resultset to those features whose bounding box overlaps the
* filter geometry. It is intended for quick, but inexact spatial queries.
* A <code>Criterion</code> constraining a geometry property to have a bounding box that overlaps with
* a specified bounding box.
*
* @author Karel Maesen
*/
public class SpatialFilter implements Criterion {
private static final long serialVersionUID = 1L;
private String propertyName;
private Geometry filter;
private String propertyName = null;
private Geometry filter = null;
/**
* Constructs an instance with the specified property and the bounding box of the specified geometry.
*
* @param propertyName The name of the propety being constrained
* @param filter The geometry whose bounding box is used as search geometry
*/
public SpatialFilter(String propertyName, Geometry filter) {
this.propertyName = propertyName;
this.filter = filter;
}
public SpatialFilter(String propertyName, Envelope envelope, int SRID) {
/**
* Constructs an instance with the specified property and the bounding box of the specified geometry.
*
* @param propertyName The name of the propety being constrained
* @param envelope The bounding box is used as search geometry
* @param srid The SRID of the specified bounding box
*/
public SpatialFilter(String propertyName, Envelope envelope, int srid) {
this.propertyName = propertyName;
this.filter = EnvelopeAdapter.toPolygon( envelope, SRID );
this.filter = EnvelopeAdapter.toPolygon( envelope, srid );
}
public TypedValue[] getTypedValues(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
@Override
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] {
criteriaQuery.getTypedValue(
criteria,
propertyName, filter
)
criteriaQuery.getTypedValue( criteria, propertyName, filter )
};
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
SessionFactoryImplementor factory = criteriaQuery.getFactory();
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria,
this.propertyName
);
Dialect dialect = factory.getDialect();
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
final SessionFactoryImplementor factory = criteriaQuery.getFactory();
final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, this.propertyName );
final Dialect dialect = factory.getDialect();
if ( dialect instanceof SpatialDialect ) {
SpatialDialect seDialect = (SpatialDialect) dialect;
final SpatialDialect seDialect = (SpatialDialect) dialect;
return seDialect.getSpatialFilterExpression( columns[0] );
}
else {
throw new IllegalStateException(
"Dialect must be spatially enabled dialect"
);
throw new IllegalStateException( "Dialect must be spatially enabled dialect" );
}
}
}

View File

@ -32,40 +32,44 @@ import org.hibernate.spatial.SpatialDialect;
import org.hibernate.type.Type;
/**
* A factory for spatial projections.
*
* @author Karel Maesen
*/
public class SpatialProjections {
private SpatialProjections() {
}
/**
* Applies an extent projection to the specified geometry function
*
* <p>The extent of a set of {@code Geometry}s is the union of their bounding boxes.</p>
*
* @param propertyName The property to use for calculating the extent
*
* @return an extent-projection for the specified property.
*/
public static Projection extent(final String propertyName) {
return new SimpleProjection() {
public Type[] getTypes(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new Type[] {
criteriaQuery.getType(
criteria,
propertyName
)
criteriaQuery.getType( criteria, propertyName )
};
}
public String toSqlString(Criteria criteria, int position,
CriteriaQuery criteriaQuery) throws HibernateException {
StringBuilder stbuf = new StringBuilder();
public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery)
throws HibernateException {
final StringBuilder stbuf = new StringBuilder();
SessionFactoryImplementor factory = criteriaQuery.getFactory();
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, propertyName
);
Dialect dialect = factory.getDialect();
final SessionFactoryImplementor factory = criteriaQuery.getFactory();
final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, propertyName );
final Dialect dialect = factory.getDialect();
if ( dialect instanceof SpatialDialect ) {
SpatialDialect seDialect = (SpatialDialect) dialect;
final SpatialDialect seDialect = (SpatialDialect) dialect;
stbuf.append(
seDialect.getSpatialAggregateSQL(
columns[0],
SpatialAggregate.EXTENT
)
seDialect.getSpatialAggregateSQL( columns[0], SpatialAggregate.EXTENT )
);
stbuf.append( " as y" ).append( position ).append( '_' );
return stbuf.toString();

View File

@ -32,82 +32,56 @@ import org.hibernate.engine.spi.TypedValue;
import org.hibernate.spatial.SpatialDialect;
/**
* An implementation of the <code>Criterion</code> interface that implements
* spatial queries: queries to the effect that a geometry property has a
* specific spatial relation to a test geometry
* A {@code Criterion} constraining a {@code Geometry} property to have specific spatial relation
* to a search {@code Geometry}.
*
* @author Karel Maesen
*/
public class SpatialRelateExpression implements Criterion {
private static final long serialVersionUID = 1L;
/**
* The geometry property
*/
private String propertyName = null;
private String propertyName;
/**
* The test geometry
*/
private Geometry value = null;
private Geometry value;
/**
* The spatial relation that is queried for.
*/
private int spatialRelation = -1;
private static final long serialVersionUID = 1L;
public SpatialRelateExpression(String propertyName,
Geometry value, int spatialRelation) {
/**
* Constructs an instance
*
* @param propertyName The name of the property being constrained
* @param value The search {@code Geometry}
* @param spatialRelation The type of {@code SpatialRelation} to use in the comparison
*/
public SpatialRelateExpression(String propertyName, Geometry value, int spatialRelation) {
this.propertyName = propertyName;
this.spatialRelation = spatialRelation;
this.value = value;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.criterion.Criterion#getTypedValues(org.hibernate.Criteria,
* org.hibernate.criterion.CriteriaQuery)
*/
public TypedValue[] getTypedValues(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] {
criteriaQuery.getTypedValue(
criteria,
propertyName, value
)
};
@Override
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] { criteriaQuery.getTypedValue( criteria, propertyName, value ) };
}
/*
* (non-Javadoc)
*
* @see org.hibernate.criterion.Criterion#toSqlString(org.hibernate.Criteria,
* org.hibernate.criterion.CriteriaQuery)
*/
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
SessionFactoryImplementor factory = criteriaQuery.getFactory();
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria,
this.propertyName
);
Dialect dialect = factory.getDialect();
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
final SessionFactoryImplementor factory = criteriaQuery.getFactory();
final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, this.propertyName );
final Dialect dialect = factory.getDialect();
if ( dialect instanceof SpatialDialect ) {
SpatialDialect seDialect = (SpatialDialect) dialect;
return seDialect.getSpatialRelateSQL(
columns[0],
spatialRelation
);
final SpatialDialect seDialect = (SpatialDialect) dialect;
return seDialect.getSpatialRelateSQL( columns[0], spatialRelation );
}
else {
throw new IllegalStateException(
"Dialect must be spatially enabled dialect"
);
throw new IllegalStateException( "Dialect must be spatially enabled dialect" );
}
}

View File

@ -27,25 +27,31 @@ import org.hibernate.criterion.Criterion;
import org.hibernate.spatial.SpatialRelation;
/**
* Static Factory Class for creating spatial criterion types.
* <p/>
* <p>
* A factory for spatial criteria.
*
* The criterion types created by this class implement the spatial query
* expressions of the OpenGIS Simple Features Specification for SQL, Revision
* 1.1.
* <p/>
* In addition, it provides for a simple spatial <code>filter</code> that
* 1.1. In addition, it provides for a simple spatial <code>filter</code> that
* works mostly using the spatial index. This corresponds to the Oracle
* Spatial's "SDO_FILTER" function, or the "&&" operator of PostGIS.
* </p>
*
* @author Karel Maesen
*/
public class SpatialRestrictions {
SpatialRestrictions() {
private SpatialRestrictions() {
}
/**
* Apply a "spatially equal" constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value to use in comparison
*
* @return SpatialRelateExpression
*
* @see SpatialRelateExpression
*/
public static SpatialRelateExpression eq(String propertyName, Geometry value) {
return new SpatialRelateExpression(
propertyName, value,
@ -53,7 +59,16 @@ public class SpatialRestrictions {
);
}
/**
* Apply a "spatially within" constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value to use in comparison
*
* @return SpatialRelateExpression
*
* @see SpatialRelateExpression
*/
public static SpatialRelateExpression within(String propertyName, Geometry value) {
return new SpatialRelateExpression(
propertyName, value,
@ -61,6 +76,16 @@ public class SpatialRestrictions {
);
}
/**
* Apply a "spatially contains" constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value to use in comparison
*
* @return SpatialRelateExpression
*
* @see SpatialRelateExpression
*/
public static SpatialRelateExpression contains(String propertyName, Geometry value) {
return new SpatialRelateExpression(
propertyName, value,
@ -68,6 +93,16 @@ public class SpatialRestrictions {
);
}
/**
* Apply a "spatially crosses" constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value to use in comparison
*
* @return SpatialRelateExpression
*
* @see SpatialRelateExpression
*/
public static SpatialRelateExpression crosses(String propertyName, Geometry value) {
return new SpatialRelateExpression(
propertyName, value,
@ -75,6 +110,16 @@ public class SpatialRestrictions {
);
}
/**
* Apply a "spatially disjoint" constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value to use in comparison
*
* @return SpatialRelateExpression
*
* @see SpatialRelateExpression
*/
public static SpatialRelateExpression disjoint(String propertyName, Geometry value) {
return new SpatialRelateExpression(
propertyName, value,
@ -82,6 +127,16 @@ public class SpatialRestrictions {
);
}
/**
* Apply a "spatially intersects" constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value to use in comparison
*
* @return SpatialRelateExpression
*
* @see SpatialRelateExpression
*/
public static SpatialRelateExpression intersects(String propertyName, Geometry value) {
return new SpatialRelateExpression(
propertyName, value,
@ -89,6 +144,16 @@ public class SpatialRestrictions {
);
}
/**
* Apply a "spatially overlaps" constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value to use in comparison
*
* @return SpatialRelateExpression
*
* @see SpatialRelateExpression
*/
public static SpatialRelateExpression overlaps(String propertyName, Geometry value) {
return new SpatialRelateExpression(
propertyName, value,
@ -96,6 +161,16 @@ public class SpatialRestrictions {
);
}
/**
* Apply a "spatially touches" constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value to use in comparison
*
* @return SpatialRelateExpression
*
* @see SpatialRelateExpression
*/
public static SpatialRelateExpression touches(String propertyName, Geometry value) {
return new SpatialRelateExpression(
propertyName, value,
@ -103,34 +178,102 @@ public class SpatialRestrictions {
);
}
public static SpatialFilter filter(String propertyName, Geometry filter) {
return new SpatialFilter( propertyName, filter );
/**
* Apply a bounding box overlap constraint to the named property
*
* @param propertyName The name of the property
* @param value The geometry value whose bounding box to use in the comparison
*
* @return SpatialFilter
*
* @see SpatialFilter
*/
public static SpatialFilter filter(String propertyName, Geometry value) {
return new SpatialFilter( propertyName, value );
}
public static SpatialFilter filter(String propertyName, Envelope envelope,
int SRID) {
return new SpatialFilter( propertyName, envelope, SRID );
/**
* Apply a bounding box overlap constraint to the named property
*
* @param propertyName The name of the property
* @param envelope The envelope or bounding box to use in the comparison
* @param srid the SRID of the bounding box
*
* @return SpatialFilter
*
* @see SpatialFilter
*/
public static SpatialFilter filter(String propertyName, Envelope envelope, int srid) {
return new SpatialFilter( propertyName, envelope, srid );
}
/**
* Apply a "distance within" constraint to the named property
*
* @param propertyName The name of the property
* @param geometry The geometry value to use in the comparison
* @param distance The distance
*
* @return DWithinExpression
*
* @see DWithinExpression
*/
public static Criterion distanceWithin(String propertyName, Geometry geometry, double distance) {
return new DWithinExpression( propertyName, geometry, distance );
}
/**
* Apply a "having srid" constraint to the named property
*
* @param propertyName The name of the property
* @param srid The SRID value to use in the comparison
*
* @return A HavingSridExpression
*
* @see HavingSridExpression
*/
public static Criterion havingSRID(String propertyName, int srid) {
return new HavingSridExpression( propertyName, srid );
}
/**
* Apply an "is empty" constraint to the named property
*
* @param propertyName The name of the property
*
* @return A IsEmptyExpression
*
* @see IsEmptyExpression
*/
public static Criterion isEmpty(String propertyName) {
return new IsEmptyExpression( propertyName, true );
}
/**
* Apply an "is not empty" constraint to the named property
*
* @param propertyName The name of the property
*
* @return A IsEmptyExpression
*
* @see IsEmptyExpression
*/
public static Criterion isNotEmpty(String propertyName) {
return new IsEmptyExpression( propertyName, false );
}
public static Criterion spatialRestriction(int relation,
String propertyName, Geometry value) {
/**
* Apply the specified spatial relation constraint to the named property.
*
* @param relation The spatial relation to apply
* @param propertyName The name of the property
* @param value The geometry value to use in the comparison
*
* @return SpatialFilter
*
* @see SpatialFilter
*/
public static Criterion spatialRestriction(int relation, String propertyName, Geometry value) {
switch ( relation ) {
case SpatialRelation.CONTAINS:
return contains( propertyName, value );

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This extends the criterion API with spatial query expressions.
</p>
</body>
</html>

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA, Geodan IT b.v.
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -252,6 +252,7 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
typeContributions.contributeType( new JTSGeometryType( GeoDBGeometryTypeDescriptor.INSTANCE ) );
}
@Override
public String getSpatialAggregateSQL(String columnName, int aggregation) {
switch ( aggregation ) {
// NOT YET AVAILABLE IN GEODB
@ -267,30 +268,28 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
}
}
@Override
public String getDWithinSQL(String columnName) {
return "ST_DWithin(" + columnName + ",?,?)";
}
@Override
public String getHavingSridSQL(String columnName) {
return "( ST_srid(" + columnName + ") = ?)";
}
@Override
public String getIsEmptySQL(String columnName, boolean isEmpty) {
String emptyExpr = " ST_IsEmpty(" + columnName + ") ";
final String emptyExpr = " ST_IsEmpty(" + columnName + ") ";
return isEmpty ? emptyExpr : "( NOT " + emptyExpr + ")";
}
/* (non-Javadoc)
* @see org.hibernatespatial.SpatialDialect#getSpatialFilterExpression(java.lang.String)
*/
@Override
public String getSpatialFilterExpression(String columnName) {
return "(" + columnName + " && ? ) ";
}
/* (non-Javadoc)
* @see org.hibernatespatial.SpatialDialect#getSpatialRelateSQL(java.lang.String, int, boolean)
*/
@Override
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
switch ( spatialRelation ) {
case SpatialRelation.WITHIN:
@ -316,31 +315,14 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
}
}
/* (non-Javadoc)
* @see org.hibernatespatial.SpatialDialect#getDbGeometryTypeName()
*/
public String getDbGeometryTypeName() {
return "GEOM";
}
/* (non-Javadoc)
* @see org.hibernatespatial.SpatialDialect#isTwoPhaseFiltering()
*/
public boolean isTwoPhaseFiltering() {
return false;
}
@Override
public boolean supportsFiltering() {
return false;
}
@Override
public boolean supports(SpatialFunction function) {
if ( function == SpatialFunction.difference ) {
return false;
}
return ( getFunctions().get( function.toString() ) != null );
return function != SpatialFunction.difference && ( getFunctions().get( function.toString() ) != null );
}
}

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA, Geodan IT b.v.
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -38,11 +38,15 @@ import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* Descriptor for GeoDB Geometries.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/29/12
*/
public class GeoDBGeometryTypeDescriptor implements SqlTypeDescriptor {
/**
* An instance of this Descriptor
*/
public static final GeoDBGeometryTypeDescriptor INSTANCE = new GeoDBGeometryTypeDescriptor();
@Override
@ -50,7 +54,6 @@ public class GeoDBGeometryTypeDescriptor implements SqlTypeDescriptor {
return Types.ARRAY;
}
@Override
public boolean canBeRemapped() {
return false;
@ -62,7 +65,7 @@ public class GeoDBGeometryTypeDescriptor implements SqlTypeDescriptor {
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException {
Geometry geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
final Geometry geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
st.setBytes( index, GeoDbWkb.to( geometry ) );
}
};
@ -91,5 +94,4 @@ public class GeoDBGeometryTypeDescriptor implements SqlTypeDescriptor {
}
}

View File

@ -2,7 +2,7 @@
* This file is part of Hibernate Spatial, an extension to the
* hibernate ORM solution for spatial (geographic) data.
*
* Copyright © 2007-2012 Geovise BVBA, Geodan IT b.v.
* Copyright © 2007-2013 Geovise BVBA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -47,30 +47,45 @@ import org.hibernate.spatial.LogFactory;
/**
* A utility class to serialize from/to GeoDB WKB's.
* <p/>
*
* <p>Note: this utility makes it unnecessary to have a dependency on GeoDB. As long as GeoDB is
* not available in common maven repositories, such a dependency is to be avoided.</p>
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 2/29/12
*/
public class GeoDbWkb {
private static Log LOG = LogFactory.make();
private static final Log LOGGER = LogFactory.make();
private GeoDbWkb() {
}
/**
* Encode the specified {@code Geometry} into a WKB
*
* @param geometry The value to encode
*
* @return A byte-array representing the geometry in WKB.
*/
public static byte[] to(Geometry geometry) {
WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.POSTGIS_EWKB_1 );
ByteBuffer buffer = encoder.encode( geometry, ByteOrder.NDR );
final WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.POSTGIS_EWKB_1 );
final ByteBuffer buffer = encoder.encode( geometry, ByteOrder.NDR );
return ( buffer == null ? null : buffer.toByteArray() );
}
/**
* Decode the object into a {@code Geometry}
*
* @param object The object to decode
*
* @return The {@code Geometry}
*/
public static Geometry from(Object object) {
if ( object == null ) {
return null;
}
try {
WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.POSTGIS_EWKB_1 );
final WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.POSTGIS_EWKB_1 );
if ( object instanceof Blob ) {
return decoder.decode( toByteBuffer( (Blob) object ) );
}
@ -88,14 +103,14 @@ public class GeoDbWkb {
}
}
catch ( Exception e ) {
LOG.warn( "Could not convert database object to a Geometry." );
LOGGER.warn( "Could not convert database object to a Geometry." );
throw new HibernateException( e );
}
}
private static Geometry toPolygon(Envelope env) {
PointSequence ps = PointSequenceBuilders.fixedSized( 4, DimensionalFlag.d2D, CrsId.UNDEFINED )
final PointSequence ps = PointSequenceBuilders.fixedSized( 4, DimensionalFlag.d2D, CrsId.UNDEFINED )
.add( env.getMinX(), env.getMinY() )
.add( env.getMinX(), env.getMaxY() )
.add( env.getMaxX(), env.getMaxY() )
@ -104,8 +119,8 @@ public class GeoDbWkb {
}
private static ByteBuffer toByteBuffer(Blob blob) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final byte[] buf = new byte[1024];
InputStream in = null;
try {
@ -116,7 +131,7 @@ public class GeoDbWkb {
}
}
catch ( Exception e ) {
LOG.warn( "Could not convert database BLOB object to binary stream.", e );
LOGGER.warn( "Could not convert database BLOB object to binary stream.", e );
}
finally {
try {
@ -125,7 +140,7 @@ public class GeoDbWkb {
}
}
catch ( IOException e ) {
LOG.warn( "Could not close binary stream." );
LOGGER.warn( "Could not close binary stream." );
}
}
return ByteBuffer.from( baos.toByteArray() );

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This package contains the H2 Dialect extensions for the GeoDB dialect.
</p>
<p>
For more information on GeoDB, see <a href="https://github.com/jdeolive/geodb">https://github.com/jdeolive/geodb</a>.
</p>
</body>
</html>

View File

@ -12,14 +12,18 @@ import org.hibernate.spatial.SpatialFunction;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* A Dialect for MySQL 5 using InnoDB engine, with support for its spatial features
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 6/21/12
*
*/
public class MySQL5SpatialInnoDBDialect extends MySQL5InnoDBDialect implements SpatialDialect {
private MySQLSpatialDialect dialectDelegate = new MySQLSpatialDialect();
/**
* Constructs an instance
*/
public MySQL5SpatialInnoDBDialect() {
super();
registerColumnType(
@ -76,10 +80,6 @@ public class MySQL5SpatialInnoDBDialect extends MySQL5InnoDBDialect implements S
return dialectDelegate.getIsEmptySQL( columnName, isEmpty );
}
public String getDbGeometryTypeName() {
return dialectDelegate.getDbGeometryTypeName();
}
@Override
public boolean supportsFiltering() {
return dialectDelegate.supportsFiltering();

View File

@ -43,22 +43,21 @@ import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* Descriptor for MySQL Geometries.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 1/17/12
*/
public class MySQLGeometryTypeDescriptor implements SqlTypeDescriptor {
/**
* An instance of this Descriptor
*/
public static final MySQLGeometryTypeDescriptor INSTANCE = new MySQLGeometryTypeDescriptor();
@Override
public int getSqlType() {
return Types.ARRAY;
}
//
// @Override
// public String getTypeName() {
// return "GEOMETRY";
// }
@Override
public boolean canBeRemapped() {
@ -71,10 +70,10 @@ public class MySQLGeometryTypeDescriptor implements SqlTypeDescriptor {
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException {
WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.MYSQL_WKB );
Geometry geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
ByteBuffer buffer = encoder.encode( geometry, ByteOrder.NDR );
byte[] bytes = ( buffer == null ? null : buffer.toByteArray() );
final WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.MYSQL_WKB );
final Geometry geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
final ByteBuffer buffer = encoder.encode( geometry, ByteOrder.NDR );
final byte[] bytes = ( buffer == null ? null : buffer.toByteArray() );
st.setBytes( index, bytes );
}
};
@ -106,8 +105,8 @@ public class MySQLGeometryTypeDescriptor implements SqlTypeDescriptor {
if ( bytes == null ) {
return null;
}
ByteBuffer buffer = ByteBuffer.from( bytes );
WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.MYSQL_WKB );
final ByteBuffer buffer = ByteBuffer.from( bytes );
final WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.MYSQL_WKB );
return decoder.decode( buffer );
}

View File

@ -33,14 +33,15 @@ import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation;
/**
* Extends the MySQLDialect by also including information on spatial operators,
* constructors and processing functions.
* A Dialect for MySQL with support for its spatial features
*
* @author Karel Maesen
* @author Boni Gopalan [3/11/2011:Refactored the code to introduce MySQLSpatialInnoDBDialect without much code duplication]
* @author Karel Maesen, Boni Gopalan
*/
public class MySQLSpatialDialect extends MySQLDialect implements SpatialDialect {
/**
* Constructs an instance
*/
public MySQLSpatialDialect() {
super();
registerColumnType(
@ -62,14 +63,7 @@ public class MySQLSpatialDialect extends MySQLDialect implements SpatialDialect
typeContributions.contributeType( new JTSGeometryType( MySQLGeometryTypeDescriptor.INSTANCE ) );
}
/**
* @param columnName The name of the geometry-typed column to which the relation is
* applied
* @param spatialRelation The type of spatial relation (as defined in
* <code>SpatialRelation</code>).
*
* @return
*/
@Override
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
switch ( spatialRelation ) {
case SpatialRelation.WITHIN:
@ -96,35 +90,38 @@ public class MySQLSpatialDialect extends MySQLDialect implements SpatialDialect
}
@Override
public String getSpatialFilterExpression(String columnName) {
return "MBRIntersects(" + columnName + ", ? ) ";
}
@Override
public String getSpatialAggregateSQL(String columnName, int aggregation) {
throw new UnsupportedOperationException( "Mysql has no spatial aggregate SQL functions." );
}
@Override
public String getDWithinSQL(String columnName) {
throw new UnsupportedOperationException( String.format( "Mysql doesn't support the Dwithin function" ) );
}
@Override
public String getHavingSridSQL(String columnName) {
return " (srid(" + columnName + ") = ?) ";
}
@Override
public String getIsEmptySQL(String columnName, boolean isEmpty) {
String emptyExpr = " IsEmpty(" + columnName + ") ";
final String emptyExpr = " IsEmpty(" + columnName + ") ";
return isEmpty ? emptyExpr : "( NOT " + emptyExpr + ")";
}
public String getDbGeometryTypeName() {
return "GEOMETRY";
}
@Override
public boolean supportsFiltering() {
return false;
}
@Override
public boolean supports(SpatialFunction function) {
switch ( function ) {
case boundary:
@ -139,8 +136,9 @@ public class MySQLSpatialDialect extends MySQLDialect implements SpatialDialect
case dwithin:
case transform:
return false;
}
default:
return true;
}
}
}

View File

@ -8,12 +8,14 @@ import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StandardBasicTypes;
/**
* An {@code Iterable} over the spatial functions supported by MySQL.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 9/15/12
*
*/
class MySQLSpatialFunctions implements Iterable<Map.Entry<String, StandardSQLFunction>> {
final private Map<String, StandardSQLFunction> functionsToRegister = new HashMap<String, StandardSQLFunction>();
private final Map<String, StandardSQLFunction> functionsToRegister = new HashMap<String, StandardSQLFunction>();
MySQLSpatialFunctions(){
functionsToRegister.put(

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This package contains the spatial extensions for the MySQL dialect.
</p>
</body>
</html>

View File

@ -43,23 +43,24 @@ import org.hibernate.spatial.helper.FinderException;
*/
public class DefaultConnectionFinder implements ConnectionFinder {
private final static Class<?> oracleConnectionClass;
private static final Class<?> ORACLE_CONNECTION_CLASS;
static {
try {
oracleConnectionClass = Class.forName( "oracle.jdbc.driver.OracleConnection" );
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 ( oracleConnectionClass.isInstance( con ) ) {
if ( ORACLE_CONNECTION_CLASS.isInstance( con ) ) {
return con;
}
// try to find the Oracleconnection recursively
@ -71,7 +72,7 @@ public class DefaultConnectionFinder implements ConnectionFinder {
try {
method.setAccessible( true );
Connection oc = find( (Connection) ( method.invoke( con, new Object[] { } ) ) );
final Connection oc = find( (Connection) ( method.invoke( con, new Object[] { } ) ) );
if ( oc == null ) {
throw new FinderException(
String.format(

View File

@ -31,15 +31,14 @@ import java.sql.Array;
class ElemInfo {
static final String TYPE_NAME = "MDSYS.SDO_ELEM_INFO_ARRAY";
private BigDecimal[] triplets;
public ElemInfo(int size) {
this.triplets = new BigDecimal[3 * size];
}
public ElemInfo(BigDecimal[] elem_info) {
this.triplets = elem_info;
public ElemInfo(BigDecimal[] elemInfo) {
this.triplets = elemInfo;
}
public ElemInfo(Array array) {
@ -55,7 +54,6 @@ class ElemInfo {
}
}
public BigDecimal[] getElements() {
return this.triplets;
}
@ -73,10 +71,9 @@ class ElemInfo {
}
public ElementType getElementType(int i) {
int etype = this.triplets[i * 3 + 1].intValue();
int interp = this.triplets[i * 3 + 2].intValue();
ElementType et = ElementType.parseType( etype, interp );
return et;
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) {
@ -92,8 +89,7 @@ class ElemInfo {
}
}
public void setElement(int i, int ordinatesOffset, ElementType et,
int numCompounds) {
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."
@ -112,7 +108,7 @@ class ElemInfo {
}
public void addElement(BigDecimal[] element) {
BigDecimal[] newTriplets = new BigDecimal[this.triplets.length + element.length];
final BigDecimal[] newTriplets = new BigDecimal[this.triplets.length + element.length];
System.arraycopy(
this.triplets, 0, newTriplets, 0,
this.triplets.length
@ -131,7 +127,7 @@ class ElemInfo {
public BigDecimal[] getElement(int i) {
BigDecimal[] ea = null;
if ( this.getElementType( i ).isCompound() ) {
int numCompounds = this.getNumCompounds( i );
final int numCompounds = this.getNumCompounds( i );
ea = new BigDecimal[numCompounds + 1];
}
else {
@ -141,9 +137,4 @@ class ElemInfo {
return ea;
}
// public ARRAY toOracleArray(Connection conn) throws SQLException {
// ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor(
// TYPE_NAME, conn);
// return new ARRAY(arrayDescriptor, conn, this.triplets);
// }
}

View File

@ -46,7 +46,7 @@ enum ElementType {
private int interpretation = 2;
private boolean compound = false;
private boolean compound;
private ElementType(int etype, int interp) {
this.etype = etype;

View File

@ -36,9 +36,8 @@ class GetDimensionFunction extends SDOObjectMethod {
super( "Get_Dims", StandardBasicTypes.INTEGER );
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
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 "

View File

@ -36,9 +36,8 @@ class GetGeometryTypeFunction extends SDOObjectMethod {
super( "Get_GType", StandardBasicTypes.STRING );
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
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"

View File

@ -56,7 +56,6 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
private static Constructor<?> arrayConstructor;
private static Constructor<?> structConstructor;
static {
Object[] obj = findDescriptorCreator( "oracle.sql.StructDescriptor" );
structDescriptorClass = (Class<?>) obj[0];
@ -96,12 +95,8 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
private static Object[] findDescriptorCreator(String className) {
try {
Class clazz = ReflectHelper.classForName( className );
Method m = clazz.getMethod(
"createDescriptor",
String.class,
Connection.class
);
final Class clazz = ReflectHelper.classForName( className );
final Method m = clazz.getMethod( "createDescriptor", String.class, Connection.class );
return new Object[] { clazz, m };
}
catch ( ClassNotFoundException e ) {
@ -120,7 +115,7 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
connectionFinder = finder;
}
@Override
public Struct createStruct(SDOGeometry geom, Connection conn) throws SQLException {
Connection oracleConnection = null;
try {
@ -130,8 +125,8 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
throw new HibernateException( "Problem finding Oracle Connection", e );
}
Object structDescriptor = createStructDescriptor( SDOGeometry.getTypeName(), oracleConnection );
Object[] attributes = createDatumArray( 5 );
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() );
@ -144,19 +139,19 @@ public class OracleJDBCTypeFactory implements SQLTypeFactory {
return createStruct( structDescriptor, oracleConnection, attributes );
}
@Override
public Array createElemInfoArray(ElemInfo elemInfo, Connection conn) {
Object arrayDescriptor = createArrayDescriptor( ElemInfo.TYPE_NAME, 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 {
Object arrayDescriptor = createArrayDescriptor( Ordinates.TYPE_NAME, conn );
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 );

View File

@ -57,16 +57,22 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
SpatialDialect, Serializable {
public final static String SHORT_NAME = "oraclespatial";
private final static String CONNECTION_FINDER_PROPERTY = "CONNECTION-FINDER";
private final static Log LOG = LogFactory.make();
private String OGC_STRICT = "OGC_STRICT";
/**
* Short name for this dialect
*/
public static final String SHORT_NAME = "oraclespatial";
private static final String CONNECTION_FINDER_PROPERTY = "CONNECTION-FINDER";
private static final Log LOG = LogFactory.make();
private String ogcStrict = "OGC_STRICT";
private Map<String, Boolean> features = new HashMap<String, Boolean>();
/**
* Creates a dialect instance
*/
public OracleSpatial10gDialect() {
super();
// initialise features to default
features.put( OGC_STRICT, new Boolean( true ) );
features.put( ogcStrict, new Boolean( true ) );
// read configuration information from
// classpath
@ -134,10 +140,10 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
// keyword. (See also postgis documentation).
// portable spatial aggregate functions
registerFunction( "extent", new SpatialAggregationFunction("extent", false, OracleSpatialAggregate.EXTENT) );
registerFunction( "extent", new SpatialAggregationFunction( "extent", false, OracleSpatialAggregate.EXTENT ) );
//other common functions
registerFunction( "transform", new StandardSQLFunction("SDO_CS.TRANSFORM"));
registerFunction( "transform", new StandardSQLFunction( "SDO_CS.TRANSFORM" ) );
// Oracle specific Aggregate functions
registerFunction(
@ -172,13 +178,12 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
typeContributions.contributeType( new JTSGeometryType( SDOGeometryTypeDescriptor.INSTANCE ) );
}
public String getNativeSpatialRelateSQL(String arg1, String arg2,
int spatialRelation) {
String getNativeSpatialRelateSQL(String arg1, String arg2, int spatialRelation) {
String mask = "";
boolean negate = false;
switch ( spatialRelation ) {
case SpatialRelation.INTERSECTS:
mask = "ANYINTERACT"; // OGC Compliance verified
mask = "ANYINTERACT";
break;
case SpatialRelation.CONTAINS:
mask = "CONTAINS+COVERS";
@ -226,10 +231,8 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
return buffer.toString();
}
public String getOGCSpatialRelateSQL(String arg1, String arg2,
int spatialRelation) {
StringBuffer ogcFunction = new StringBuffer( "MDSYS." );
String getOGCSpatialRelateSQL(String arg1, String arg2, int spatialRelation) {
final StringBuffer ogcFunction = new StringBuffer( "MDSYS." );
switch ( spatialRelation ) {
case SpatialRelation.INTERSECTS:
ogcFunction.append( "OGC_INTERSECTS" );
@ -270,20 +273,18 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
}
public String getNativeSpatialAggregateSQL(String arg1, int aggregation) {
String getNativeSpatialAggregateSQL(String arg1, int aggregation) {
final StringBuffer aggregateFunction = new StringBuffer();
final SpatialAggregate sa = new SpatialAggregate( aggregation );
StringBuffer aggregateFunction = new StringBuffer();
SpatialAggregate sa = new SpatialAggregate( aggregation );
if ( sa._aggregateSyntax == null ) {
if ( sa.getAggregateSyntax() == null ) {
throw new IllegalArgumentException(
"Unknown Spatial Aggregation ("
+ aggregation + ")."
);
}
aggregateFunction.append( sa._aggregateSyntax );
aggregateFunction.append( sa.getAggregateSyntax() );
aggregateFunction.append( "(" );
if ( sa.isAggregateType() ) {
@ -304,8 +305,9 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
.append( ")" );
}
@Override
public String getSpatialFilterExpression(String columnName) {
StringBuffer buffer = new StringBuffer( "SDO_FILTER(" );
final StringBuffer buffer = new StringBuffer( "SDO_FILTER(" );
// String pureColumnName =
// columnName.substring(columnName.lastIndexOf(".")+1);
// buffer.append("\"" + pureColumnName.toUpperCase() + "\"");
@ -314,8 +316,8 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
return buffer.toString();
}
@Override
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
String sql = ( isOGCStrict() ? ( getOGCSpatialRelateSQL(
columnName, "?",
spatialRelation
@ -326,45 +328,36 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
return sql;
}
public String getSpatialAnalysisSQL(List args, int spatialAnalysisFunction,
boolean useFilter) {
return isOGCStrict() ? getOGCSpatialAnalysisSQL(
args,
spatialAnalysisFunction
) : getNativeSpatialAnalysisSQL(
String getSpatialAnalysisSQL(List args, int spatialAnalysisFunction, boolean useFilter) {
return isOGCStrict() ? getOGCSpatialAnalysisSQL( args, spatialAnalysisFunction ) : getNativeSpatialAnalysisSQL(
args,
spatialAnalysisFunction
);
}
public String getSpatialAggregateSQL(String columnName,
int spatialAggregateFunction) {
return getNativeSpatialAggregateSQL(
columnName,
spatialAggregateFunction
);
@Override
public String getSpatialAggregateSQL(String columnName, int spatialAggregateFunction) {
return getNativeSpatialAggregateSQL( columnName, spatialAggregateFunction );
}
@Override
public String getDWithinSQL(String columnName) {
throw new UnsupportedOperationException( "No DWithin in this dialect" );
}
@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
);
return String.format( "( MDSYS.ST_GEOMETRY(%s).ST_ISEMPTY() = %d )", columnName, isEmpty ? 1 : 0 );
}
private String getOGCSpatialAnalysisSQL(List args,
int spatialAnalysisFunction) {
private String getOGCSpatialAnalysisSQL(List args, int spatialAnalysisFunction) {
boolean[] geomArgs;
StringBuffer ogcFunction = new StringBuffer( "MDSYS." );
final StringBuffer ogcFunction = new StringBuffer( "MDSYS." );
boolean isGeomReturn = true;
switch ( spatialAnalysisFunction ) {
case SpatialAnalysis.BUFFER:
@ -434,52 +427,39 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
}
boolean isOGCStrict() {
return ( (Boolean) this.features.get( OGC_STRICT ) ).booleanValue();
return this.features.get( ogcStrict );
}
private void configure() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String propfileLoc = getClass().getCanonicalName() + ".properties";
URL propfile = loader.getResource( propfileLoc );
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
final String propfileLoc = getClass().getCanonicalName() + ".properties";
final URL propfile = loader.getResource( propfileLoc );
if ( propfile != null ) {
InputStream is = null;
LOG.info( "properties file found: " + propfile );
try {
loader.getResource( getClass().getCanonicalName() );
is = propfile.openStream();
PropertyFileReader reader = new PropertyFileReader( is );
Properties props = reader.getProperties();
final PropertyFileReader reader = new PropertyFileReader( is );
final Properties props = reader.getProperties();
// checking for connectionfinder
String ccn = props.getProperty( CONNECTION_FINDER_PROPERTY );
final String ccn = props.getProperty( CONNECTION_FINDER_PROPERTY );
if ( ccn != null ) {
try {
Class clazz = Thread.currentThread()
.getContextClassLoader().loadClass( ccn );
ConnectionFinder cf = (ConnectionFinder) clazz
.newInstance();
final Class clazz = Thread.currentThread().getContextClassLoader().loadClass( ccn );
final ConnectionFinder cf = (ConnectionFinder) clazz.newInstance();
OracleJDBCTypeFactory.setConnectionFinder( cf );
LOG.info( "Setting ConnectionFinder to " + ccn );
}
catch ( ClassNotFoundException e ) {
LOG.warn(
"Tried to set ConnectionFinder to " + ccn
+ ", but class not found."
);
LOG.warn( "Tried to set ConnectionFinder to " + ccn + ", but class not found." );
}
catch ( InstantiationException e ) {
LOG.warn(
"Tried to set ConnectionFinder to " + ccn
+ ", but couldn't instantiate."
);
LOG.warn( "Tried to set ConnectionFinder to " + ccn + ", but couldn't instantiate." );
}
catch ( IllegalAccessException e ) {
LOG
.warn(
"Tried to set ConnectionFinder to "
+ ccn
+ ", but got IllegalAcessException on instantiation."
);
LOG.warn( "Tried to set ConnectionFinder to " + ccn + ", but got IllegalAcessException on instantiation." );
}
}
@ -497,10 +477,12 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
}
}
@Override
public boolean supportsFiltering() {
return true;
}
@Override
public boolean supports(SpatialFunction function) {
return ( getFunctions().get( function.toString() ) != null );
}
@ -514,19 +496,12 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
super( "astext", StandardBasicTypes.STRING );
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuffer buf = new StringBuffer();
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"
);
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( "))" );
buf.append( "TO_CHAR(SDO_UTIL.TO_WKTGEOMETRY(" ).append( args.get( 0 ) ).append( "))" );
return buf.toString();
}
}
@ -545,8 +520,7 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
this.relation = relation;
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
public String render(Type firstArgumentType, final List args, final SessionFactoryImplementor factory) {
if ( args.size() < 2 ) {
throw new QueryException(
@ -554,7 +528,6 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
);
}
String srf;
return isOGCStrict() ?
getOGCSpatialRelateSQL(
(String) args.get( 0 ),
@ -580,7 +553,6 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements
this( name, null, analysis );
}
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) {
return isOGCStrict() ? getSpatialAnalysisSQL(
args, this.analysis,

View File

@ -43,7 +43,7 @@ class Ordinates {
return;
}
try {
Number[] ords = (Number[]) array.getArray();
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()
@ -60,13 +60,13 @@ class Ordinates {
}
public Double[] getOrdinatesArray(int startPosition, int endPosition) {
Double[] a = new Double[endPosition - startPosition];
final Double[] a = new Double[endPosition - startPosition];
System.arraycopy( this.ordinates, startPosition - 1, a, 0, a.length );
return a;
}
public Double[] getOrdinatesArray(int startPosition) {
Double[] a = new Double[this.ordinates.length - ( startPosition - 1 )];
final Double[] a = new Double[this.ordinates.length - ( startPosition - 1 )];
System.arraycopy( this.ordinates, startPosition - 1, a, 0, a.length );
return a;
}
@ -76,7 +76,7 @@ class Ordinates {
}
public void addOrdinates(Double[] ordinatesToAdd) {
Double[] newOrdinates = new Double[this.ordinates.length
final Double[] newOrdinates = new Double[this.ordinates.length
+ ordinatesToAdd.length];
System.arraycopy(
this.ordinates, 0, newOrdinates, 0,
@ -89,10 +89,4 @@ class Ordinates {
this.ordinates = newOrdinates;
}
// public ARRAY toOracleArray(Connection conn) throws SQLException {
// ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor(
// TYPE_NAME, conn);
// return new ARRAY(arrayDescriptor, conn, this.ordinates);
// }
}

View File

@ -42,7 +42,7 @@ class SDOBooleanType extends BooleanType {
}
public Object get(ResultSet rs, String name) throws SQLException {
String value = rs.getString( name );
final String value = rs.getString( name );
if ( rs.wasNull() ) {
return getDefaultValue();
}
@ -61,17 +61,12 @@ class SDOBooleanType extends BooleanType {
st.setNull( index, Types.VARCHAR );
}
else {
boolean bool = value.booleanValue();
st.setString( index, bool ? "TRUE" : "FALSE" );
st.setString( index, value ? "TRUE" : "FALSE" );
}
}
public String objectToSQLString(Boolean value, Dialect dialect) {
return value.booleanValue() ? "'TRUE'" : "'FALSE'";
return value ? "'TRUE'" : "'FALSE'";
}
// public int sqlType() {
// return Types.VARCHAR;
// }
}

View File

@ -29,7 +29,7 @@ class SDOGType {
private int dimension = 2;
private int lrsDimension = 0;
private int lrsDimension;
private TypeGeometry typeGeometry = TypeGeometry.UNKNOWN_GEOMETRY;
@ -105,18 +105,18 @@ class SDOGType {
}
public static SDOGType parse(int v) {
int dim = v / 1000;
final int dim = v / 1000;
v -= dim * 1000;
int lrsDim = v / 100;
final int lrsDim = v / 100;
v -= lrsDim * 100;
TypeGeometry typeGeometry = TypeGeometry.parse( v );
final TypeGeometry typeGeometry = TypeGeometry.parse( v );
return new SDOGType( dim, lrsDim, typeGeometry );
}
public static SDOGType parse(Object datum) {
try {
int v = ( (Number) datum ).intValue();
final int v = ( (Number) datum ).intValue();
return parse( v );
}
catch ( Exception e ) {

View File

@ -37,17 +37,12 @@ import org.hibernate.spatial.helper.FinderException;
class SDOGeometry {
private final static SQLTypeFactory TYPE_FACTORY = new OracleJDBCTypeFactory();
private static final SQLTypeFactory TYPE_FACTORY = new OracleJDBCTypeFactory();
private static final String SQL_TYPE_NAME = "MDSYS.SDO_GEOMETRY";
private SDOGType gtype;
private int srid;
private SDOPoint point;
private ElemInfo info;
private Ordinates ordinates;
@ -63,8 +58,8 @@ class SDOGeometry {
if ( array == null || java.lang.reflect.Array.getLength( array ) == 0 ) {
return "()";
}
int length = java.lang.reflect.Array.getLength( array );
StringBuilder stb = new StringBuilder();
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 ) );
@ -73,51 +68,107 @@ class SDOGeometry {
return stb.toString();
}
/**
* This joins an array of SDO_GEOMETRIES to a SDOGeometry of type
* COLLECTION
*
* @param SDOElements
* @param sdoElements The SDO_geometries to join into an SDO Geometry Collection
*
* @return
* @return The SDO Collection Geometry
*/
public static SDOGeometry join(SDOGeometry[] SDOElements) {
SDOGeometry SDOCollection = new SDOGeometry();
if ( SDOElements == null || SDOElements.length == 0 ) {
SDOCollection.setGType(
new SDOGType(
2, 0,
TypeGeometry.COLLECTION
)
);
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 {
SDOGeometry firstElement = SDOElements[0];
int dim = firstElement.getGType().getDimension();
int lrsDim = firstElement.getGType().getLRSDimension();
SDOCollection.setGType(
new SDOGType(
dim, lrsDim,
TypeGeometry.COLLECTION
)
);
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++ ) {
ElemInfo element = SDOElements[i].getInfo();
Double[] ordinates = SDOElements[i].getOrdinates()
.getOrdinateArray();
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 ) {
int shift = ordinatesOffset
- element.getOrdinatesOffset( 0 );
final int shift = ordinatesOffset - element.getOrdinatesOffset( 0 );
shiftOrdinateOffset( element, shift );
SDOCollection.addElement( element );
SDOCollection.addOrdinates( ordinates );
sdoCollection.addElement( element );
sdoCollection.addOrdinates( ordinates );
ordinatesOffset += ordinates.length;
}
}
}
return SDOCollection;
return sdoCollection;
}
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 static Struct store(SDOGeometry geom, Connection conn)
throws SQLException, FinderException {
return TYPE_FACTORY.createStruct( geom, conn );
}
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 ElemInfo getInfo() {
@ -156,38 +207,6 @@ class SDOGeometry {
return srid;
}
public void setSRID(int srid) {
this.srid = srid;
}
public static SDOGeometry load(Struct struct) {
Object[] data;
try {
data = struct.getAttributes();
}
catch ( SQLException e ) {
throw new RuntimeException( e );
}
SDOGeometry geom = new SDOGeometry();
geom.setGType( SDOGType.parse( data[0] ) );
geom.setSRID( data[1] );
if ( data[2] != null ) {
geom.setPoint( new SDOPoint( (Struct) data[2] ) );
}
geom.setInfo( new ElemInfo( (Array) data[3] ) );
geom.setOrdinates( new Ordinates( (Array) data[4] ) );
return geom;
}
public static Struct store(SDOGeometry geom, Connection conn)
throws SQLException, FinderException {
return TYPE_FACTORY.createStruct( geom, conn );
}
private void setSRID(Object datum) {
if ( datum == null ) {
this.srid = 0;
@ -201,6 +220,10 @@ class SDOGeometry {
}
}
public void setSRID(int srid) {
this.srid = srid;
}
public boolean isLRSGeometry() {
return gtype.isLRSGeometry();
}
@ -229,7 +252,7 @@ class SDOGeometry {
int i = 0;
while ( i < info.getSize() ) {
if ( info.getElementType( i ).isCompound() ) {
int numCompounds = info.getNumCompounds( i );
final int numCompounds = info.getNumCompounds( i );
i += 1 + numCompounds;
}
else {
@ -241,7 +264,7 @@ class SDOGeometry {
}
public String toString() {
StringBuilder stb = new StringBuilder();
final StringBuilder stb = new StringBuilder();
stb.append( "(" ).append( gtype ).append( "," ).append( srid ).append( "," )
.append( point ).append( "," ).append( info ).append( "," ).append(
ordinates
@ -276,14 +299,15 @@ class SDOGeometry {
*/
public SDOGeometry[] getElementGeometries() {
if ( getGType().getTypeGeometry() == TypeGeometry.COLLECTION ) {
List<SDOGeometry> elements = new ArrayList<SDOGeometry>();
final List<SDOGeometry> elements = new ArrayList<SDOGeometry>();
int i = 0;
while ( i < this.getNumElements() ) {
ElementType et = this.getInfo().getElementType( i );
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
if ( et.isExteriorRing() ) {
// then next element is the
// first non-interior ring
while ( next < this.getNumElements() ) {
if ( !this.getInfo().getElementType( next )
@ -296,28 +320,17 @@ class SDOGeometry {
else if ( et.isCompound() ) {
next = i + this.getInfo().getNumCompounds( i ) + 1;
}
SDOGeometry elemGeom = new SDOGeometry();
SDOGType elemGtype = deriveGTYPE(
this.getInfo()
.getElementType( i ), this
);
final SDOGeometry elemGeom = new SDOGeometry();
final SDOGType elemGtype = deriveGTYPE( this.getInfo().getElementType( i ), this );
elemGeom.setGType( elemGtype );
elemGeom.setSRID( this.getSRID() );
ElemInfo elemInfo = new ElemInfo(
this.getInfo()
.getElement( i )
);
shiftOrdinateOffset(
elemInfo, -elemInfo
.getOrdinatesOffset( 0 ) + 1
);
final ElemInfo elemInfo = new ElemInfo( this.getInfo().getElement( i ) );
shiftOrdinateOffset( elemInfo, -elemInfo.getOrdinatesOffset( 0 ) + 1 );
elemGeom.setInfo( elemInfo );
int startPosition = this.getInfo().getOrdinatesOffset( i );
final int startPosition = this.getInfo().getOrdinatesOffset( i );
Ordinates elemOrdinates = null;
if ( next < this.getNumElements() ) {
int endPosition = this.getInfo().getOrdinatesOffset(
next
);
final int endPosition = this.getInfo().getOrdinatesOffset( next );
elemOrdinates = new Ordinates(
this.getOrdinates()
.getOrdinatesArray( startPosition, endPosition )
@ -340,45 +353,4 @@ class SDOGeometry {
}
}
private static void shiftOrdinateOffset(ElemInfo elemInfo, int offset) {
for ( int i = 0; i < elemInfo.getSize(); i++ ) {
int newOffset = elemInfo.getOrdinatesOffset( i ) + offset;
elemInfo.setOrdinatesOffset( i, newOffset );
}
}
private static SDOGType deriveGTYPE(ElementType elementType,
SDOGeometry origGeom) {
switch ( elementType ) {
case POINT:
case ORIENTATION:
return new SDOGType(
origGeom.getDimension(), origGeom
.getLRSDimension(), TypeGeometry.POINT
);
case POINT_CLUSTER:
return new SDOGType(
origGeom.getDimension(), origGeom
.getLRSDimension(), TypeGeometry.MULTIPOINT
);
case LINE_ARC_SEGMENTS:
case LINE_STRAITH_SEGMENTS:
case COMPOUND_LINE:
return new SDOGType(
origGeom.getDimension(), origGeom
.getLRSDimension(), TypeGeometry.LINE
);
case COMPOUND_EXTERIOR_RING:
case EXTERIOR_RING_ARC_SEGMENTS:
case EXTERIOR_RING_CIRCLE:
case EXTERIOR_RING_RECT:
case EXTERIOR_RING_STRAIGHT_SEGMENTS:
return new SDOGType(
origGeom.getDimension(), origGeom
.getLRSDimension(), TypeGeometry.POLYGON
);
}
return null;
}
}

View File

@ -29,12 +29,17 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* Descriptor for the Oracle Spatial SDO_GEOMETRY type
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/22/11
*
*/
public class SDOGeometryTypeDescriptor implements SqlTypeDescriptor {
public static SDOGeometryTypeDescriptor INSTANCE = new SDOGeometryTypeDescriptor();
/**
* An instance of this class
*/
public static final SDOGeometryTypeDescriptor INSTANCE = new SDOGeometryTypeDescriptor();
@Override
public int getSqlType() {

View File

@ -49,13 +49,11 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/22/11
*/
public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
class SDOGeometryValueBinder<J> implements ValueBinder<J> {
private static final Log LOG = LogFactory.make();
private static final String BIND_MSG_TEMPLATE = "binding parameter [%s] as [%s] - %s";
private static final String NULL_BIND_MSG_TEMPLATE = "binding parameter [%s] as [%s] - <null>";
private final JavaTypeDescriptor<J> javaDescriptor;
@ -91,14 +89,14 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
)
);
}
Geometry jtsGeom = javaDescriptor.unwrap( value, Geometry.class, options );
Object dbGeom = toNative( jtsGeom, st.getConnection() );
final Geometry jtsGeom = javaDescriptor.unwrap( value, Geometry.class, options );
final Object dbGeom = toNative( jtsGeom, st.getConnection() );
st.setObject( index, dbGeom );
}
}
protected Object toNative(Geometry jtsGeom, Connection connection) {
SDOGeometry geom = convertJTSGeometry( jtsGeom );
final SDOGeometry geom = convertJTSGeometry( jtsGeom );
if ( geom != null ) {
try {
return SDOGeometry.store( geom, connection );
@ -151,26 +149,25 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
private SDOGeometry convertJTSGeometryCollection(
GeometryCollection collection) {
SDOGeometry[] SDOElements = new SDOGeometry[collection
.getNumGeometries()];
final SDOGeometry[] sdoElements = new SDOGeometry[collection.getNumGeometries()];
for ( int i = 0; i < collection.getNumGeometries(); i++ ) {
Geometry geom = collection.getGeometryN( i );
SDOElements[i] = convertJTSGeometry( geom );
final Geometry geom = collection.getGeometryN( i );
sdoElements[i] = convertJTSGeometry( geom );
}
SDOGeometry ccollect = SDOGeometry.join( SDOElements );
final SDOGeometry ccollect = SDOGeometry.join( sdoElements );
ccollect.setSRID( collection.getSRID() );
return ccollect;
}
private SDOGeometry convertJTSMultiPolygon(MultiPolygon multiPolygon) {
int dim = getCoordDimension( multiPolygon );
int lrsPos = getCoordinateLrsPosition( multiPolygon );
SDOGeometry geom = new SDOGeometry();
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 {
Polygon pg = (Polygon) multiPolygon.getGeometryN( i );
final Polygon pg = (Polygon) multiPolygon.getGeometryN( i );
addPolygon( geom, pg );
}
catch ( Exception e ) {
@ -183,17 +180,14 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
}
private SDOGeometry convertJTSLineString(LineString lineString) {
int dim = getCoordDimension( lineString );
int lrsPos = getCoordinateLrsPosition( lineString );
boolean isLrs = lrsPos > 0;
Double[] ordinates = convertCoordinates(
lineString.getCoordinates(),
dim, isLrs
);
SDOGeometry geom = new SDOGeometry();
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() );
ElemInfo info = new ElemInfo( 1 );
final ElemInfo info = new ElemInfo( 1 );
info.setElement( 0, 1, ElementType.LINE_STRAITH_SEGMENTS, 0 );
geom.setInfo( info );
geom.setOrdinates( new Ordinates( ordinates ) );
@ -202,13 +196,13 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
}
private SDOGeometry convertJTSMultiPoint(MultiPoint multiPoint) {
int dim = getCoordDimension( multiPoint );
int lrsDim = getCoordinateLrsPosition( multiPoint );
boolean isLrs = ( lrsDim != 0 );
SDOGeometry geom = new SDOGeometry();
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() );
ElemInfo info = new ElemInfo( multiPoint.getNumPoints() );
final ElemInfo info = new ElemInfo( multiPoint.getNumPoints() );
int oordinatesOffset = 1;
Double[] ordinates = new Double[] { };
for ( int i = 0; i < multiPoint.getNumPoints(); i++ ) {
@ -225,19 +219,15 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
}
private SDOGeometry convertJTSPoint(Point jtsGeom) {
int dim = getCoordDimension( jtsGeom );
final int dim = getCoordDimension( jtsGeom );
final int lrsDim = getCoordinateLrsPosition( jtsGeom );
final boolean isLrs = ( lrsDim != 0 );
int lrsDim = getCoordinateLrsPosition( jtsGeom );
boolean isLrs = ( lrsDim != 0 );
Double[] coord = convertCoordinates(
jtsGeom.getCoordinates(), dim,
isLrs
);
SDOGeometry geom = new SDOGeometry();
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() );
ElemInfo info = new ElemInfo( 1 );
final ElemInfo info = new ElemInfo( 1 );
info.setElement( 0, 1, ElementType.POINT, 1 );
geom.setInfo( info );
geom.setOrdinates( new Ordinates( coord ) );
@ -245,9 +235,9 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
}
private SDOGeometry convertJTSPolygon(Polygon polygon) {
int dim = getCoordDimension( polygon );
int lrsPos = getCoordinateLrsPosition( polygon );
SDOGeometry geom = new SDOGeometry();
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 );
@ -255,8 +245,8 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
}
private void addPolygon(SDOGeometry geom, Polygon polygon) {
int numInteriorRings = polygon.getNumInteriorRing();
ElemInfo info = new ElemInfo( numInteriorRings + 1 );
final int numInteriorRings = polygon.getNumInteriorRing();
final ElemInfo info = new ElemInfo( numInteriorRings + 1 );
int ordinatesPreviousOffset = 0;
if ( geom.getOrdinates() != null ) {
ordinatesPreviousOffset = geom.getOrdinates().getOrdinateArray().length;
@ -293,13 +283,13 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
private SDOGeometry convertJTSMultiLineString(
MultiLineString multiLineString) {
int dim = getCoordDimension( multiLineString );
int lrsDim = getCoordinateLrsPosition( multiLineString );
boolean isLrs = ( lrsDim != 0 );
SDOGeometry geom = new SDOGeometry();
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() );
ElemInfo info = new ElemInfo( multiLineString.getNumGeometries() );
final ElemInfo info = new ElemInfo( multiLineString.getNumGeometries() );
int oordinatesOffset = 1;
Double[] ordinates = new Double[] { };
for ( int i = 0; i < multiLineString.getNumGeometries(); i++ ) {
@ -318,10 +308,9 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
return geom;
}
private Double[] convertAddCoordinates(Double[] ordinates,
Coordinate[] coordinates, int dim, boolean isLrs) {
Double[] no = convertCoordinates( coordinates, dim, isLrs );
Double[] newordinates = new Double[ordinates.length + no.length];
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;
@ -341,18 +330,18 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
private Double[] convertCoordinates(Coordinate[] coordinates, int dim,
boolean isLrs) {
if (isLrs)
if ( isLrs ) {
throw new UnsupportedOperationException();
}
if ( dim > 4 ) {
throw new IllegalArgumentException(
"Dim parameter value cannot be greater than 4"
);
}
Double[] converted = new Double[coordinates.length * dim];
final Double[] converted = new Double[coordinates.length * dim];
for ( int i = 0; i < coordinates.length; i++ ) {
Coordinate c = coordinates[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 );
@ -395,7 +384,7 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
// This shall be cleaner if MCoordinate.getOrdinate(int ordinateIndex)
// is moved to the
// Coordinate class
Coordinate c = geom.getCoordinate();
final Coordinate c = geom.getCoordinate();
int d = 0;
if ( c != null ) {
if ( !Double.isNaN( c.x ) ) {
@ -429,8 +418,8 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
* @return the lrs position for the SDOGeometry.SDOGType
*/
private int getCoordinateLrsPosition(Geometry geom) {
Coordinate c = geom.getCoordinate();
int measurePos = 0;
final Coordinate c = geom.getCoordinate();
final int measurePos = 0;
// if ( c != null && !Double.isNaN( c.m ) ) {
// measurePos = ( Double.isNaN( c.z ) ) ? 3 : 4;
// }
@ -441,7 +430,7 @@ public class SDOGeometryValueBinder<J> implements ValueBinder<J> {
private Coordinate[] reverseRing(Coordinate[] ar) {
for ( int i = 0; i < ar.length / 2; i++ ) {
Coordinate cs = ar[i];
final Coordinate cs = ar[i];
ar[i] = ar[ar.length - 1 - i];
ar[ar.length - 1 - i] = cs;
}

View File

@ -45,7 +45,12 @@ import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicExtractor;
//TODO -- requires cleanup and must be made package local
/**
* ValueExtractor for SDO_GEOMETRY
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/22/11
*/
@ -54,25 +59,30 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
private static GeometryFactory geometryFactory = new GeometryFactory();
/**
* Creates instance
*
* @param javaDescriptor javadescriptor to use
*/
public SDOGeometryValueExtractor(JavaTypeDescriptor<X> javaDescriptor) {
super( javaDescriptor, SDOGeometryTypeDescriptor.INSTANCE );
}
@Override
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
Object geomObj = rs.getObject( name );
final Object geomObj = rs.getObject( name );
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
}
@Override
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
Object geomObj = statement.getObject( index );
final Object geomObj = statement.getObject( index );
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
}
@Override
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
Object geomObj = statement.getObject( name );
final Object geomObj = statement.getObject( name );
return getJavaDescriptor().wrap( toJTS( geomObj ), options );
}
@ -82,106 +92,110 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
return geometryFactory;
}
/**
* Converts an oracle to a JTS Geometry
*
* @param struct The Oracle STRUCT representation of an SDO_GEOMETRY
*
* @return The JTS Geometry value
*/
public Geometry toJTS(Object struct) {
if ( struct == null ) {
return null;
}
SDOGeometry SDOGeom = SDOGeometry.load( (Struct) struct );
return convert2JTS( SDOGeom );
final SDOGeometry sdogeom = SDOGeometry.load( (Struct) struct );
return convert2JTS( sdogeom );
}
private Geometry convert2JTS(SDOGeometry SDOGeom) {
int dim = SDOGeom.getGType().getDimension();
int lrsDim = SDOGeom.getGType().getLRSDimension();
private Geometry convert2JTS(SDOGeometry sdoGeom) {
final int dim = sdoGeom.getGType().getDimension();
final int lrsDim = sdoGeom.getGType().getLRSDimension();
Geometry result = null;
switch ( SDOGeom.getGType().getTypeGeometry() ) {
switch ( sdoGeom.getGType().getTypeGeometry() ) {
case POINT:
result = convertSDOPoint( SDOGeom );
result = convertSDOPoint( sdoGeom );
break;
case LINE:
result = convertSDOLine( dim, lrsDim, SDOGeom );
result = convertSDOLine( dim, lrsDim, sdoGeom );
break;
case POLYGON:
result = convertSDOPolygon( dim, lrsDim, SDOGeom );
result = convertSDOPolygon( dim, lrsDim, sdoGeom );
break;
case MULTIPOINT:
result = convertSDOMultiPoint( dim, lrsDim, SDOGeom );
result = convertSDOMultiPoint( dim, lrsDim, sdoGeom );
break;
case MULTILINE:
result = convertSDOMultiLine( dim, lrsDim, SDOGeom );
result = convertSDOMultiLine( dim, lrsDim, sdoGeom );
break;
case MULTIPOLYGON:
result = convertSDOMultiPolygon( dim, lrsDim, SDOGeom );
result = convertSDOMultiPolygon( dim, lrsDim, sdoGeom );
break;
case COLLECTION:
result = convertSDOCollection( dim, lrsDim, SDOGeom );
result = convertSDOCollection( dim, lrsDim, sdoGeom );
break;
default:
throw new IllegalArgumentException(
"Type not supported: "
+ SDOGeom.getGType().getTypeGeometry()
+ sdoGeom.getGType().getTypeGeometry()
);
}
result.setSRID( SDOGeom.getSRID() );
result.setSRID( sdoGeom.getSRID() );
return result;
}
private Geometry convertSDOCollection(int dim, int lrsDim,
SDOGeometry SDOGeom) {
List<Geometry> geometries = new ArrayList<Geometry>();
for ( SDOGeometry elemGeom : SDOGeom.getElementGeometries() ) {
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 ) );
}
Geometry[] geomArray = new Geometry[geometries.size()];
final Geometry[] geomArray = new Geometry[geometries.size()];
return getGeometryFactory().createGeometryCollection(
geometries.toArray( geomArray )
);
}
private Point convertSDOPoint(SDOGeometry SDOGeom) {
Double[] ordinates = SDOGeom.getOrdinates().getOrdinateArray();
private Point convertSDOPoint(SDOGeometry sdoGeom) {
Double[] ordinates = sdoGeom.getOrdinates().getOrdinateArray();
if ( ordinates.length == 0 ) {
if ( SDOGeom.getDimension() == 2 ) {
if ( sdoGeom.getDimension() == 2 ) {
ordinates = new Double[] {
SDOGeom.getPoint().x,
SDOGeom.getPoint().y
sdoGeom.getPoint().x,
sdoGeom.getPoint().y
};
}
else {
ordinates = new Double[] {
SDOGeom.getPoint().x,
SDOGeom.getPoint().y, SDOGeom.getPoint().z
sdoGeom.getPoint().x,
sdoGeom.getPoint().y, sdoGeom.getPoint().z
};
}
}
CoordinateSequence cs = convertOrdinateArray( ordinates, SDOGeom );
Point point = getGeometryFactory().createPoint( cs );
return point;
final CoordinateSequence cs = convertOrdinateArray( ordinates, sdoGeom );
return getGeometryFactory().createPoint( cs );
}
private MultiPoint convertSDOMultiPoint(int dim, int lrsDim,
SDOGeometry SDOGeom) {
Double[] ordinates = SDOGeom.getOrdinates().getOrdinateArray();
CoordinateSequence cs = convertOrdinateArray( ordinates, SDOGeom );
MultiPoint multipoint = getGeometryFactory().createMultiPoint( 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) {
boolean lrs = SDOGeom.isLRSGeometry();
ElemInfo info = SDOGeom.getInfo();
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() ) {
int numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
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 ) );
cs = add( cs, getElementCSeq( i, sdoGeom, false ) );
i++;
}
}
@ -196,41 +210,38 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
}
private MultiLineString convertSDOMultiLine(int dim, int lrsDim,
SDOGeometry SDOGeom) {
boolean lrs = SDOGeom.isLRSGeometry();
private MultiLineString convertSDOMultiLine(int dim, int lrsDim, SDOGeometry sdoGeom) {
final boolean lrs = sdoGeom.isLRSGeometry();
if ( lrs ) {
throw new UnsupportedOperationException();
}
ElemInfo info = SDOGeom.getInfo();
LineString[] lines = new LineString[SDOGeom.getInfo().getSize()];
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() ) {
int numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
LineString line = getGeometryFactory().createLineString( cs );
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 ) );
LineString line = getGeometryFactory().createLineString( cs );
cs = add( cs, getElementCSeq( i, sdoGeom, false ) );
final LineString line = getGeometryFactory().createLineString( cs );
lines[i] = line;
i++;
}
}
MultiLineString mls = getGeometryFactory().createMultiLineString( lines );
return mls;
return getGeometryFactory().createMultiLineString( lines );
}
private Geometry convertSDOPolygon(int dim, int lrsDim, SDOGeometry SDOGeom) {
private Geometry convertSDOPolygon(int dim, int lrsDim, SDOGeometry sdoGeom) {
LinearRing shell = null;
LinearRing[] holes = new LinearRing[SDOGeom.getNumElements() - 1];
ElemInfo info = SDOGeom.getInfo();
final LinearRing[] holes = new LinearRing[sdoGeom.getNumElements() - 1];
final ElemInfo info = sdoGeom.getInfo();
int i = 0;
int idxInteriorRings = 0;
while ( i < info.getSize() ) {
@ -238,10 +249,10 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
int numCompounds = 0;
if ( info.getElementType( i ).isCompound() ) {
numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, sdoGeom ) );
}
else {
cs = add( cs, getElementCSeq( i, SDOGeom, false ) );
cs = add( cs, getElementCSeq( i, sdoGeom, false ) );
}
if ( info.getElementType( i ).isInteriorRing() ) {
holes[idxInteriorRings] = getGeometryFactory()
@ -256,11 +267,10 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
return getGeometryFactory().createPolygon( shell, holes );
}
private MultiPolygon convertSDOMultiPolygon(int dim, int lrsDim,
SDOGeometry SDOGeom) {
private MultiPolygon convertSDOMultiPolygon(int dim, int lrsDim, SDOGeometry sdoGeom) {
List<LinearRing> holes = new ArrayList<LinearRing>();
List<Polygon> polygons = new ArrayList<Polygon>();
ElemInfo info = SDOGeom.getInfo();
final List<Polygon> polygons = new ArrayList<Polygon>();
final ElemInfo info = sdoGeom.getInfo();
LinearRing shell = null;
int i = 0;
while ( i < info.getSize() ) {
@ -268,18 +278,18 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
int numCompounds = 0;
if ( info.getElementType( i ).isCompound() ) {
numCompounds = info.getNumCompounds( i );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, SDOGeom ) );
cs = add( cs, getCompoundCSeq( i + 1, i + numCompounds, sdoGeom ) );
}
else {
cs = add( cs, getElementCSeq( i, SDOGeom, false ) );
cs = add( cs, getElementCSeq( i, sdoGeom, false ) );
}
if ( info.getElementType( i ).isInteriorRing() ) {
LinearRing lr = getGeometryFactory().createLinearRing( cs );
final LinearRing lr = getGeometryFactory().createLinearRing( cs );
holes.add( lr );
}
else {
if ( shell != null ) {
Polygon polygon = getGeometryFactory().createPolygon(
final Polygon polygon = getGeometryFactory().createPolygon(
shell,
holes.toArray( new LinearRing[holes.size()] )
);
@ -292,16 +302,13 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
i += 1 + numCompounds;
}
if ( shell != null ) {
Polygon polygon = getGeometryFactory().createPolygon(
final Polygon polygon = getGeometryFactory().createPolygon(
shell,
holes.toArray( new LinearRing[holes.size()] )
);
polygons.add( polygon );
}
MultiPolygon multiPolygon = getGeometryFactory().createMultiPolygon(
polygons.toArray( new Polygon[polygons.size()] )
);
return multiPolygon;
return getGeometryFactory().createMultiPolygon( polygons.toArray( new Polygon[polygons.size()] ) );
}
/**
@ -309,27 +316,22 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
*
* @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.
* @param sdoGeom the SDOGeometry that holds the compound element.
*
* @return
*/
private CoordinateSequence getCompoundCSeq(int idxFirst, int idxLast,
SDOGeometry SDOGeom) {
private CoordinateSequence getCompoundCSeq(int idxFirst, int idxLast, SDOGeometry sdoGeom) {
CoordinateSequence cs = null;
for ( int i = idxFirst; i <= idxLast; i++ ) {
// pop off the last element as it is added with the next
// coordinate sequence
if ( cs != null && cs.size() > 0 ) {
Coordinate[] coordinates = cs.toCoordinateArray();
Coordinate[] newCoordinates = new Coordinate[coordinates.length - 1];
System.arraycopy(
coordinates, 0, newCoordinates, 0,
coordinates.length - 1
);
cs = getGeometryFactory().getCoordinateSequenceFactory()
.create( newCoordinates );
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 ) ) );
cs = add( cs, getElementCSeq( i, sdoGeom, ( i < idxLast ) ) );
}
return cs;
}
@ -338,36 +340,32 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
* Gets the CoordinateSequence corresponding to an element.
*
* @param i
* @param SDOGeom
* @param sdoGeom
*
* @return
*/
private CoordinateSequence getElementCSeq(int i, SDOGeometry SDOGeom,
boolean hasNextSE) {
ElementType type = SDOGeom.getInfo().getElementType( i );
Double[] elemOrdinates = extractOrdinatesOfElement(
i, SDOGeom,
hasNextSE
);
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 );
cs = convertOrdinateArray( elemOrdinates, sdoGeom );
}
else if ( type.isArcSegment() || type.isCircle() ) {
Coordinate[] linearized = linearize(
elemOrdinates, SDOGeom
.getDimension(), SDOGeom.isLRSGeometry(), type.isCircle()
);
cs = getGeometryFactory().getCoordinateSequenceFactory().create(
linearized
final Coordinate[] linearized = linearize(
elemOrdinates,
sdoGeom.getDimension(),
sdoGeom.isLRSGeometry(),
type.isCircle()
);
cs = getGeometryFactory().getCoordinateSequenceFactory().create( linearized );
}
else if ( type.isRect() ) {
cs = convertOrdinateArray( elemOrdinates, SDOGeom );
Coordinate ll = cs.getCoordinate( 0 );
Coordinate ur = cs.getCoordinate( 1 );
Coordinate lr = new Coordinate( ur.x, ll.y );
Coordinate ul = new Coordinate( ll.x, ur.y );
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 } );
@ -386,46 +384,43 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
return cs;
}
private CoordinateSequence add(CoordinateSequence seq1,
CoordinateSequence seq2) {
private CoordinateSequence add(CoordinateSequence seq1, CoordinateSequence seq2) {
if ( seq1 == null ) {
return seq2;
}
if ( seq2 == null ) {
return seq1;
}
Coordinate[] c1 = seq1.toCoordinateArray();
Coordinate[] c2 = seq2.toCoordinateArray();
Coordinate[] c3 = new Coordinate[c1.length + c2.length];
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) {
int start = SDOGeom.getInfo().getOrdinatesOffset( element );
if ( element < SDOGeom.getInfo().getSize() - 1 ) {
int end = SDOGeom.getInfo().getOrdinatesOffset( element + 1 );
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();
end += sdoGeom.getDimension();
}
return SDOGeom.getOrdinates().getOrdinatesArray( start, end );
return sdoGeom.getOrdinates().getOrdinatesArray( start, end );
}
else {
return SDOGeom.getOrdinates().getOrdinatesArray( start );
return sdoGeom.getOrdinates().getOrdinatesArray( start );
}
}
private CoordinateSequence convertOrdinateArray(Double[] oordinates,
SDOGeometry SDOGeom) {
int dim = SDOGeom.getDimension();
Coordinate[] coordinates = new Coordinate[oordinates.length / dim];
int zDim = SDOGeom.getZDimension() - 1;
int lrsDim = SDOGeom.getLRSDimension() - 1;
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(
@ -434,7 +429,7 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
);
}
else if ( dim == 3 ) {
if ( SDOGeom.isLRSGeometry() ) {
if ( sdoGeom.isLRSGeometry() ) {
throw new UnsupportedOperationException();
// coordinates[i] = MCoordinate.create2dWithMeasure(
@ -445,8 +440,10 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
}
else {
coordinates[i] = new Coordinate(
oordinates[i * dim], // X
oordinates[i * dim + 1], // Y
//X
oordinates[i * dim],
//Y
oordinates[i * dim + 1],
oordinates[i * dim + zDim]
); // Z
}
@ -482,12 +479,11 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
*
* @return linearized interpolation of arcs or circle
*/
private Coordinate[] linearize(Double[] arcOrdinates, int dim, boolean lrs,
boolean entireCirlce) {
private Coordinate[] linearize(Double[] arcOrdinates, int dim, boolean lrs, boolean entireCirlce) {
Coordinate[] linearizedCoords = new Coordinate[0];
// CoordDim is the dimension that includes only non-measure (X,Y,Z)
// ordinates in its value
int coordDim = lrs ? dim - 1 : dim;
final int coordDim = lrs ? dim - 1 : dim;
// this only works with 2-Dimensional geometries, since we use
// JGeometry linearization;
if ( coordDim != 2 ) {
@ -499,15 +495,15 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
int numOrd = dim;
while ( numOrd < arcOrdinates.length ) {
numOrd = numOrd - dim;
double x1 = arcOrdinates[numOrd++];
double y1 = arcOrdinates[numOrd++];
double m1 = lrs ? arcOrdinates[numOrd++] : Double.NaN;
double x2 = arcOrdinates[numOrd++];
double y2 = arcOrdinates[numOrd++];
double m2 = lrs ? arcOrdinates[numOrd++] : Double.NaN;
double x3 = arcOrdinates[numOrd++];
double y3 = arcOrdinates[numOrd++];
double m3 = lrs ? arcOrdinates[numOrd++] : Double.NaN;
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 ) {
@ -545,18 +541,10 @@ public class SDOGeometryValueExtractor<X> extends BasicExtractor<X> {
resultBegin = 0;
}
int destPos = linearizedCoords.length;
Coordinate[] tmpCoords = new Coordinate[linearizedCoords.length
+ coords.length - resultBegin];
System.arraycopy(
linearizedCoords, 0, tmpCoords, 0,
linearizedCoords.length
);
System.arraycopy(
coords, resultBegin, tmpCoords, destPos,
coords.length - resultBegin
);
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;

View File

@ -88,7 +88,7 @@ class SDOObjectMethod implements SQLFunction {
*/
public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException {
StringBuffer buf = new StringBuffer();
final StringBuffer buf = new StringBuffer();
if ( args.isEmpty() ) {
throw new QueryException(
"First Argument in arglist must be object to which method is applied"

View File

@ -89,7 +89,7 @@ class SDOObjectProperty implements SQLFunction {
public String render(Type firstArgtype, List args, SessionFactoryImplementor factory)
throws QueryException {
StringBuffer buf = new StringBuffer();
final StringBuffer buf = new StringBuffer();
if ( args.isEmpty() ) {
throw new QueryException(
"First Argument in arglist must be object of which property is queried"

View File

@ -29,15 +29,15 @@ import java.sql.Struct;
* creation-date: Jul 1, 2010
*/
class SDOPoint {
public double x = 0.0;
public double x;
public double y = 0.0;
public double y;
public double z = Double.NaN;
public SDOPoint(Struct struct) {
try {
Object[] data = struct.getAttributes();
final Object[] data = struct.getAttributes();
this.x = ( (Number) data[0] ).doubleValue();
this.y = ( (Number) data[1] ).doubleValue();
if ( data[2] != null ) {
@ -50,7 +50,7 @@ class SDOPoint {
}
public String toString() {
StringBuilder stb = new StringBuilder();
final StringBuilder stb = new StringBuilder();
stb.append( "(" ).append( x ).append( "," ).append( y ).append( "," ).append(
z
).append( ")" );

View File

@ -26,12 +26,22 @@ 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;

View File

@ -29,11 +29,11 @@ import org.hibernate.spatial.dialect.oracle.criterion.OracleSpatialAggregate;
*/
class SpatialAggregate {
boolean _aggregateType;
private boolean aggregateType;
String _aggregateSyntax;
private String aggregateSyntax;
private final String SDO_AGGR = "SDO_AGGR_";
private static final String SDO_AGGR = "SDO_AGGR_";
SpatialAggregate() {
}
@ -45,43 +45,43 @@ class SpatialAggregate {
switch ( aggregation ) {
case org.hibernate.spatial.SpatialAggregate.EXTENT:
specificAggrSyntax = "MBR";
_aggregateType = false;
aggregateType = false;
break;
case OracleSpatialAggregate.LRS_CONCAT:
specificAggrSyntax = "LRS_CONCAT";
_aggregateType = true;
aggregateType = true;
break;
case OracleSpatialAggregate.CENTROID:
specificAggrSyntax = "CENTROID";
_aggregateType = true;
aggregateType = true;
break;
case OracleSpatialAggregate.CONCAT_LINES:
specificAggrSyntax = "CONCAT_LINES";
_aggregateType = false;
aggregateType = false;
break;
case OracleSpatialAggregate.UNION:
specificAggrSyntax = "UNION";
_aggregateType = true;
aggregateType = true;
break;
case OracleSpatialAggregate.CONVEXHULL:
specificAggrSyntax = "CONVEXHULL";
_aggregateType = true;
aggregateType = true;
break;
default:
specificAggrSyntax = null;
break;
}
if ( specificAggrSyntax != null ) {
_aggregateSyntax = SDO_AGGR + specificAggrSyntax;
aggregateSyntax = SDO_AGGR + specificAggrSyntax;
}
}
public boolean isAggregateType() {
return _aggregateType;
return aggregateType;
}
public String getAggregateSyntax() {
return _aggregateSyntax;
return aggregateSyntax;
}
}

View File

@ -31,7 +31,7 @@ enum TypeGeometry {
5
), MULTILINE( 6 ), MULTIPOLYGON( 7 ), SOLID( 8 ), MULTISOLID( 9 );
private int gtype = 0;
private int gtype;
TypeGeometry(int gtype) {
this.gtype = gtype;

View File

@ -44,8 +44,7 @@ class WrappedOGCFunction extends StandardSQLFunction {
* @param geomArrays indicates which argument places are occupied by
* sdo_geometries
*/
WrappedOGCFunction(final String name, final Type type,
final boolean[] geomArrays) {
WrappedOGCFunction(final String name, final Type type, final boolean[] geomArrays) {
super( name, type );
if ( isSpatial( type ) ) {
throw new IllegalArgumentException(
@ -67,10 +66,8 @@ class WrappedOGCFunction extends StandardSQLFunction {
this.isGeometryTyped = true;
}
public String render(Type firstArgumentType, final List args,
final SessionFactoryImplementor factory) {
StringBuilder buf = new StringBuilder();
public String render(Type firstArgumentType, final List args, final SessionFactoryImplementor factory) {
final StringBuilder buf = new StringBuilder();
buf.append( "MDSYS." ).append( getName() ).append( "(" );
for ( int i = 0; i < args.size(); i++ ) {
if ( i > 0 ) {

View File

@ -24,17 +24,34 @@ package org.hibernate.spatial.dialect.oracle.criterion;
import org.hibernate.spatial.SpatialAggregate;
/**
* Defines types of OracleSpatialAggregate
* Defines types of Oracle Spatial aggregate functions
*
* @author Karel Maesen, Geovise BVBA
*/
public interface OracleSpatialAggregate extends SpatialAggregate {
/**
* LRS_CONCAT aggregate function
*/
public static int LRS_CONCAT = 100;
/**
* CENTROID aggregate function
*/
public static int CENTROID = 101;
/**
* CONCAT_LINES aggregate function
*/
public static int CONCAT_LINES = 102;
/**
* UNION aggregate function
*/
public static int UNION = 103;
/**
* CONVEXHULL aggregate function
*/
public static int CONVEXHULL = 104;
}

View File

@ -37,27 +37,31 @@ import org.hibernate.type.Type;
public class OracleSpatialProjection extends SimpleProjection {
private static final long serialVersionUID = 1L;
private final String propertyName;
private final int aggregate;
/**
* Constructs an instance for the specified aggregate function and property
*
* @param aggregate The aggregate function (a value of {@code OracleSpatialAggregate}
* @param propertyName The name of the geometry property
*/
public OracleSpatialProjection(int aggregate, String propertyName) {
this.propertyName = propertyName;
this.aggregate = aggregate;
}
public String toSqlString(Criteria criteria, int position,
CriteriaQuery criteriaQuery) throws HibernateException {
@Override
public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException {
SessionFactoryImplementor factory = criteriaQuery.getFactory();
String[] columns = criteriaQuery.getColumnsUsingProjection(
final SessionFactoryImplementor factory = criteriaQuery.getFactory();
final String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria,
this.propertyName
);
Dialect dialect = factory.getDialect();
final Dialect dialect = factory.getDialect();
if ( dialect instanceof SpatialDialect ) {
SpatialDialect seDialect = (SpatialDialect) dialect;
final SpatialDialect seDialect = (SpatialDialect) dialect;
return new StringBuffer(
seDialect.getSpatialAggregateSQL(
@ -74,11 +78,13 @@ public class OracleSpatialProjection extends SimpleProjection {
}
@Override
public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
return new Type[] { criteriaQuery.getType( criteria, this.propertyName ) };
}
@Override
public String toString() {
return aggregate + "(" + propertyName + ")";
}

View File

@ -30,6 +30,15 @@ public final class OracleSpatialProjections {
private OracleSpatialProjections() {
}
/**
* Applies a "CONCAT_LRS" projection to the named property.
*
* @param propertyName The name of the geometry property
*
* @return OracleSpatialProjection
*
* @see OracleSpatialProjection
*/
public static OracleSpatialProjection concatLrs(String propertyName) {
return new OracleSpatialProjection(
OracleSpatialAggregate.LRS_CONCAT,
@ -37,6 +46,15 @@ public final class OracleSpatialProjections {
);
}
/**
* Applies a "CENTROID" projection to the named property.
*
* @param propertyName The name of the geometry property
*
* @return OracleSpatialProjection
*
* @see OracleSpatialProjection
*/
public static OracleSpatialProjection centroid(String propertyName) {
return new OracleSpatialProjection(
OracleSpatialAggregate.CENTROID,
@ -44,6 +62,15 @@ public final class OracleSpatialProjections {
);
}
/**
* Applies a "CONCAT_LINES" projection to the named property.
*
* @param propertyName The name of the geometry property
*
* @return OracleSpatialProjection
*
* @see OracleSpatialProjection
*/
public static OracleSpatialProjection concatLines(String propertyName) {
return new OracleSpatialProjection(
OracleSpatialAggregate.CONCAT_LINES,
@ -51,8 +78,17 @@ public final class OracleSpatialProjections {
);
}
public static OracleSpatialProjection projection(int projection,
String propertyName) {
/**
* Applies the specified {@code OracleSpatialProjection} to the named property.
*
* @param projection The projection function
* @param propertyName The name of the geometry property
*
* @return OracleSpatialProjection
*
* @see OracleSpatialProjection
*/
public static OracleSpatialProjection projection(int projection, String propertyName) {
return new OracleSpatialProjection( projection, propertyName );
}
}

View File

@ -29,24 +29,32 @@ import org.hibernate.criterion.Criterion;
import org.hibernate.engine.spi.TypedValue;
/**
* A static factory class for creating <code>Criterion</code> instances that
* correspond to Oracle Spatial "native" spatial operators.
* A static factory class for spatial criteria using the Oracle Spatial native spatial operators
* for the SDO_GEOMTRY type.
*
* @author Karel Maesen
*/
public class OracleSpatialRestrictions {
private OracleSpatialRestrictions() {
}
/**
* Apply the "SDO_FILTER" constraint to the specified property, using the specified parameters
*
* @param propertyName The name of the proerty
* @param geom The search geometry to use in the constraint
* @param param The function parameters for the SDO_FILTER
*
* @return The Criterion
*/
@SuppressWarnings("serial")
public static Criterion SDOFilter(String propertyName, Geometry geom,
SDOParameterMap param) {
public static Criterion SDOFilter(String propertyName, Geometry geom, SDOParameterMap param) {
return new OracleSpatialCriterion( propertyName, geom, param ) {
@Override
public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, this.propertyName
);
StringBuilder sql = new StringBuilder( "SDO_FILTER(" );
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, this.propertyName );
final StringBuilder sql = new StringBuilder( "SDO_FILTER(" );
sql.append( columns[0] ).append( "," ).append( "?" );
if ( param != null && !param.isEmpty() ) {
sql.append( "," ).append( param.toQuotedString() );
@ -57,28 +65,47 @@ public class OracleSpatialRestrictions {
};
}
/**
* Apply the "SDO_FILTER" constraint to the specified property, using the specified parameters
*
* @param propertyName The name of the proerty
* @param geom The search geometry to use in the constraint
* @param minResolution The min_resolution parameter
* @param maxResolution The max_resolution parameter
*
* @return The Criterion
*/
@SuppressWarnings("serial")
public static Criterion SDOFilter(String propertyName, Geometry geom,
Double minResolution, Double maxResolution) {
public static Criterion SDOFilter(String propertyName, Geometry geom, Double minResolution, Double maxResolution) {
if ( minResolution == null && maxResolution == null ) {
return SDOFilter( propertyName, geom, null );
}
else {
SDOParameterMap param = new SDOParameterMap();
final SDOParameterMap param = new SDOParameterMap();
param.setMinResolution( minResolution );
param.setMaxResolution( maxResolution );
return SDOFilter( propertyName, geom, param );
}
}
/**
* Apply the "SDO_NN" constraint to the specified property, using the specified parameters
*
* @param propertyName The name of the property
* @param geom The search geometry to use in the constraint
* @param distance The distance parameter
* @param numResults The num_results parameter
* @param unit The unit parameter
*
* @return The Criterion
*/
@SuppressWarnings("serial")
public static Criterion SDONN(String propertyName, Geometry geom,
Double distance, Integer numResults, String unit) {
public static Criterion SDONN(String propertyName, Geometry geom, Double distance, Integer numResults, String unit) {
if ( distance == null && numResults == null && unit == null ) {
return SDONN( propertyName, geom, null );
}
else {
SDOParameterMap param = new SDOParameterMap();
final SDOParameterMap param = new SDOParameterMap();
param.setDistance( distance );
param.setSdoNumRes( numResults );
param.setUnit( unit );
@ -86,17 +113,22 @@ public class OracleSpatialRestrictions {
}
}
/**
* Apply the "SDO_NN" constraint to the specified property, using the specified {@code SDOParameterMap}
*
* @param propertyName The name of the property
* @param geom The search geometry to use in the constraint
* @param param The parameters for the constraint function
*
* @return The Criterion
*/
@SuppressWarnings("serial")
public static Criterion SDONN(String propertyName, Geometry geom,
SDOParameterMap param) {
public static Criterion SDONN(String propertyName, Geometry geom, SDOParameterMap param) {
return new OracleSpatialCriterion( propertyName, geom, param ) {
@Override
public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, this.propertyName
);
StringBuilder sql = new StringBuilder( "SDO_NN(" );
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, this.propertyName );
final StringBuilder sql = new StringBuilder( "SDO_NN(" );
sql.append( columns[0] ).append( "," ).append( "?" );
if ( param != null && !param.isEmpty() ) {
sql.append( "," ).append( param.toQuotedString() );
@ -107,17 +139,22 @@ public class OracleSpatialRestrictions {
};
}
/**
* Apply the "SDO_RELATE" constraint to the specified property, using the specified {@code SDOParameterMap}
*
* @param propertyName The name of the property
* @param geom The search geometry to use in the constraint
* @param param The parameters for the constraint function
*
* @return The Criterion
*/
@SuppressWarnings("serial")
public static Criterion SDORelate(String propertyName, Geometry geom,
SDOParameterMap param) {
public static Criterion SDORelate(String propertyName, Geometry geom, SDOParameterMap param) {
return new OracleSpatialCriterion( propertyName, geom, param ) {
@Override
public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, this.propertyName
);
StringBuilder sql = new StringBuilder( "SDO_RELATE(" );
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, this.propertyName );
final StringBuilder sql = new StringBuilder( "SDO_RELATE(" );
sql.append( columns[0] ).append( "," ).append( "?" );
if ( param != null && !param.isEmpty() ) {
sql.append( "," ).append( param.toQuotedString() );
@ -128,28 +165,43 @@ public class OracleSpatialRestrictions {
};
}
/**
* Apply the "SDO_RELATE" constraint to the specified property, using the specified parameters.
*
* @param propertyName The name of the property
* @param geom The search geometry to use in the constraint
* @param mask The mask parameter
* @param minResolution The min_resolution parameter
* @param maxResolution The max_resolution parameter
*
* @return The Criterion
*/
@SuppressWarnings("serial")
public static Criterion SDORelate(String propertyName, Geometry geom,
RelationshipMask[] mask, Double minResolution, Double maxResolution) {
SDOParameterMap param = new SDOParameterMap();
public static Criterion SDORelate(String propertyName, Geometry geom, RelationshipMask[] mask, Double minResolution, Double maxResolution) {
final SDOParameterMap param = new SDOParameterMap();
param.setMask( RelationshipMask.booleanCombination( mask ) );
param.setMinResolution( minResolution );
param.setMaxResolution( maxResolution );
return SDORelate( propertyName, geom, param );
}
/**
* Apply the "SDO_WITHIN_DISTANCE" constraint to the specified property, using the specified {@code SDOParameterMap}.
*
* @param propertyName The name of the property
* @param geom The search geometry to use in the constraint
* @param param The parameters for the constraint function
*
* @return The Criterion
*/
@SuppressWarnings("serial")
public static Criterion SDOWithinDistance(String propertyName,
Geometry geom, SDOParameterMap param) {
public static Criterion SDOWithinDistance(String propertyName, Geometry geom, SDOParameterMap param) {
return new OracleSpatialCriterion( propertyName, geom, param ) {
@Override
public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, this.propertyName
);
StringBuilder sql = new StringBuilder( "SDO_WITHIN_DISTANCE(" );
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, this.propertyName );
final StringBuilder sql = new StringBuilder( "SDO_WITHIN_DISTANCE(" );
sql.append( columns[0] ).append( "," ).append( "?" );
if ( param != null && !param.isEmpty() ) {
sql.append( "," ).append( param.toQuotedString() );
@ -160,8 +212,17 @@ public class OracleSpatialRestrictions {
};
}
public static Criterion SDOWithinDistance(String propertyName,
Geometry geom, Double distance, SDOParameterMap param) {
/**
* Apply the "SDO_WITHIN_DISTANCE" constraint to the specified property, using the specified {@code SDOParameterMap}.
*
* @param propertyName The name of the property
* @param geom The search geometry to use in the constraint
* @param distance The distance parameter for the constraint function
* @param param The parameters for the constraint function
*
* @return The Criterion
*/
public static Criterion SDOWithinDistance(String propertyName, Geometry geom, Double distance, SDOParameterMap param) {
if ( param == null ) {
param = new SDOParameterMap();
}
@ -172,13 +233,10 @@ public class OracleSpatialRestrictions {
abstract class OracleSpatialCriterion implements Criterion {
protected String propertyName;
protected Geometry value;
protected SDOParameterMap param;
public OracleSpatialCriterion(String propertyName, Geometry value,
SDOParameterMap param) {
public OracleSpatialCriterion(String propertyName, Geometry value, SDOParameterMap param) {
this.propertyName = propertyName;
this.value = value;
this.param = param;
@ -191,17 +249,12 @@ abstract class OracleSpatialCriterion implements Criterion {
* org.hibernate.criterion.CriteriaQuery)
*/
public TypedValue[] getTypedValues(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException {
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] {
criteriaQuery.getTypedValue(
criteria,
propertyName, value
)
criteriaQuery.getTypedValue( criteria, propertyName, value )
};
}
abstract public String toSqlString(Criteria criteria,
CriteriaQuery criteriaQuery) throws HibernateException;
public abstract String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException;
}

View File

@ -20,9 +20,66 @@
*/
package org.hibernate.spatial.dialect.oracle.criterion;
/**
* Enumerates the types of spatial relationship masks supported by Oracle Spatial.
*/
public enum RelationshipMask {
TOUCH, OVERLAPBYDISJOINT, OVERLAPBYINTERSECT, EQUAL, INSIDE, COVEREDBY, CONTAINS, COVERS, ANYINTERACT, ON;
/**
* The "touch" relationship
*/
TOUCH,
/**
* The "overlapbydisjoint" relationship
*/
OVERLAPBYDISJOINT,
/**
* The "overlapbyintersect" relationship
*/
OVERLAPBYINTERSECT,
/**
* The "equal" relationship
*/
EQUAL,
/**
* The "inside" relationship
*/
INSIDE,
/**
* The "coveredby" relationship
*/
COVEREDBY,
/**
* The "contains" relationship
*/
CONTAINS,
/**
* The "covers" relationship
*/
COVERS,
/**
* The "anyinteract" relationship
*/
ANYINTERACT,
/**
* The "on" relationship
*/
ON;
/**
* Combines the passed "{@code RelationshipMask}s
*
* @param masks The array of masks to combine
* @return A {@code String} representing the combined relationship mask
*/
public static String booleanCombination(RelationshipMask[] masks) {
String strMask = null;
for ( RelationshipMask relationshipMask : masks ) {

View File

@ -24,142 +24,218 @@ import java.util.HashMap;
import java.util.Map;
/**
* This class represents the parameters that can be passed into Oracle's Spatial
* Operators
* Represents the parameters that can be passed into Oracle's Spatial operators
*
* @author Karel Maesen
*/
public class SDOParameterMap {
/**
* The distance parameter
*/
public static final String DISTANCE = "distance";
/**
* The sdo_batch_size parameter
*/
public static final String SDO_BATCH_SIZE = "sdo_batch_size";
/**
* The sdo_num_res parameter
*/
public static final String SDO_NUM_RES = "sdo_num_res";
/**
* The unit parameter
*/
public static final String UNIT = "unit";
/**
* The min_resolution parameter
*/
public static final String MIN_RESOLUTION = "min_resolution";
/**
* The max_resolution parameter
*/
public static final String MAX_RESOLUTION = "max_resolution";
/**
* The mask parameter
*/
public static final String MASK = "mask";
/**
* The querytype parameter
*/
public static final String QUERYTYPE = "querytype";
private Map<String, Object> params = new HashMap<String, Object>();
/**
* Constructs an empty instance
*/
public SDOParameterMap() {
}
/**
* Checks whether this instance is empty
*
* @return true if empty, false otherwise
*/
public boolean isEmpty() {
return this.params.isEmpty();
}
public void setDistance(Double distance) {
if ( distance != null ) {
params.put( DISTANCE, distance );
}
}
public Double getDistance() {
return (Double) params.get( DISTANCE );
}
public void removeDistance() {
params.remove( DISTANCE );
/**
* Adds the distance parameter with the specified value
*
* @param distance The value for the distance parameter
*/
public void setDistance(Double distance) {
if ( distance != null ) {
params.put( DISTANCE, distance );
}
}
public void setSdoBatchSize(Integer size) {
if ( size != null ) {
params.put( SDO_BATCH_SIZE, size );
}
/**
* Removes the distance parameter
*/
public void removeDistance() {
params.remove( DISTANCE );
}
public Integer getSdoBatchSize() {
return (Integer) params.get( SDO_BATCH_SIZE );
}
public void removeSdoBatchSize() {
params.remove( SDO_BATCH_SIZE );
/**
* Adds the sdo_batch_size parameter with the specified value
*
* @param size The value for the sdo_batch_size parameter
*/
public void setSdoBatchSize(Integer size) {
if ( size != null ) {
params.put( SDO_BATCH_SIZE, size );
}
}
public void setSdoNumRes(Integer size) {
if ( size != null ) {
params.put( SDO_NUM_RES, size );
}
/**
* Removes the sdo_batch_size parameter
*/
public void removeSdoBatchSize() {
params.remove( SDO_BATCH_SIZE );
}
public Integer getSdoNumRes() {
return (Integer) params.get( SDO_NUM_RES );
}
public void removeSdoNumRes() {
params.remove( SDO_NUM_RES );
/**
* Adds the sdo_num_res parameter with the specified value
*
* @param res The value for the sdo_num_res parameter
*/
public void setSdoNumRes(Integer res) {
if ( res != null ) {
params.put( SDO_NUM_RES, res );
}
}
public void setUnit(String unit) {
if ( unit != null ) {
this.params.put( UNIT, unit );
}
/**
* Removes the sdo_num_res parameter
*/
public void removeSdoNumRes() {
params.remove( SDO_NUM_RES );
}
public String getUnit() {
return (String) this.params.get( UNIT );
}
public void removeUnit() {
this.params.remove( UNIT );
/**
* Adds the unit parameter with the specified value
*
* @param unit The value for the unit parameter
*/
public void setUnit(String unit) {
if ( unit != null ) {
this.params.put( UNIT, unit );
}
}
public void setMaxResolution(Double res) {
if ( res != null ) {
params.put( MAX_RESOLUTION, res );
}
/**
* Removes the unit parameter
*/
public void removeUnit() {
this.params.remove( UNIT );
}
public Double getMaxResolution() {
return (Double) params.get( MAX_RESOLUTION );
}
public void removeMaxResolution() {
params.remove( MAX_RESOLUTION );
/**
* Adds the max_resolution parameter with the specified value
*
* @param res The value for the max_resolution parameter
*/
public void setMaxResolution(Double res) {
if ( res != null ) {
params.put( MAX_RESOLUTION, res );
}
}
public void setMinResolution(Double res) {
if ( res != null ) {
params.put( MIN_RESOLUTION, res );
}
/**
* Removes the max_resolution parameter
*/
public void removeMaxResolution() {
params.remove( MAX_RESOLUTION );
}
public Double getMinResolution() {
return (Double) params.get( MIN_RESOLUTION );
}
public void removeMinResolution() {
params.remove( MIN_RESOLUTION );
/**
* Adds the min_resolution parameter with the specified value
*
* @param res The value for the min_resolution parameter
*/
public void setMinResolution(Double res) {
if ( res != null ) {
params.put( MIN_RESOLUTION, res );
}
}
public void setMask(String mask) {
if ( mask != null ) {
this.params.put( MASK, mask );
}
/**
* Removes the min_resolution parameter
*/
public void removeMinResolution() {
params.remove( MIN_RESOLUTION );
}
public String getMask() {
return (String) this.params.get( MASK );
}
/**
* Adds the mask parameter with the specified value
*
* @param mask The value for the mask parameter
*/
public void setMask(String mask) {
if ( mask != null ) {
this.params.put( MASK, mask );
}
}
/**
* Removes the mask parameter
*/
public void removeMask() {
this.params.remove( MASK );
}
public void setQueryType(String queryType) {
if ( queryType != null ) {
this.params.put( QUERYTYPE, queryType );
}
}
/**
* Adds the querytype parameter with value "FILTER"
*/
public void setQueryTypeToFilter() {
this.params.put( QUERYTYPE, "FILTER" );
}
@ -168,12 +244,34 @@ public class SDOParameterMap {
return (String) this.params.get( QUERYTYPE );
}
/**
* Adds the querytype parameter with the specified value
*
* @param queryType The value for the quertype parameter
*/
public void setQueryType(String queryType) {
if ( queryType != null ) {
this.params.put( QUERYTYPE, queryType );
}
}
/**
* Removes the querytype parameter
*/
public void removeQueryType() {
this.params.remove( QUERYTYPE );
}
/**
* Returns all parameters contained in this instance as a quoted String containing
* the <parameter name>=<parameter value> pairs separated by spaces.
*
* The return format is as expected by the various SDO_GEOMETRY spatial functions.
*
* @return String
*/
public String toQuotedString() {
StringBuilder stb = new StringBuilder();
final StringBuilder stb = new StringBuilder();
if ( params.isEmpty() ) {
return "";
}
@ -182,8 +280,7 @@ public class SDOParameterMap {
if ( params.get( paramName ) == null ) {
continue;
}
stb.append( paramName ).append( "=" ).append( params.get( paramName ) )
.append( " " );
stb.append( paramName ).append( "=" ).append( params.get( paramName ) ).append( " " );
}
stb.deleteCharAt( stb.length() - 1 );
stb.append( '\'' );

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
A criterion API for Oracle Spatial (10g and later) using SDOGeometry.
</p>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This package contains the spatial extensions for the Oracle 10g dialect. It currently supports only the SDO_GEOMETRY
spatial data type.
</p>
</body>
</html>

View File

@ -44,12 +44,17 @@ import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* Type Descriptor for the Postgis Geometry type
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 7/27/11
*
*/
public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
/**
* An instance of this class
*/
public static final PGGeometryTypeDescriptor INSTANCE = new PGGeometryTypeDescriptor();
@Override
@ -68,9 +73,9 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException {
WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.POSTGIS_EWKB_1 );
Geometry geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
byte[] bytes = encoder.encode( geometry, ByteOrder.NDR ).toByteArray();
final WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.POSTGIS_EWKB_1 );
final Geometry geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
final byte[] bytes = encoder.encode( geometry, ByteOrder.NDR ).toByteArray();
st.setBytes( index, bytes );
}
@ -106,7 +111,7 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
ByteBuffer buffer = null;
if ( object instanceof PGobject ) {
buffer = ByteBuffer.from( ( (PGobject) object ).getValue() );
WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.POSTGIS_EWKB_1 );
final WkbDecoder decoder = Wkb.newDecoder( Wkb.Dialect.POSTGIS_EWKB_1 );
return decoder.decode( buffer );
}
throw new IllegalStateException( "Received object of type " + object.getClass().getCanonicalName() );

View File

@ -34,17 +34,18 @@ import org.hibernate.spatial.SpatialRelation;
import org.hibernate.type.StandardBasicTypes;
/**
* Extends the PostgreSQLDialect by also including information on spatial
* operators, constructors and processing functions.
* A Dialect for Postgresql with support for the Postgis spatial types, functions and operators (release 1.3 or higher)
*
* @author Karel Maesen
*/
public class PostgisDialect extends PostgreSQL82Dialect implements SpatialDialect {
/**
* Creates an instance
*/
public PostgisDialect() {
super();
registerTypesAndFunctions();
}
@ -239,6 +240,7 @@ public class PostgisDialect extends PostgreSQL82Dialect implements SpatialDialec
);
}
@Override
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
switch ( spatialRelation ) {
case SpatialRelation.WITHIN:
@ -266,27 +268,32 @@ public class PostgisDialect extends PostgreSQL82Dialect implements SpatialDialec
}
@Override
public String getDWithinSQL(String columnName) {
return "ST_DWithin(" + columnName + ",?,?)";
}
@Override
public String getHavingSridSQL(String columnName) {
return "( ST_srid(" + columnName + ") = ?)";
}
@Override
public String getIsEmptySQL(String columnName, boolean isEmpty) {
String emptyExpr = " ST_IsEmpty(" + columnName + ") ";
final String emptyExpr = " ST_IsEmpty(" + columnName + ") ";
return isEmpty ? emptyExpr : "( NOT " + emptyExpr + ")";
}
@Override
public String getSpatialFilterExpression(String columnName) {
return "(" + columnName + " && ? ) ";
}
@Override
public String getSpatialAggregateSQL(String columnName, int aggregation) {
switch ( aggregation ) {
case SpatialAggregate.EXTENT:
StringBuilder stbuf = new StringBuilder();
final StringBuilder stbuf = new StringBuilder();
stbuf.append( "extent(" ).append( columnName ).append( ")" );
return stbuf.toString();
default:
@ -297,10 +304,12 @@ public class PostgisDialect extends PostgreSQL82Dialect implements SpatialDialec
}
}
@Override
public boolean supportsFiltering() {
return true;
}
@Override
public boolean supports(SpatialFunction function) {
return ( getFunctions().get( function.toString() ) != null );
}

View File

@ -27,10 +27,13 @@ import org.hibernate.spatial.SpatialRelation;
import org.hibernate.type.StandardBasicTypes;
/**
* A Dialect for Postgresql with support for the Postgis spatial types, functions and operators (release 1.x - 1.3)
*
* @author Karel Maesen, Geovise BVBA
* creation-date: Dec 18, 2010
*/
public class PostgisNoSQLMM extends PostgisDialect {
@Override
protected void registerTypesAndFunctions() {
@ -183,7 +186,7 @@ public class PostgisNoSQLMM extends PostgisDialect {
);
registerFunction(
"symdifference",
new StandardSQLFunction( "symdifference")
new StandardSQLFunction( "symdifference" )
);
registerFunction(
"geomunion", new StandardSQLFunction(
@ -218,42 +221,31 @@ public class PostgisNoSQLMM extends PostgisDialect {
@Override
public String getIsEmptySQL(String columnName, boolean isEmpty) {
String emptyExpr = "( isempty(" + columnName + ")) ";
final String emptyExpr = "( isempty(" + columnName + ")) ";
return isEmpty ? emptyExpr : "not " + emptyExpr;
}
public String getSpatialRelateSQL(String columnName, int spatialRelation,
boolean hasFilter) {
@Override
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
switch ( spatialRelation ) {
case SpatialRelation.WITHIN:
return hasFilter ? "(" + columnName + " && ? AND within("
+ columnName + ", ?))" : " within(" + columnName + ",?)";
return "(" + columnName + " && ? AND within(" + columnName + ", ?))";
case SpatialRelation.CONTAINS:
return hasFilter ? "(" + columnName + " && ? AND contains("
+ columnName + ", ?))" : " contains(" + columnName + ", ?)";
return "(" + columnName + " && ? AND contains(" + columnName + ", ?))";
case SpatialRelation.CROSSES:
return hasFilter ? "(" + columnName + " && ? AND crosses("
+ columnName + ", ?))" : " crosses(" + columnName + ", ?)";
return "(" + columnName + " && ? AND crosses(" + columnName + ", ?))";
case SpatialRelation.OVERLAPS:
return hasFilter ? "(" + columnName + " && ? AND overlaps("
+ columnName + ", ?))" : " overlaps(" + columnName + ", ?)";
return "(" + columnName + " && ? AND overlaps(" + columnName + ", ?))";
case SpatialRelation.DISJOINT:
return hasFilter ? "(" + columnName + " && ? AND disjoint("
+ columnName + ", ?))" : " disjoint(" + columnName + ", ?)";
return "(" + columnName + " && ? AND disjoint(" + columnName + ", ?))";
case SpatialRelation.INTERSECTS:
return hasFilter ? "(" + columnName + " && ? AND intersects("
+ columnName + ", ?))" : " intersects(" + columnName
+ ", ?)";
return "(" + columnName + " && ? AND intersects(" + columnName + ", ?))";
case SpatialRelation.TOUCHES:
return hasFilter ? "(" + columnName + " && ? AND touches("
+ columnName + ", ?))" : " touches(" + columnName + ", ?)";
return "(" + columnName + " && ? AND touches(" + columnName + ", ?))";
case SpatialRelation.EQUALS:
return hasFilter ? "(" + columnName + " && ? AND equals("
+ columnName + ", ?))" : " equals(" + columnName + ", ?)";
return "(" + columnName + " && ? AND equals(" + columnName + ", ?))";
default:
throw new IllegalArgumentException(
"Spatial relation is not known by this dialect"
);
throw new IllegalArgumentException( "Spatial relation is not known by this dialect" );
}
}

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This package contains the spatial extensions for the Postgresql dialect.
</p>
<p>We provide two dialects for postgis</p>
<ul>
<li>PostgisDialect: this dialect uses the SQL/MM convention for spatial function names (using a 'ST_' prefix).
It is recommended for use with Postgis version 1.3 or higher</li>
<li>PostgisNoSQLMM: this dialect does not use the SQL/MM convention. Use it with older, pre-1.3 versions of Postgis</li>
</ul>
</body>
</html>

View File

@ -41,11 +41,16 @@ import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* Type descriptor for the SQL Server 2008 Geometry type.
*
* @author Karel Maesen, Geovise BVBA
* creation-date: 8/23/11
*/
public class SqlServer2008GeometryTypeDescriptor implements SqlTypeDescriptor {
/**
* An instance of the descrtiptor
*/
public static final SqlServer2008GeometryTypeDescriptor INSTANCE = new SqlServer2008GeometryTypeDescriptor();
@Override
@ -63,8 +68,8 @@ public class SqlServer2008GeometryTypeDescriptor implements SqlTypeDescriptor {
return new BasicBinder<X>(javaTypeDescriptor, this){
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
Geometry geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
byte[] bytes = Encoders.encode( geometry );
final Geometry geometry = getJavaDescriptor().unwrap( value, Geometry.class, options );
final byte[] bytes = Encoders.encode( geometry );
st.setObject( index, bytes );
}

View File

@ -40,8 +40,14 @@ import org.hibernate.type.StandardBasicTypes;
*/
public class SqlServer2008SpatialDialect extends SQLServer2008Dialect implements SpatialDialect {
public final static String SHORT_NAME = "sqlserver";
/**
* The short name for this dialect
*/
public static final String SHORT_NAME = "sqlserver";
/**
* Constructs an instance
*/
public SqlServer2008SpatialDialect() {
super();
@ -114,6 +120,7 @@ public class SqlServer2008SpatialDialect extends SQLServer2008Dialect implements
typeContributions.contributeType( new JTSGeometryType( SqlServer2008GeometryTypeDescriptor.INSTANCE ) );
}
@Override
public String getSpatialRelateSQL(String columnName, int spatialRelation) {
final String stfunction;
switch ( spatialRelation ) {
@ -150,31 +157,38 @@ public class SqlServer2008SpatialDialect extends SQLServer2008Dialect implements
return columnName + "." + stfunction + "(?) = 1";
}
@Override
public String getSpatialFilterExpression(String columnName) {
return columnName + ".Filter(?) = 1";
}
@Override
public String getSpatialAggregateSQL(String columnName, int aggregation) {
throw new UnsupportedOperationException( "No spatial aggregate SQL functions." );
}
@Override
public String getDWithinSQL(String columnName) {
throw new UnsupportedOperationException( "SQL Server has no DWithin function." );
}
@Override
public String getHavingSridSQL(String columnName) {
return columnName + ".STSrid = (?)";
}
@Override
public String getIsEmptySQL(String columnName, boolean isEmpty) {
String base = "(" + columnName + ".STIsEmpty() ";
final String base = "(" + columnName + ".STIsEmpty() ";
return isEmpty ? base + " = 1 )" : base + " = 0 )";
}
@Override
public boolean supportsFiltering() {
return true;
}
@Override
public boolean supports(SpatialFunction function) {
return ( getFunctions().get( function.toString() ) != null );
}

View File

@ -10,7 +10,7 @@ import org.hibernate.type.Type;
* @author Karel Maesen, Geovise BVBA
* creation-date: 4/8/13
*/
public class SqlServerMethod extends StandardSQLFunction {
class SqlServerMethod extends StandardSQLFunction {
public SqlServerMethod(String name) {
super( name );
@ -18,19 +18,20 @@ public class SqlServerMethod extends StandardSQLFunction {
@Override
public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) {
StringBuffer buf = new StringBuffer();
if (arguments.size() < 1) {
buf.append(getName()).append("()");
} else {
buf.append( arguments.get( 0 ) ).append(".")
.append(getName()).append("(");
final StringBuffer buf = new StringBuffer();
if ( arguments.size() < 1 ) {
buf.append( getName() ).append( "()" );
}
else {
buf.append( arguments.get( 0 ) ).append( "." )
.append( getName() ).append( "(" );
for ( int i = 1; i < arguments.size(); i++ ) {
buf.append(arguments.get(i));
if (i < arguments.size()-1) {
buf.append(",");
buf.append( arguments.get( i ) );
if ( i < arguments.size() - 1 ) {
buf.append( "," );
}
}
buf.append(")");
buf.append( ")" );
}
return buf.toString();
}

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This package contains the spatial extensions for the SqlServer2008 dialect.
</p>
<p>Currently, only the Geometry type is supported.</p>
</body>
</html>

View File

@ -24,12 +24,17 @@ package org.hibernate.spatial.helper;
* This exception is thrown when Hibernate Spatial fails to find a required
* resource.
*
* @author maesenka
* @author Karel Maesen, Geovise BVBA
*/
public class FinderException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Creates an instance with the specified message
*
* @param msg the error message for this exception
*/
public FinderException(String msg) {
super( msg );
}

View File

@ -20,14 +20,9 @@
*/
package org.hibernate.spatial.helper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.spatial.Log;
@ -41,49 +36,38 @@ import org.hibernate.spatial.LogFactory;
public class PropertyFileReader {
private static final Log LOG = LogFactory.make();
/**
* pattern for comment lines. If it matches, it is a comment.
*/
private static final Pattern nonCommentPattern = Pattern
.compile( "^([^#]+)" );
private static final Pattern NON_COMMENT_PATTERN = Pattern.compile( "^([^#]+)" );
private InputStream is = null;
private InputStream is;
/**
* Constructs an instance from the specified {@code InputStream}
* @param is The inputstream
*/
public PropertyFileReader(InputStream is) {
this.is = is;
}
/**
* Returns the properties
* @return {@code Properties}
* @throws IOException if an error occurs when reading from the {@code InputStream}
*/
public Properties getProperties() throws IOException {
if ( is == null ) {
return null;
}
Properties props = new Properties();
final Properties props = new Properties();
props.load( is );
return props;
}
/**
* Returns the non-comment lines in a file.
*
* @return set of non-comment strings.
*
* @throws IOException
* Closes this instance, and closes the underlying {@code InputStream}
*/
public Set<String> getNonCommentLines() throws IOException {
Set<String> lines = new HashSet<String>();
String line;
BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
while ( ( line = reader.readLine() ) != null ) {
line = line.trim();
Matcher m = nonCommentPattern.matcher( line );
if ( m.find() ) {
lines.add( m.group().trim() );
}
}
return lines;
}
public void close() {
try {
this.is.close();

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This package contains general helper classes.
</p>
</body>
</html>

View File

@ -27,22 +27,21 @@ import java.util.List;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.PrecisionModel;
//TODO -- verify code, and put into Geolatte.
/**
* This class provides operations for handling the usage of Circles and arcs in
* Geometries.
* <p/>
* Date: Oct 15, 2007
*
* @author Tom Acree
*/
public class Circle {
private static final double TWO_PI = Math.PI * 2;
private Coordinate center = new Coordinate( 0.0, 0.0 );
private double radius = 0;
private PrecisionModel precisionModel = new PrecisionModel();
private double radius;
// Constructors **********************************************************
private PrecisionModel precisionModel = new PrecisionModel();
/**
* Creates a circle whose center is at the origin and whose radius is 0.
@ -79,18 +78,13 @@ public class Circle {
* To this end, we check the box and set the side of the box to the larger
* dimension of the rectangle
*
* @param xLeft
* @param yUpper
* @param xRight
* @param yLower
* @param xLeft The leftmost x coordinate
* @param yUpper The uppermost y coordinate
* @param xRight The rightmost x coordinate
* @param yLower The lowest y coordinate
*/
public Circle(double xLeft, double yUpper, double xRight, double yLower) {
double side = Math.min(
Math.abs( xRight - xLeft ), Math.abs(
yLower
- yUpper
)
);
final double side = Math.min( Math.abs( xRight - xLeft ), Math.abs( yLower - yUpper ) );
this.center.x = Math.min( xRight, xLeft ) + side / 2;
this.center.y = Math.min( yUpper, yLower ) + side / 2;
this.radius = side / 2;
@ -100,9 +94,9 @@ public class Circle {
* Three point method of circle construction. All three points must be on
* the circumference of the circle.
*
* @param point1
* @param point2
* @param point3
* @param point1 The first point
* @param point2 The second point
* @param point3 The third point
*/
public Circle(Coordinate point1, Coordinate point2, Coordinate point3) {
initThreePointCircle( point1, point2, point3 );
@ -112,25 +106,137 @@ public class Circle {
* Three point method of circle construction. All three points must be on
* the circumference of the circle.
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param x3
* @param y3
* @param x1 The x coordinate of the first point
* @param y1 The y coordinate of the first point
* @param x2 The x coordinate of the second point
* @param y2 The y coordinate of the second point
* @param x3 The x coordinate of the third point
* @param y3 The y coordinate of the third point
*/
public Circle(double x1, double y1, double x2, double y2, double x3,
double y3) {
public Circle(double x1, double y1, double x2, double y2, double x3, double y3) {
this(
new Coordinate( x1, y1 ), new Coordinate( x2, y2 ), new Coordinate(
x3,
y3
)
new Coordinate( x1, y1 ), new Coordinate( x2, y2 ), new Coordinate( x3, y3 )
);
}
/**
* shift the center of the circle by delta X and delta Y
* Given 2 points defining an arc on the circle, interpolates the circle
* into a collection of points that provide connected chords that
* approximate the arc based on the tolerance value. The tolerance value
* specifies the maximum distance between a chord and the circle.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
* @param tolerence maximum distance between the center of the chord and the outer
* edge of the circle
*
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeArc(double x1, double y1, double x2, double y2, double x3, double y3, double tolerence) {
final Coordinate p1 = new Coordinate( x1, y1 );
final Coordinate p2 = new Coordinate( x2, y2 );
final Coordinate p3 = new Coordinate( x3, y3 );
return new Circle( p1, p2, p3 ).linearizeArc( p1, p2, p3, tolerence );
}
/**
* Given 2 points defining an arc on the circle, interpolates the circle
* into a collection of points that provide connected chords that
* approximate the arc based on the tolerance value. This method uses a
* tolerence value of 1/100 of the length of the radius.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
*
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeArc(double x1, double y1, double x2, double y2, double x3, double y3) {
final Coordinate p1 = new Coordinate( x1, y1 );
final Coordinate p2 = new Coordinate( x2, y2 );
final Coordinate p3 = new Coordinate( x3, y3 );
final Circle c = new Circle( p1, p2, p3 );
final double tolerence = 0.01 * c.getRadius();
return c.linearizeArc( p1, p2, p3, tolerence );
}
/**
* Given a circle defined by the 3 points, creates a linearized
* interpolation of the circle starting and ending on the first coordinate.
* This method uses a tolerence value of 1/100 of the length of the radius.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
*
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeCircle(double x1, double y1, double x2, double y2, double x3, double y3) {
final Coordinate p1 = new Coordinate( x1, y1 );
final Coordinate p2 = new Coordinate( x2, y2 );
final Coordinate p3 = new Coordinate( x3, y3 );
final Circle c = new Circle( p1, p2, p3 );
final double tolerence = 0.01 * c.getRadius();
return c.linearizeArc( p1, p2, p1, tolerence );
}
/**
* Returns an angle between 0 and 2*PI. For example, 4*PI would get returned
* as 2*PI since they are equivalent.
*
* @param angle an angle in radians to normalize
*
* @return an angle between 0 and 2*PI
*/
public static double normalizeAngle(double angle) {
final double maxRadians = 2 * Math.PI;
if ( angle >= 0 && angle <= maxRadians ) {
return angle;
}
if ( angle < 0 ) {
return maxRadians - Math.abs( angle );
}
else {
return angle % maxRadians;
}
}
/**
* Returns the angle between the angles a1 and a2 in radians. Angle is
* calculated in the counterclockwise direction.
*
* @param a1 first angle
* @param a2 second angle
*
* @return the angle between a1 and a2 in the clockwise direction
*/
public static double subtractAngles(double a1, double a2) {
if ( a1 < a2 ) {
return a2 - a1;
}
else {
return TWO_PI - Math.abs( a2 - a1 );
}
}
/**
* Shifts the center of the circle by delta X and delta Y
*
* @param deltaX The shift along the X-coordinate axis
* @param deltaY The shift along the Y-coordinate axis
*/
public void shift(double deltaX, double deltaY) {
this.center.x = this.center.x + deltaX;
@ -138,7 +244,10 @@ public class Circle {
}
/**
* Move the circle to a new center
* Moves the circle to a new center
*
* @param x The x coordinate of the new center
* @param y The y coordinate of the new center
*/
public void move(double x, double y) {
this.center.x = x;
@ -155,11 +264,10 @@ public class Circle {
* @param p2 A point on the desired circle
* @param p3 A point on the desired circle
*/
private void initThreePointCircle(Coordinate p1, Coordinate p2,
Coordinate p3) {
private void initThreePointCircle(Coordinate p1, Coordinate p2, Coordinate p3) {
double a13, b13, c13;
double a23, b23, c23;
double x = 0., y = 0., rad = 0.;
double x, y, rad;
// begin pre-calculations for linear system reduction
a13 = 2 * ( p1.x - p3.x );
@ -169,7 +277,7 @@ public class Circle {
b23 = 2 * ( p2.y - p3.y );
c23 = ( p2.y * p2.y - p3.y * p3.y ) + ( p2.x * p2.x - p3.x * p3.x );
// testsuite-suite to be certain we have three distinct points passed
double smallNumber = 0.01;
final double smallNumber = 0.01;
if ( ( Math.abs( a13 ) < smallNumber && Math.abs( b13 ) < smallNumber )
|| ( Math.abs( a13 ) < smallNumber && Math.abs( b13 ) < smallNumber ) ) {
// // points too close so set to default circle
@ -204,83 +312,6 @@ public class Circle {
return this.radius;
}
/**
* Given 2 points defining an arc on the circle, interpolates the circle
* into a collection of points that provide connected chords that
* approximate the arc based on the tolerance value. The tolerance value
* specifies the maximum distance between a chord and the circle.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
* @param tolerence maximum distance between the center of the chord and the outer
* edge of the circle
*
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeArc(double x1, double y1, double x2,
double y2, double x3, double y3, double tolerence) {
Coordinate p1 = new Coordinate( x1, y1 );
Coordinate p2 = new Coordinate( x2, y2 );
Coordinate p3 = new Coordinate( x3, y3 );
return new Circle( p1, p2, p3 ).linearizeArc( p1, p2, p3, tolerence );
}
/**
* Given 2 points defining an arc on the circle, interpolates the circle
* into a collection of points that provide connected chords that
* approximate the arc based on the tolerance value. This method uses a
* tolerence value of 1/100 of the length of the radius.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
*
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeArc(double x1, double y1, double x2,
double y2, double x3, double y3) {
Coordinate p1 = new Coordinate( x1, y1 );
Coordinate p2 = new Coordinate( x2, y2 );
Coordinate p3 = new Coordinate( x3, y3 );
Circle c = new Circle( p1, p2, p3 );
double tolerence = 0.01 * c.getRadius();
return c.linearizeArc( p1, p2, p3, tolerence );
}
/**
* Given a circle defined by the 3 points, creates a linearized
* interpolation of the circle starting and ending on the first coordinate.
* This method uses a tolerence value of 1/100 of the length of the radius.
*
* @param x1 x coordinate of point 1
* @param y1 y coordinate of point 1
* @param x2 x coordinate of point 2
* @param y2 y coordinate of point 2
* @param x3 x coordinate of point 3
* @param y3 y coordinate of point 3
*
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public static Coordinate[] linearizeCircle(double x1, double y1, double x2,
double y2, double x3, double y3) {
Coordinate p1 = new Coordinate( x1, y1 );
Coordinate p2 = new Coordinate( x2, y2 );
Coordinate p3 = new Coordinate( x3, y3 );
Circle c = new Circle( p1, p2, p3 );
double tolerence = 0.01 * c.getRadius();
return c.linearizeArc( p1, p2, p1, tolerence );
}
/**
* Given 2 points defining an arc on the circle, interpolates the circle
* into a collection of points that provide connected chords that
@ -296,24 +327,20 @@ public class Circle {
* @return an ordered list of Coordinates representing a series of chords
* approximating the arc.
*/
public Coordinate[] linearizeArc(Coordinate p1, Coordinate p2,
Coordinate p3, double tolerence) {
Arc arc = createArc( p1, p2, p3 );
List<Coordinate> result = linearizeInternal( null, arc, tolerence );
public Coordinate[] linearizeArc(Coordinate p1, Coordinate p2, Coordinate p3, double tolerence) {
final Arc arc = createArc( p1, p2, p3 );
final List<Coordinate> result = linearizeInternal( null, arc, tolerence );
return result.toArray( new Coordinate[result.size()] );
}
private List<Coordinate> linearizeInternal(List<Coordinate> coordinates,
Arc arc, double tolerence) {
private List<Coordinate> linearizeInternal(List<Coordinate> coordinates, Arc arc, double tolerence) {
if ( coordinates == null ) {
coordinates = new ArrayList<Coordinate>();
}
double arcHt = arc.getArcHeight();
final double arcHt = arc.getArcHeight();
if ( Double.compare( arcHt, tolerence ) <= 0 ) {
int lastIndex = coordinates.size() - 1;
Coordinate lastCoord = lastIndex >= 0 ? coordinates.get( lastIndex )
: null;
final int lastIndex = coordinates.size() - 1;
final Coordinate lastCoord = lastIndex >= 0 ? coordinates.get( lastIndex ) : null;
if ( lastCoord == null || !arc.getP1().equals2D( lastCoord ) ) {
coordinates.add( arc.getP1() );
coordinates.add( arc.getP2() );
@ -325,13 +352,14 @@ public class Circle {
}
else {
// otherwise, split
Arc[] splits = arc.split();
final Arc[] splits = arc.split();
linearizeInternal( coordinates, splits[0], tolerence );
linearizeInternal( coordinates, splits[1], tolerence );
}
return coordinates;
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
@ -339,7 +367,7 @@ public class Circle {
if ( o == null || getClass() != o.getClass() ) {
return false;
}
Circle circle = (Circle) o;
final Circle circle = (Circle) o;
if ( Double.compare( circle.radius, this.radius ) != 0 ) {
return false;
@ -351,6 +379,17 @@ public class Circle {
return true;
}
@Override
public int hashCode() {
int result;
long temp;
result = center.hashCode();
temp = radius != +0.0d ? Double.doubleToLongBits( radius ) : 0L;
result = 31 * result + (int) ( temp ^ ( temp >>> 32 ) );
return result;
}
@Override
public String toString() {
return "Circle with Radius = " + this.radius
+ " and a center at the coordinates (" + this.center.x + ", "
@ -366,8 +405,8 @@ public class Circle {
* @return The angle of the point from the center of the circle
*/
public double getAngle(Coordinate p) {
double dx = p.x - this.center.x;
double dy = p.y - this.center.y;
final double dx = p.x - this.center.x;
final double dy = p.y - this.center.y;
double angle;
if ( dx == 0.0 ) {
@ -403,6 +442,13 @@ public class Circle {
return angle;
}
/**
* Returns the coordinate on the circle at the specified angle
*
* @param angle The angle
*
* @return Coordinate
*/
public Coordinate getPoint(final double angle) {
double x = Math.cos( angle ) * this.radius;
x = x + this.center.x;
@ -415,6 +461,8 @@ public class Circle {
}
/**
* Returns the distance the point is from the center of the circle
*
* @param p A point in space
*
* @return The distance the point is from the center of the circle
@ -423,60 +471,27 @@ public class Circle {
return Math.abs( this.center.distance( p ) );
}
/**
* Creates an arc through the specified points
*
* @param p1 The first point
* @param p2 The second point
* @param p3 The third point
*
* @return The {@code Arc} through the three points
*/
public Arc createArc(Coordinate p1, Coordinate p2, Coordinate p3) {
return new Arc( p1, p2, p3 );
}
/**
* Returns an angle between 0 and 2*PI. For example, 4*PI would get returned
* as 2*PI since they are equivalent.
*
* @param angle an angle in radians to normalize
*
* @return an angle between 0 and 2*PI
* An arc, or circle segment
*/
public static double normalizeAngle(double angle) {
double maxRadians = 2 * Math.PI;
if ( angle >= 0 && angle <= maxRadians ) {
return angle;
}
if ( angle < 0 ) {
return maxRadians - Math.abs( angle );
}
else {
return angle % maxRadians;
}
}
/**
* Returns the angle between the angles a1 and a2 in radians. Angle is
* calculated in the counterclockwise direction.
*
* @param a1 first angle
* @param a2 second angle
*
* @return the angle between a1 and a2 in the clockwise direction
*/
public static double subtractAngles(double a1, double a2) {
if ( a1 < a2 ) {
return a2 - a1;
}
else {
return TWO_PI - Math.abs( a2 - a1 );
}
}
private static final double TWO_PI = Math.PI * 2;
public class Arc {
private Coordinate p1, p2;
private double arcAngle; // angle in radians
private double arcAngle;
private double p1Angle;
private double p2Angle;
private boolean clockwise;
private Arc(Coordinate p1, Coordinate midPt, Coordinate p2) {
@ -490,14 +505,13 @@ public class Circle {
}
else {
this.p2Angle = getAngle( p2 );
double midPtAngle = getAngle( midPt );
final double midPtAngle = getAngle( midPt );
// determine the direction
double ccDegrees = Circle.subtractAngles(
this.p1Angle,
midPtAngle
)
+ Circle.subtractAngles( midPtAngle, this.p2Angle );
final double ccDegrees = Circle.subtractAngles( this.p1Angle, midPtAngle ) + Circle.subtractAngles(
midPtAngle,
this.p2Angle
);
if ( ccDegrees < TWO_PI ) {
this.clockwise = false;
@ -547,8 +561,8 @@ public class Circle {
* @return the arc height
*/
public double getArcHeight() {
Coordinate chordCenterPt = this.getChordCenterPoint();
double dist = distanceFromCenter( chordCenterPt );
final Coordinate chordCenterPt = this.getChordCenterPoint();
final double dist = distanceFromCenter( chordCenterPt );
if ( this.arcAngle > Math.PI ) {
return Circle.this.radius + dist;
}
@ -557,21 +571,31 @@ public class Circle {
}
}
/**
* Returns the center of this {@code Arc}
*
* @return the center of this {@code Arc}
*/
public Coordinate getChordCenterPoint() {
double centerX = this.p1.x + ( this.p2.x - this.p1.x ) / 2;
double centerY = this.p1.y + ( this.p2.y - this.p1.y ) / 2;
final double centerX = this.p1.x + ( this.p2.x - this.p1.x ) / 2;
final double centerY = this.p1.y + ( this.p2.y - this.p1.y ) / 2;
return new Coordinate( centerX, centerY );
}
/**
* Splits this {@code Arc} at the mid point
*
* @return an array of two {@code Arc}s
*/
public Arc[] split() {
int directionFactor = isClockwise() ? -1 : 1;
double angleOffset = directionFactor * ( this.arcAngle / 2 );
final int directionFactor = isClockwise() ? -1 : 1;
final double angleOffset = directionFactor * ( this.arcAngle / 2 );
double midAngle = this.p1Angle + angleOffset;
Coordinate newMidPoint = getPoint( midAngle );
final double midAngle = this.p1Angle + angleOffset;
final Coordinate newMidPoint = getPoint( midAngle );
Arc arc1 = new Arc( this.p1, newMidPoint, isClockwise() );
Arc arc2 = new Arc( newMidPoint, this.p2, isClockwise() );
final Arc arc1 = new Arc( this.p1, newMidPoint, isClockwise() );
final Arc arc2 = new Arc( newMidPoint, this.p2, isClockwise() );
return new Arc[] { arc1, arc2 };
}
@ -603,6 +627,7 @@ public class Circle {
return this.clockwise;
}
@Override
public String toString() {
return "P1: " + this.p1 + " P2: " + this.p2 + " clockwise: " + this.clockwise;
}

View File

@ -26,22 +26,35 @@ import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;
//TODO -- put into Geolatte?
/**
* Converts an {@code Envelope} to a {@code Polygon}
*/
public class EnvelopeAdapter {
static private GeometryFactory geomFactory = new GeometryFactory();
private static GeometryFactory geomFactory = new GeometryFactory();
static public Polygon toPolygon(Envelope env, int SRID) {
Coordinate[] coords = new Coordinate[5];
private EnvelopeAdapter() {
}
/**
* Converts the specified {@code Envelope} to a {@code Polygon} having the specified srid.
* @param env The envelope to convert
* @param srid The srid for the polygon
* @return The Polygon
*/
public static Polygon toPolygon(Envelope env, int srid) {
final Coordinate[] coords = new Coordinate[5];
coords[0] = new Coordinate( env.getMinX(), env.getMinY() );
coords[1] = new Coordinate( env.getMinX(), env.getMaxY() );
coords[2] = new Coordinate( env.getMaxX(), env.getMaxY() );
coords[3] = new Coordinate( env.getMaxX(), env.getMinY() );
coords[4] = new Coordinate( env.getMinX(), env.getMinY() );
LinearRing shell = geomFactory.createLinearRing( coords );
final LinearRing shell = geomFactory.createLinearRing( coords );
Polygon pg = geomFactory.createPolygon( shell, null );
pg.setSRID( SRID );
final Polygon pg = geomFactory.createPolygon( shell, null );
pg.setSRID( srid );
return pg;
}

View File

@ -1,99 +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.jts.mgeom;
/**
* This utility class is used to testsuite-suite doubles for equality
*
* @author Didier H. Besset <p/> Adapted from "Object-oriented implementation of
* numerical methods"
*/
//TODO: This class should be removed.
public final class DoubleComparator {
private final static int radix = computeRadix();
private final static double machinePrecision = computeMachinePrecision();
private final static double defaultNumericalPrecision = Math
.sqrt( machinePrecision );
private static int computeRadix() {
int radix = 0;
double a = 1.0d;
double tmp1, tmp2;
do {
a += a;
tmp1 = a + 1.0d;
tmp2 = tmp1 - a;
} while ( tmp2 - 1.0d != 0.0d );
double b = 1.0d;
while ( radix == 0 ) {
b += b;
tmp1 = a + b;
radix = (int) ( tmp1 - a );
}
return radix;
}
public static int getRadix() {
return radix;
}
private static double computeMachinePrecision() {
double floatingRadix = getRadix();
double inverseRadix = 1.0d / floatingRadix;
double machinePrecision = 1.0d;
double tmp = 1.0d + machinePrecision;
while ( tmp - 1.0d != 0.0 ) {
machinePrecision *= inverseRadix;
tmp = 1.0d + machinePrecision;
}
return machinePrecision;
}
public static double getMachinePrecision() {
return machinePrecision;
}
public static double defaultNumericalPrecision() {
return defaultNumericalPrecision;
}
public static boolean equals(double a, double b) {
return equals( a, b, defaultNumericalPrecision() );
}
public static boolean equals(double a, double b, double precision) {
double norm = Math.max( Math.abs( a ), Math.abs( b ) );
boolean result = norm < precision || Math.abs( a - b ) < precision * norm;
return result || ( Double.isNaN( a ) && Double.isNaN( b ) );
}
public static void main(String[] args) {
System.out.println( "Machine precision = " + getMachinePrecision() );
System.out.println( "Radix = " + getRadix() );
System.out.println(
"default numerical precision = "
+ defaultNumericalPrecision()
);
}
}

View File

@ -1,260 +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.jts.mgeom;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
/**
* This coordinate class supports 4D coordinates, where the first 3 measures
* (x,y,z) are coordinates in a 3 dimensional space (cartesian for example), and
* the fourth is a measure value used for linear referencing. Note that the
* measure value is independent of whether the (x,y,z) values are used. For
* example, the z value can not be used while the measure value is used. <p/>
* While this class extends the Coordinate class, it can be used seamlessly as a
* substitute in the event that the Measure value is not used. In these cases
* the Measure value shall simply be Double.NaN
*
* @see com.vividsolutions.jts.geom.Coordinate
*/
public class MCoordinate extends Coordinate {
/**
*
*/
private static final long serialVersionUID = 1L;
public double m;
/**
* Default constructor
*/
public MCoordinate() {
super();
this.m = Double.NaN;
}
public MCoordinate(double x, double y, double z, double m) {
super( x, y, z );
this.m = m;
}
public MCoordinate(double x, double y) {
super( x, y );
m = Double.NaN;
}
public MCoordinate(Coordinate coord) {
super( coord );
if ( coord instanceof MCoordinate ) {
m = ( (MCoordinate) coord ).m;
}
else {
m = Double.NaN;
}
}
public MCoordinate(MCoordinate coord) {
super( coord );
m = coord.m;
}
/**
* TODO: I'd like to see this method added to the base Coordinate class
* Returns the ordinate value specified in this Coordinate instance. The
* index of the desired ordinates are specified in the CoordinateSequence
* class; hence CoodinateSequence.X returns the x ordinate,
* CoodinateSequence.Y the y ordinate, CoodinateSequence.Z the z ordinate,
* and CoodinateSequence.M the m ordinate. Note that the dimension may not
* imply the desired ordinate in the case where one is using a 2 dimensional
* geometry with a measure value. Therefore, these constants are highly
* recommended.
*
* @param ordinateIndex the desired ordinate index.
*
* @return the value of stored in the ordinate index. Incorrect or unused
* indexes shall return Double.NaN
*/
public double getOrdinate(int ordinateIndex) {
switch ( ordinateIndex ) {
case CoordinateSequence.X:
return this.x;
case CoordinateSequence.Y:
return this.y;
case CoordinateSequence.Z:
return this.z;
case CoordinateSequence.M:
return this.m;
}
return Double.NaN;
}
/**
* TODO: I'd like to see this method added to the base Coordinate class Sets
* the value for a given ordinate. This should be specified using the
* CoordinateSequence ordinate index constants.
*
* @param ordinateIndex the desired ordinate index.
* @param value the new ordinate value
*
* @throws IllegalArgumentException if the ordinateIndex value is incorrect
* @see #getOrdinate(int)
*/
public void setOrdinate(int ordinateIndex, double value) {
switch ( ordinateIndex ) {
case CoordinateSequence.X:
this.x = value;
break;
case CoordinateSequence.Y:
this.y = value;
break;
case CoordinateSequence.Z:
this.z = value;
break;
case CoordinateSequence.M:
this.m = value;
break;
default:
throw new IllegalArgumentException( "invalid ordinateIndex" );
}
}
public boolean equals2DWithMeasure(Coordinate other) {
boolean result = this.equals2D( other );
if ( result ) {
MCoordinate mc = convertCoordinate( other );
result = ( Double.compare( this.m, mc.m ) == 0 );
}
return result;
}
public boolean equals3DWithMeasure(Coordinate other) {
boolean result = this.equals3D( other );
if ( result ) {
MCoordinate mc = convertCoordinate( other );
result = ( Double.compare( this.m, mc.m ) == 0 );
}
return result;
}
/*
* Default equality is now equality in 2D-plane. This is required to remain
* consistent with JTS.
*
* TODO:check whether this method is still needed.
*
* (non-Javadoc)
*
* @see com.vividsolutions.jts.geom.Coordinate#equals(java.lang.Object)
*/
public boolean equals(Object other) {
if ( other instanceof Coordinate ) {
return equals2D( (Coordinate) other );
}
else {
return false;
}
}
public String toString() {
return "(" + x + "," + y + "," + z + "," + " m=" + m + ")";
}
/**
* Converts a standard Coordinate instance to an MCoordinate instance. If
* coordinate is already an instance of an MCoordinate, then it is simply
* returned. In cases where it is converted, the measure value of the
* coordinate is initialized to Double.NaN.
*
* @param coordinate The coordinate to be converted
*
* @return an instance of MCoordinate corresponding to the
* <code>coordinate</code> parameter
*/
public static MCoordinate convertCoordinate(Coordinate coordinate) {
if ( coordinate == null ) {
return null;
}
if ( coordinate instanceof MCoordinate ) {
return (MCoordinate) coordinate;
}
return new MCoordinate( coordinate );
}
/**
* A convenience method for creating a MCoordinate instance where there are
* only 2 coordinates and an lrs measure value. The z value of the
* coordinate shall be set to Double.NaN
*
* @param x the x coordinate value
* @param y the y coordinate value
* @param m the lrs measure value
*
* @return The constructed MCoordinate value
*/
public static MCoordinate create2dWithMeasure(double x, double y, double m) {
return new MCoordinate( x, y, Double.NaN, m );
}
/**
* A convenience method for creating a MCoordinate instance where there are
* only 2 coordinates and an lrs measure value. The z and m value of the
* coordinate shall be set to Double.NaN
*
* @param x the x coordinate value
* @param y the y coordinate value
*
* @return The constructed MCoordinate value
*/
public static MCoordinate create2d(double x, double y) {
return new MCoordinate( x, y, Double.NaN, Double.NaN );
}
/**
* A convenience method for creating a MCoordinate instance where there are
* 3 coordinates and an lrs measure value.
*
* @param x the x coordinate value
* @param y the y coordinate value
* @param z the z coordinate value
* @param m the lrs measure value
*
* @return The constructed MCoordinate value
*/
public static MCoordinate create3dWithMeasure(double x, double y, double z,
double m) {
return new MCoordinate( x, y, z, m );
}
/**
* A convenience method for creating a MCoordinate instance where there are
* 3 coordinates but no lrs measure value. The m value of the coordinate
* shall be set to Double.NaN
*
* @param x the x coordinate value
* @param y the y coordinate value
* @param z the z coordinate value
*
* @return The constructed MCoordinate value
*/
public static MCoordinate create3d(double x, double y, double z) {
return new MCoordinate( x, y, z, Double.NaN );
}
}

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This package contains utility classes for use with JTS.
</p>
</body>
</html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<!--
~ This file is part of Hibernate Spatial, an extension to the
~ hibernate ORM solution for spatial (geographic) data.
~
~ Copyright © 2007-2013 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
-->
<html>
<head></head>
<body>
<p>
This package defines the central Hibernate Spatial APIs.
</p>
</body>
</html>

View File

@ -31,7 +31,7 @@ import com.vividsolutions.jts.geom.Geometry;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.metamodel.spi.MetadataImplementor;
import org.hibernate.spatial.Log;
import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction;
@ -110,13 +110,12 @@ public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCa
*
* @return
*/
protected Configuration constructConfiguration() {
Configuration cfg = super.constructConfiguration();
initializeSpatialTestSupport( cfg );
return cfg;
public void afterMetadataBuilt(MetadataImplementor metadataImplementor) {
super.afterMetadataBuilt( metadataImplementor );
initializeSpatialTestSupport( metadataImplementor );
}
private void initializeSpatialTestSupport(Configuration cfg) {
private void initializeSpatialTestSupport(MetadataImplementor cfg) {
try {
TestSupport support = TestSupportFactories.instance().getTestSupportFactory( getDialect() );
dataSourceUtils = support.createDataSourceUtil( cfg );
@ -134,7 +133,7 @@ public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCa
* <p/>
* Mostly used to register spatial metadata in databases such as Oracle Spatial.
*/
protected void afterSessionFactoryBuilt() {
public void afterSessionFactoryBuilt() {
dataSourceUtils.afterCreateSchema();
}

View File

@ -21,7 +21,9 @@
package org.hibernate.spatial.testing;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.metamodel.spi.MetadataImplementor;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@ -31,10 +33,10 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
*/
public abstract class TestSupport {
protected Configuration configuration;
protected ConfigurationService configurationService;
public DataSourceUtils createDataSourceUtil(Configuration configuration) {
this.configuration = configuration;
public DataSourceUtils createDataSourceUtil(MetadataImplementor metadataImplementor) {
this.configurationService = metadataImplementor.getServiceRegistry().getService( ConfigurationService.class );
return new DataSourceUtils( driver(), url(), user(), passwd(), getSQLExpressionTemplate() );
}
@ -49,18 +51,18 @@ public abstract class TestSupport {
public abstract SQLExpressionTemplate getSQLExpressionTemplate();
protected String driver() {
return configuration.getProperty( "hibernate.connection.driver_class" );
return configurationService.getSetting( AvailableSettings.DRIVER );
}
protected String url() {
return configuration.getProperty( "hibernate.connection.url" );
return configurationService.getSetting( AvailableSettings.URL );
}
protected String user() {
return configuration.getProperty( "hibernate.connection.username" );
return configurationService.getSetting( AvailableSettings.USER );
}
protected String passwd() {
return configuration.getProperty( "hibernate.connection.password" );
return configurationService.getSetting( AvailableSettings.PASS );
}
}

View File

@ -24,7 +24,7 @@ package org.hibernate.spatial.testing.dialects.h2geodb;
import java.io.IOException;
import java.sql.SQLException;
import org.hibernate.cfg.Configuration;
import org.hibernate.metamodel.spi.MetadataImplementor;
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.DataSourceUtils;
import org.hibernate.spatial.testing.GeometryEquality;
@ -40,8 +40,8 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
public class GeoDBTestSupport extends TestSupport {
public DataSourceUtils createDataSourceUtil(Configuration configuration) {
super.createDataSourceUtil( configuration );
public DataSourceUtils createDataSourceUtil(MetadataImplementor metadataImplementor) {
super.createDataSourceUtil( metadataImplementor );
try {
return new GeoDBDataSourceUtils( driver(), url(), user(), passwd(), getSQLExpressionTemplate() );
}

View File

@ -21,7 +21,7 @@
package org.hibernate.spatial.testing.dialects.oracle;
import org.hibernate.cfg.Configuration;
import org.hibernate.metamodel.spi.MetadataImplementor;
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
import org.hibernate.spatial.testing.DataSourceUtils;
import org.hibernate.spatial.testing.SQLExpressionTemplate;
@ -51,8 +51,8 @@ public class OracleSDOTestSupport extends TestSupport {
}
@Override
public DataSourceUtils createDataSourceUtil(Configuration configuration) {
this.configuration = configuration;
public DataSourceUtils createDataSourceUtil(MetadataImplementor metadataImplementor) {
super.createDataSourceUtil( metadataImplementor );
return new SDODataSourceUtils( driver(), url(), user(), passwd(), getSQLExpressionTemplate() );
}
}