HHH-13799 : Criteria API support for Hibernate Spatial (#3159)
* HHH-13799 : Criteria API support for Hibernate Spatial Co-authored-by: Karel Maesen <karel@geovise.com>
This commit is contained in:
parent
b914b02dca
commit
cab651e194
|
@ -10,7 +10,7 @@ hibernate.dialect org.hibernate.spatial.dialect.db2.DB2SpatialDialect
|
||||||
hibernate.connection.driver_class com.ibm.db2.jcc.DB2Driver
|
hibernate.connection.driver_class com.ibm.db2.jcc.DB2Driver
|
||||||
hibernate.connection.url jdbc:db2://localhost:50000/hibern8
|
hibernate.connection.url jdbc:db2://localhost:50000/hibern8
|
||||||
hibernate.connection.username db2inst1
|
hibernate.connection.username db2inst1
|
||||||
hibernate.connection.password password
|
hibernate.connection.password oPucroAsMAgL
|
||||||
|
|
||||||
|
|
||||||
hibernate.connection.pool_size 5
|
hibernate.connection.pool_size 5
|
||||||
|
|
|
@ -9,7 +9,7 @@ hibernate.dialect org.hibernate.spatial.dialect.sqlserver.SqlServer2012SpatialDi
|
||||||
hibernate.connection.driver_class com.microsoft.sqlserver.jdbc.SQLServerDriver
|
hibernate.connection.driver_class com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||||
hibernate.connection.url jdbc:sqlserver://localhost:1433;databaseName=TestDb
|
hibernate.connection.url jdbc:sqlserver://localhost:1433;databaseName=TestDb
|
||||||
hibernate.connection.username hibern8
|
hibernate.connection.username hibern8
|
||||||
hibernate.connection.password hibern8Pass
|
hibernate.connection.password langpaswoord123A%1
|
||||||
|
|
||||||
|
|
||||||
hibernate.connection.pool_size 5
|
hibernate.connection.pool_size 5
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
|
|
||||||
|
## The same effect can be achieved by setting the system properties
|
||||||
|
# in ~/.gradle/gradle.properties
|
||||||
|
|
||||||
TASK=matrix
|
TASK=matrix
|
||||||
if [[ -n $@ ]]; then
|
if [[ -n $@ ]]; then
|
||||||
TASK="$@"
|
TASK="$@"
|
||||||
|
|
|
@ -164,8 +164,16 @@ public enum SpatialFunction {
|
||||||
/**
|
/**
|
||||||
* the extents function
|
* the extents function
|
||||||
*/
|
*/
|
||||||
extent( "common" );
|
extent( "common" ),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The filter function
|
||||||
|
* <p>
|
||||||
|
* <p>Corresponds to the Oracle Spatial's "SDO_FILTER" function, or the "&&" operator of PostGIS.
|
||||||
|
*/
|
||||||
|
filter( "filter" ),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.spatial.dialect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Interface for {@code SpatialDialect}s that require a custom
|
||||||
|
* rendering to JPAQL for the filter predicate
|
||||||
|
* <p>
|
||||||
|
* Created by Karel Maesen, Geovise BVBA on 09/02/2020.
|
||||||
|
*/
|
||||||
|
public interface WithCustomJPAFilter {
|
||||||
|
|
||||||
|
String filterExpression(String geometryParam, String filterParam);
|
||||||
|
}
|
|
@ -7,9 +7,15 @@
|
||||||
|
|
||||||
package org.hibernate.spatial.dialect.h2geodb;
|
package org.hibernate.spatial.dialect.h2geodb;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.hibernate.QueryException;
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.hibernate.dialect.H2Dialect;
|
||||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.spatial.GeolatteGeometryJavaTypeDescriptor;
|
import org.hibernate.spatial.GeolatteGeometryJavaTypeDescriptor;
|
||||||
import org.hibernate.spatial.GeolatteGeometryType;
|
import org.hibernate.spatial.GeolatteGeometryType;
|
||||||
|
@ -19,6 +25,7 @@ import org.hibernate.spatial.SpatialDialect;
|
||||||
import org.hibernate.spatial.SpatialFunction;
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
import org.hibernate.spatial.SpatialRelation;
|
import org.hibernate.spatial.SpatialRelation;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends the H2Dialect by also including information on spatial functions.
|
* Extends the H2Dialect by also including information on spatial functions.
|
||||||
|
@ -74,6 +81,8 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
|
||||||
|
|
||||||
registerFunction( "dwithin", new StandardSQLFunction( "ST_DWithin", StandardBasicTypes.BOOLEAN ) );
|
registerFunction( "dwithin", new StandardSQLFunction( "ST_DWithin", StandardBasicTypes.BOOLEAN ) );
|
||||||
|
|
||||||
|
// Register Spatial Filter function
|
||||||
|
registerFunction( SpatialFunction.filter.name(), new FilterFunction() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -157,4 +166,26 @@ public class GeoDBDialect extends H2Dialect implements SpatialDialect {
|
||||||
return function != SpatialFunction.difference && ( getFunctions().get( function.toString() ) != null );
|
return function != SpatialFunction.difference && ( getFunctions().get( function.toString() ) != null );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FilterFunction extends StandardSQLFunction {
|
||||||
|
|
||||||
|
public FilterFunction() {
|
||||||
|
super( "&&" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String render(
|
||||||
|
Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) {
|
||||||
|
int argumentCount = arguments.size();
|
||||||
|
if ( argumentCount != 2 ) {
|
||||||
|
throw new QueryException( String.format( "2 arguments expected, received %d", argumentCount ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
String.valueOf( arguments.get( 0 ) ),
|
||||||
|
getRenderedName( arguments ),
|
||||||
|
String.valueOf( arguments.get( 1 ) )
|
||||||
|
).collect( Collectors.joining( " ", "(", ")" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
package org.hibernate.spatial.dialect.hana;
|
package org.hibernate.spatial.dialect.hana;
|
||||||
|
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
import org.hibernate.dialect.HANAColumnStoreDialect;
|
import org.hibernate.dialect.HANAColumnStoreDialect;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService.Converter;
|
import org.hibernate.engine.config.spi.ConfigurationService.Converter;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.spatial.GeolatteGeometryJavaTypeDescriptor;
|
import org.hibernate.spatial.GeolatteGeometryJavaTypeDescriptor;
|
||||||
import org.hibernate.spatial.GeolatteGeometryType;
|
import org.hibernate.spatial.GeolatteGeometryType;
|
||||||
|
@ -22,6 +24,7 @@ import org.hibernate.spatial.SpatialDialect;
|
||||||
import org.hibernate.spatial.SpatialFunction;
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
import org.hibernate.spatial.SpatialRelation;
|
import org.hibernate.spatial.SpatialRelation;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
public class HANASpatialDialect extends HANAColumnStoreDialect implements SpatialDialect {
|
public class HANASpatialDialect extends HANAColumnStoreDialect implements SpatialDialect {
|
||||||
|
|
||||||
|
@ -102,6 +105,9 @@ public class HANASpatialDialect extends HANAColumnStoreDialect implements Spatia
|
||||||
registerFunction(
|
registerFunction(
|
||||||
SpatialFunction.within.name(),
|
SpatialFunction.within.name(),
|
||||||
new HANASpatialFunction( "ST_Within", StandardBasicTypes.NUMERIC_BOOLEAN, true ) );
|
new HANASpatialFunction( "ST_Within", StandardBasicTypes.NUMERIC_BOOLEAN, true ) );
|
||||||
|
registerFunction(
|
||||||
|
SpatialFunction.filter.name(),
|
||||||
|
new FilterFunction() );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Additional HANA functions
|
* Additional HANA functions
|
||||||
|
@ -408,4 +414,17 @@ public class HANASpatialDialect extends HANAColumnStoreDialect implements Spatia
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FilterFunction extends HANASpatialFunction {
|
||||||
|
|
||||||
|
public FilterFunction() {
|
||||||
|
super( "ST_IntersectsFilter", StandardBasicTypes.NUMERIC_BOOLEAN, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String render(
|
||||||
|
Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) {
|
||||||
|
return super.render( firstArgumentType, arguments, sessionFactory ) + " = 1";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.spatial.dialect.mysql;
|
package org.hibernate.spatial.dialect.mysql;
|
||||||
|
|
||||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||||
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
|
@ -163,6 +164,13 @@ class MySQL5SpatialFunctions extends SpatialFunctionsRegistry {
|
||||||
// "union"
|
// "union"
|
||||||
// )
|
// )
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
functionMap.put(
|
||||||
|
SpatialFunction.filter.name(), new StandardSQLFunction(
|
||||||
|
"MBRIntersects",
|
||||||
|
StandardBasicTypes.BOOLEAN
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.spatial.dialect.mysql;
|
package org.hibernate.spatial.dialect.mysql;
|
||||||
|
|
||||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||||
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
|
@ -169,6 +170,13 @@ class MySQL8SpatialFunctions extends SpatialFunctionsRegistry {
|
||||||
"ST_Union"
|
"ST_Union"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
functionMap.put(
|
||||||
|
SpatialFunction.filter.name(), new StandardSQLFunction(
|
||||||
|
"MBRIntersects",
|
||||||
|
StandardBasicTypes.BOOLEAN
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.spatial.dialect.oracle;
|
package org.hibernate.spatial.dialect.oracle;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||||
|
@ -22,6 +23,7 @@ import org.hibernate.spatial.SpatialDialect;
|
||||||
import org.hibernate.spatial.SpatialFunction;
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
import org.hibernate.spatial.SpatialRelation;
|
import org.hibernate.spatial.SpatialRelation;
|
||||||
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
||||||
|
import org.hibernate.spatial.dialect.WithCustomJPAFilter;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ import org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory;
|
||||||
* <p>
|
* <p>
|
||||||
* Created by Karel Maesen, Geovise BVBA on 01/11/16.
|
* Created by Karel Maesen, Geovise BVBA on 01/11/16.
|
||||||
*/
|
*/
|
||||||
class OracleSDOSupport implements SpatialDialect, Serializable {
|
class OracleSDOSupport implements SpatialDialect, Serializable, WithCustomJPAFilter {
|
||||||
|
|
||||||
private static final HSMessageLogger log = Logger.getMessageLogger(
|
private static final HSMessageLogger log = Logger.getMessageLogger(
|
||||||
HSMessageLogger.class,
|
HSMessageLogger.class,
|
||||||
|
@ -290,7 +292,7 @@ class OracleSDOSupport implements SpatialDialect, Serializable {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getHavingSridSQL(String columnName) {
|
public String getHavingSridSQL(String columnName) {
|
||||||
return String.format( " (MDSYS.ST_GEOMETRY(%s).ST_SRID() = ?)", columnName );
|
return String.format( " (MDSYS.ST_GEOMETRY(%s).ST_SRID() = ?)", columnName , Locale.US);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -304,7 +306,7 @@ class OracleSDOSupport implements SpatialDialect, Serializable {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getIsEmptySQL(String columnName, boolean isEmpty) {
|
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 , Locale.US);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,4 +333,8 @@ class OracleSDOSupport implements SpatialDialect, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String filterExpression(String geometryParam, String filterParam) {
|
||||||
|
return SpatialFunction.filter.name() + "(" + geometryParam + ", " + filterParam + ") = 'TRUE' ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.spatial.HSMessageLogger;
|
import org.hibernate.spatial.HSMessageLogger;
|
||||||
import org.hibernate.spatial.SpatialDialect;
|
import org.hibernate.spatial.SpatialDialect;
|
||||||
import org.hibernate.spatial.SpatialFunction;
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
|
import org.hibernate.spatial.dialect.WithCustomJPAFilter;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ import org.jboss.logging.Logger;
|
||||||
*
|
*
|
||||||
* @author Karel Maesen
|
* @author Karel Maesen
|
||||||
*/
|
*/
|
||||||
public class OracleSpatial10gDialect extends Oracle10gDialect implements SpatialDialect, Serializable {
|
public class OracleSpatial10gDialect extends Oracle10gDialect implements SpatialDialect, WithCustomJPAFilter, Serializable {
|
||||||
|
|
||||||
private static final HSMessageLogger log = Logger.getMessageLogger(
|
private static final HSMessageLogger log = Logger.getMessageLogger(
|
||||||
HSMessageLogger.class,
|
HSMessageLogger.class,
|
||||||
|
@ -101,5 +102,8 @@ public class OracleSpatial10gDialect extends Oracle10gDialect implements Spatial
|
||||||
return ( getFunctions().get( function.toString() ) != null );
|
return ( getFunctions().get( function.toString() ) != null );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String filterExpression(String geometryParam, String filterParam) {
|
||||||
|
return sdoSupport.filterExpression( geometryParam, filterParam );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.QueryException;
|
||||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.spatial.SpatialAnalysis;
|
import org.hibernate.spatial.SpatialAnalysis;
|
||||||
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
import org.hibernate.spatial.SpatialRelation;
|
import org.hibernate.spatial.SpatialRelation;
|
||||||
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
||||||
import org.hibernate.spatial.dialect.oracle.criterion.OracleSpatialAggregate;
|
import org.hibernate.spatial.dialect.oracle.criterion.OracleSpatialAggregate;
|
||||||
|
@ -138,6 +139,12 @@ class OracleSpatialFunctions extends SpatialFunctionsRegistry {
|
||||||
new SpatialAggregationFunction( "extent", OracleSpatialAggregate.EXTENT, sdoSupport )
|
new SpatialAggregationFunction( "extent", OracleSpatialAggregate.EXTENT, sdoSupport )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// spatial filter function
|
||||||
|
put(
|
||||||
|
SpatialFunction.filter.name(),
|
||||||
|
new StandardSQLFunction( "SDO_FILTER" )
|
||||||
|
);
|
||||||
|
|
||||||
//other common functions
|
//other common functions
|
||||||
|
|
||||||
put( "transform", new StandardSQLFunction( "SDO_CS.TRANSFORM" ) );
|
put( "transform", new StandardSQLFunction( "SDO_CS.TRANSFORM" ) );
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.spatial.HSMessageLogger;
|
import org.hibernate.spatial.HSMessageLogger;
|
||||||
import org.hibernate.spatial.SpatialDialect;
|
import org.hibernate.spatial.SpatialDialect;
|
||||||
import org.hibernate.spatial.SpatialFunction;
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
|
import org.hibernate.spatial.dialect.WithCustomJPAFilter;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -25,7 +26,8 @@ import org.jboss.logging.Logger;
|
||||||
* <p>
|
* <p>
|
||||||
* Created by Karel Maesen, Geovise BVBA on 11/02/17.
|
* Created by Karel Maesen, Geovise BVBA on 11/02/17.
|
||||||
*/
|
*/
|
||||||
public class OracleSpatialSDO10gDialect extends Oracle10gDialect implements SpatialDialect, Serializable {
|
public class OracleSpatialSDO10gDialect extends Oracle10gDialect
|
||||||
|
implements SpatialDialect, WithCustomJPAFilter, Serializable {
|
||||||
|
|
||||||
private static final HSMessageLogger log = Logger.getMessageLogger(
|
private static final HSMessageLogger log = Logger.getMessageLogger(
|
||||||
HSMessageLogger.class,
|
HSMessageLogger.class,
|
||||||
|
@ -100,5 +102,8 @@ public class OracleSpatialSDO10gDialect extends Oracle10gDialect implements Spat
|
||||||
return !function.equals( SpatialFunction.crosses ) && ( getFunctions().get( function.toString() ) != null );
|
return !function.equals( SpatialFunction.crosses ) && ( getFunctions().get( function.toString() ) != null );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String filterExpression(String geometryParam, String filterParam) {
|
||||||
|
return sdoSupport.filterExpression( geometryParam, filterParam );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,13 @@
|
||||||
package org.hibernate.spatial.dialect.postgis;
|
package org.hibernate.spatial.dialect.postgis;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.hibernate.QueryException;
|
||||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -177,6 +181,11 @@ class PostgisFunctions extends SpatialFunctionsRegistry {
|
||||||
"extent", new ExtentFunction()
|
"extent", new ExtentFunction()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//register Spatial Filter function
|
||||||
|
put(
|
||||||
|
SpatialFunction.filter.name(), new FilterFunction()
|
||||||
|
);
|
||||||
|
|
||||||
//other common functions
|
//other common functions
|
||||||
put(
|
put(
|
||||||
"dwithin", new StandardSQLFunction(
|
"dwithin", new StandardSQLFunction(
|
||||||
|
@ -206,4 +215,26 @@ class PostgisFunctions extends SpatialFunctionsRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FilterFunction extends StandardSQLFunction {
|
||||||
|
|
||||||
|
public FilterFunction() {
|
||||||
|
super( "&&" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String render(
|
||||||
|
Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) {
|
||||||
|
int argumentCount = arguments.size();
|
||||||
|
if ( argumentCount != 2 ) {
|
||||||
|
throw new QueryException( String.format( "2 arguments expected, received %d", argumentCount ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
String.valueOf( arguments.get( 0 ) ),
|
||||||
|
getRenderedName( arguments ),
|
||||||
|
String.valueOf( arguments.get( 1 ) )
|
||||||
|
).collect( Collectors.joining( " ", "(", ")" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.spatial.dialect.sqlserver;
|
package org.hibernate.spatial.dialect.sqlserver;
|
||||||
|
|
||||||
import org.hibernate.dialect.function.SQLFunctionTemplate;
|
import org.hibernate.dialect.function.SQLFunctionTemplate;
|
||||||
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
|
@ -62,5 +63,7 @@ class SqlServerFunctions extends SpatialFunctionsRegistry {
|
||||||
"pointonsurface", new SqlServerMethod( "STPointOnSurface" )
|
"pointonsurface", new SqlServerMethod( "STPointOnSurface" )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Register spatial filter function.
|
||||||
|
put( SpatialFunction.filter.name(), new SQLFunctionTemplate( StandardBasicTypes.BOOLEAN, "?1.Filter(?2)" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.spatial.predicate;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.Expression;
|
||||||
|
import javax.persistence.criteria.Predicate;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
|
||||||
|
import org.hibernate.query.criteria.internal.ParameterRegistry;
|
||||||
|
import org.hibernate.query.criteria.internal.Renderable;
|
||||||
|
import org.hibernate.query.criteria.internal.compile.RenderingContext;
|
||||||
|
import org.hibernate.query.criteria.internal.predicate.AbstractSimplePredicate;
|
||||||
|
import org.hibernate.spatial.SpatialDialect;
|
||||||
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
|
import org.hibernate.spatial.criterion.SpatialFilter;
|
||||||
|
import org.hibernate.spatial.dialect.WithCustomJPAFilter;
|
||||||
|
import org.hibernate.spatial.jts.EnvelopeAdapter;
|
||||||
|
|
||||||
|
import org.locationtech.jts.geom.Envelope;
|
||||||
|
import org.locationtech.jts.geom.Geometry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JPA Criteria API {@link Predicate} equivalent of {@link SpatialFilter}.
|
||||||
|
*/
|
||||||
|
public class FilterPredicate extends AbstractSimplePredicate implements Serializable {
|
||||||
|
|
||||||
|
private final Expression<? extends Geometry> geometry;
|
||||||
|
private final Expression<? extends Geometry> filter;
|
||||||
|
|
||||||
|
public FilterPredicate(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry,
|
||||||
|
Expression<? extends Geometry> filter) {
|
||||||
|
super( (CriteriaBuilderImpl) criteriaBuilder );
|
||||||
|
this.geometry = geometry;
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterPredicate(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry,
|
||||||
|
Geometry filter) {
|
||||||
|
this( criteriaBuilder, geometry, criteriaBuilder.literal( filter )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterPredicate(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry,
|
||||||
|
Envelope envelope, int srid) {
|
||||||
|
this( criteriaBuilder, geometry, EnvelopeAdapter.toPolygon( envelope, srid )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerParameters(ParameterRegistry registry) {
|
||||||
|
Helper.possibleParameter( geometry, registry );
|
||||||
|
Helper.possibleParameter( filter, registry );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String render(boolean isNegated, RenderingContext renderingContext) {
|
||||||
|
String geometryParameter = ( (Renderable) geometry ).render( renderingContext );
|
||||||
|
String filterParameter = ( (Renderable) filter ).render( renderingContext );
|
||||||
|
Dialect dialect = renderingContext.getDialect();
|
||||||
|
if ( !( dialect instanceof SpatialDialect ) ) {
|
||||||
|
throw new IllegalStateException( "Dialect must be spatially enabled dialect" );
|
||||||
|
}
|
||||||
|
if ( dialect instanceof WithCustomJPAFilter ) {
|
||||||
|
return ( (WithCustomJPAFilter) dialect ).filterExpression( geometryParameter, filterParameter );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return SpatialFunction.filter.name() + "(" + geometryParameter + ", " + filterParameter + ") = true";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,575 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.spatial.predicate;
|
||||||
|
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.Expression;
|
||||||
|
import javax.persistence.criteria.Predicate;
|
||||||
|
|
||||||
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
|
import org.hibernate.spatial.criterion.SpatialRestrictions;
|
||||||
|
|
||||||
|
import org.locationtech.jts.geom.Envelope;
|
||||||
|
import org.locationtech.jts.geom.Geometry;
|
||||||
|
import org.locationtech.jts.geom.Polygon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory for spatial JPA Criteria API {@link Predicate}s.
|
||||||
|
*
|
||||||
|
* @author Daniel Shuy
|
||||||
|
* @see SpatialRestrictions
|
||||||
|
*/
|
||||||
|
public final class SpatialPredicates {
|
||||||
|
|
||||||
|
private SpatialPredicates() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially equal" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
*
|
||||||
|
* @return "spatially equal" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#eq(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate eq(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.equals.toString(), boolean.class,
|
||||||
|
geometry1, geometry2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially equal" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
*
|
||||||
|
* @return "spatially equal" predicate
|
||||||
|
*
|
||||||
|
* @see #eq(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate eq(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return eq( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially within" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
*
|
||||||
|
* @return "spatially within" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#within(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate within(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.within.toString(), boolean.class,
|
||||||
|
geometry1, geometry2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially within" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
*
|
||||||
|
* @return "spatially within" predicate
|
||||||
|
*
|
||||||
|
* @see #within(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate within(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return within( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially contains" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
*
|
||||||
|
* @return "spatially contains" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#contains(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate contains(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.contains.toString(), boolean.class,
|
||||||
|
geometry1, geometry2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially contains" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
*
|
||||||
|
* @return "spatially contains" predicate
|
||||||
|
*
|
||||||
|
* @see #contains(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate contains(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return contains( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially crosses" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
*
|
||||||
|
* @return "spatially crosses" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#crosses(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate crosses(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.crosses.toString(), boolean.class,
|
||||||
|
geometry1, geometry2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially crosses" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
*
|
||||||
|
* @return "spatially crosses" predicate
|
||||||
|
*
|
||||||
|
* @see #crosses(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate crosses(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return crosses( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially disjoint" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
*
|
||||||
|
* @return "spatially disjoint" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#disjoint(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate disjoint(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.disjoint.toString(), boolean.class,
|
||||||
|
geometry1, geometry2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially disjoint" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
*
|
||||||
|
* @return "spatially disjoint" predicate
|
||||||
|
*
|
||||||
|
* @see #disjoint(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate disjoint(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return disjoint( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially intersects" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
*
|
||||||
|
* @return "spatially intersects" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#intersects(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate intersects(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.intersects.toString(), boolean.class,
|
||||||
|
geometry1, geometry2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially intersects" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
*
|
||||||
|
* @return "spatially intersects" predicate
|
||||||
|
*
|
||||||
|
* @see #intersects(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate intersects(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return intersects( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially overlaps" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
*
|
||||||
|
* @return "spatially overlaps" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#overlaps(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate overlaps(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.overlaps.toString(), boolean.class,
|
||||||
|
geometry1, geometry2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially overlaps" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
*
|
||||||
|
* @return "spatially overlaps" predicate
|
||||||
|
*
|
||||||
|
* @see #overlaps(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate overlaps(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return overlaps( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially touches" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
*
|
||||||
|
* @return "spatially touches" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#touches(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate touches(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.touches.toString(), boolean.class,
|
||||||
|
geometry1, geometry2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "spatially touches" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
*
|
||||||
|
* @return "spatially touches" predicate
|
||||||
|
*
|
||||||
|
* @see #touches(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate touches(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return touches( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for bounding box overlap constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression whose bounding box to use in the comparison
|
||||||
|
*
|
||||||
|
* @return bounding box overlap predicate
|
||||||
|
*
|
||||||
|
* @see FilterPredicate
|
||||||
|
* @see SpatialRestrictions#filter(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate filter(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2) {
|
||||||
|
return new FilterPredicate( criteriaBuilder, geometry1, geometry2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for bounding box overlap constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value whose bounding box to use in the comparison
|
||||||
|
*
|
||||||
|
* @return bounding box overlap predicate
|
||||||
|
*
|
||||||
|
* @see FilterPredicate
|
||||||
|
* @see SpatialRestrictions#filter(String, Geometry)
|
||||||
|
*/
|
||||||
|
public static Predicate filter(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2) {
|
||||||
|
return new FilterPredicate( criteriaBuilder, geometry1, geometry2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for bounding box overlap constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry geometry expression
|
||||||
|
* @param envelope envelope or bounding box to use in the comparison
|
||||||
|
* @param srid the SRID of the bounding box
|
||||||
|
*
|
||||||
|
* @return bounding box overlap predicate
|
||||||
|
*
|
||||||
|
* @see FilterPredicate
|
||||||
|
* @see SpatialRestrictions#filter(String, Envelope, int)
|
||||||
|
*/
|
||||||
|
public static Predicate filterByPolygon(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry,
|
||||||
|
Envelope envelope, int srid) {
|
||||||
|
return new FilterPredicate( criteriaBuilder, geometry, envelope, srid );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "distance within" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
* @param distance distance expression
|
||||||
|
*
|
||||||
|
* @return "distance within" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#distanceWithin(String, Geometry, double)
|
||||||
|
*/
|
||||||
|
public static Predicate distanceWithin(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2, Expression<Double> distance) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.dwithin.toString(), boolean.class,
|
||||||
|
geometry1, geometry2, distance
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "distance within" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
* @param distance distance expression
|
||||||
|
*
|
||||||
|
* @return "distance within" predicate
|
||||||
|
*
|
||||||
|
* @see #distanceWithin(CriteriaBuilder, Expression, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate distanceWithin(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2, Expression<Double> distance) {
|
||||||
|
return distanceWithin( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 ), distance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "distance within" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry value
|
||||||
|
* @param distance distance value
|
||||||
|
*
|
||||||
|
* @return "distance within" predicate
|
||||||
|
*
|
||||||
|
* @see #distanceWithin(CriteriaBuilder, Expression, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate distanceWithin(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Geometry geometry2, double distance) {
|
||||||
|
return distanceWithin( criteriaBuilder, geometry1,
|
||||||
|
criteriaBuilder.literal( geometry2 ), criteriaBuilder.literal( distance )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "distance within" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry1 geometry expression
|
||||||
|
* @param geometry2 geometry expression
|
||||||
|
* @param distance distance value
|
||||||
|
*
|
||||||
|
* @return "distance within" predicate
|
||||||
|
*
|
||||||
|
* @see #distanceWithin(CriteriaBuilder, Expression, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate distanceWithin(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry1,
|
||||||
|
Expression<? extends Geometry> geometry2, double distance) {
|
||||||
|
return distanceWithin( criteriaBuilder, geometry1, geometry2,
|
||||||
|
criteriaBuilder.literal( distance )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "having srid" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry geometry expression
|
||||||
|
* @param srid SRID expression
|
||||||
|
*
|
||||||
|
* @return "having srid" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#havingSRID(String, int)
|
||||||
|
*/
|
||||||
|
public static Predicate havingSRID(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry,
|
||||||
|
Expression<Integer> srid) {
|
||||||
|
return criteriaBuilder.equal(
|
||||||
|
criteriaBuilder.function( SpatialFunction.srid.toString(), int.class, geometry ),
|
||||||
|
srid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "having srid" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry geometry expression
|
||||||
|
* @param srid SRID expression
|
||||||
|
*
|
||||||
|
* @return "having srid" predicate
|
||||||
|
*
|
||||||
|
* @see #havingSRID(CriteriaBuilder, Expression, Expression)
|
||||||
|
*/
|
||||||
|
public static Predicate havingSRID(
|
||||||
|
CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry,
|
||||||
|
int srid) {
|
||||||
|
return havingSRID( criteriaBuilder, geometry,
|
||||||
|
criteriaBuilder.literal( srid )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "is empty" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry geometry expression
|
||||||
|
*
|
||||||
|
* @return "is empty" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#isEmpty(String)
|
||||||
|
*/
|
||||||
|
public static Predicate isEmpty(CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry) {
|
||||||
|
return booleanExpressionToPredicate(
|
||||||
|
criteriaBuilder,
|
||||||
|
criteriaBuilder.function( SpatialFunction.isempty.toString(), boolean.class,
|
||||||
|
geometry
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a predicate for testing the arguments for "is not empty" constraint.
|
||||||
|
*
|
||||||
|
* @param criteriaBuilder CriteriaBuilder
|
||||||
|
* @param geometry geometry expression
|
||||||
|
*
|
||||||
|
* @return "is not empty" predicate
|
||||||
|
*
|
||||||
|
* @see SpatialRestrictions#isNotEmpty(String)
|
||||||
|
*/
|
||||||
|
public static Predicate isNotEmpty(CriteriaBuilder criteriaBuilder, Expression<? extends Geometry> geometry) {
|
||||||
|
return isEmpty( criteriaBuilder, geometry )
|
||||||
|
.not();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Predicate booleanExpressionToPredicate(
|
||||||
|
CriteriaBuilder criteriaBuilder,
|
||||||
|
Expression<Boolean> expression) {
|
||||||
|
return criteriaBuilder.equal( expression, true );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,264 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.spatial.integration;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Predicate;
|
||||||
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.spatial.HSMessageLogger;
|
||||||
|
import org.hibernate.spatial.SpatialFunction;
|
||||||
|
import org.hibernate.spatial.dialect.hana.HANASpatialDialect;
|
||||||
|
import org.hibernate.spatial.integration.jts.JtsGeomEntity;
|
||||||
|
import org.hibernate.spatial.predicate.SpatialPredicates;
|
||||||
|
import org.hibernate.spatial.testing.SpatialDialectMatcher;
|
||||||
|
import org.hibernate.spatial.testing.SpatialFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.hibernate.testing.Skip;
|
||||||
|
import org.hibernate.testing.SkipForDialect;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see TestSpatialRestrictions
|
||||||
|
*/
|
||||||
|
@Skip(condition = SpatialDialectMatcher.class, message = "No Spatial Dialect")
|
||||||
|
@SkipForDialect(value = HANASpatialDialect.class, comment = "The HANA dialect is tested via org.hibernate.spatial.dialect.hana.TestHANASpatialFunctions", jiraKey = "HHH-12426")
|
||||||
|
public class TestSpatialPredicates extends SpatialFunctionalTestCase {
|
||||||
|
|
||||||
|
private static HSMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
HSMessageLogger.class,
|
||||||
|
TestSpatialPredicates.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
protected HSMessageLogger getLogger() {
|
||||||
|
return LOG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void within() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.within ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getWithin( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.within( criteriaBuilder, root.get( "geom" ), expectationsFactory.getTestPolygon() );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void filter() throws SQLException {
|
||||||
|
if ( !dialectSupportsFiltering() ) {
|
||||||
|
LOG.info( "Filtering is not supported by Dialect" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getFilter( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.filter( criteriaBuilder, root.get( "geom" ), expectationsFactory.getTestPolygon() );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void contains() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.contains ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getContains( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.contains(
|
||||||
|
criteriaBuilder,
|
||||||
|
root.get( "geom" ),
|
||||||
|
expectationsFactory.getTestPolygon()
|
||||||
|
);
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void crosses() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.crosses ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getCrosses( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.crosses( criteriaBuilder, root.get( "geom" ), expectationsFactory.getTestPolygon() );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void touches() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.touches ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getTouches( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.touches( criteriaBuilder, root.get( "geom" ), expectationsFactory.getTestPolygon() );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void disjoint() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.disjoint ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getDisjoint( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.disjoint(
|
||||||
|
criteriaBuilder,
|
||||||
|
root.get( "geom" ),
|
||||||
|
expectationsFactory.getTestPolygon()
|
||||||
|
);
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void eq() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.equals ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getEquals( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.eq( criteriaBuilder, root.get( "geom" ), expectationsFactory.getTestPolygon() );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void intersects() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.intersects ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getIntersects( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.intersects(
|
||||||
|
criteriaBuilder,
|
||||||
|
root.get( "geom" ),
|
||||||
|
expectationsFactory.getTestPolygon()
|
||||||
|
);
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void overlaps() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.overlaps ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getOverlaps( expectationsFactory.getTestPolygon() );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.overlaps(
|
||||||
|
criteriaBuilder,
|
||||||
|
root.get( "geom" ),
|
||||||
|
expectationsFactory.getTestPolygon()
|
||||||
|
);
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dwithin() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.dwithin ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getDwithin( expectationsFactory.getTestPoint(), 30.0 );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.distanceWithin(
|
||||||
|
criteriaBuilder,
|
||||||
|
root.get( "geom" ),
|
||||||
|
expectationsFactory.getTestPoint(),
|
||||||
|
30.0
|
||||||
|
);
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isEmpty() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.isempty ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getIsEmpty();
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.isEmpty( criteriaBuilder, root.get( "geom" ) );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isNotEmpty() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.isempty ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.getIsNotEmpty();
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.isNotEmpty( criteriaBuilder, root.get( "geom" ) );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingSRID() throws SQLException {
|
||||||
|
if ( !isSupportedByDialect( SpatialFunction.srid ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Boolean> dbexpected = expectationsFactory.havingSRID( 4326 );
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.havingSRID( criteriaBuilder, root.get( "geom" ), 4326 );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
dbexpected = expectationsFactory.havingSRID( 31370 );
|
||||||
|
predicateFactory = (criteriaBuilder, root) ->
|
||||||
|
SpatialPredicates.havingSRID( criteriaBuilder, root.get( "geom" ), 31370 );
|
||||||
|
retrieveAndCompare( dbexpected, predicateFactory );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void retrieveAndCompare(
|
||||||
|
Map<Integer, Boolean> dbexpected,
|
||||||
|
BiFunction<CriteriaBuilder, Root<JtsGeomEntity>, Predicate> predicateFactory) {
|
||||||
|
try (Session session = openSession()) {
|
||||||
|
Transaction tx = null;
|
||||||
|
try {
|
||||||
|
tx = session.beginTransaction();
|
||||||
|
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<JtsGeomEntity> criteriaQuery = criteriaBuilder.createQuery( JtsGeomEntity.class );
|
||||||
|
Root<JtsGeomEntity> root = criteriaQuery.from( JtsGeomEntity.class );
|
||||||
|
criteriaQuery.select( root )
|
||||||
|
.where( predicateFactory.apply( criteriaBuilder, root ) );
|
||||||
|
List<JtsGeomEntity> list = session.createQuery( criteriaQuery )
|
||||||
|
.getResultList();
|
||||||
|
compare( dbexpected, list );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if ( tx != null ) {
|
||||||
|
tx.rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void compare(Map<Integer, Boolean> dbexpected, List<JtsGeomEntity> list) {
|
||||||
|
int cnt = dbexpected.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter( Map.Entry::getValue )
|
||||||
|
.reduce( 0, (accumulator, entry) -> {
|
||||||
|
if ( !findInList( entry.getKey(), list ) ) {
|
||||||
|
fail( String.format( "Expected object with id= %d, but not found in result", entry.getKey() ) );
|
||||||
|
}
|
||||||
|
return accumulator + 1;
|
||||||
|
}, Integer::sum );
|
||||||
|
assertEquals( cnt, list.size() );
|
||||||
|
LOG.infof( "Found %d objects within testsuite-suite polygon.", cnt );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean findInList(Integer id, List<JtsGeomEntity> list) {
|
||||||
|
return list.stream()
|
||||||
|
.anyMatch( entity -> entity.getId().equals( id ) );
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,6 @@ public class TestSupportFactories {
|
||||||
|
|
||||||
private static Class<? extends TestSupport> getSupportFactoryClass(Dialect dialect) {
|
private static Class<? extends TestSupport> getSupportFactoryClass(Dialect dialect) {
|
||||||
String canonicalName = dialect.getClass().getCanonicalName();
|
String canonicalName = dialect.getClass().getCanonicalName();
|
||||||
|
|
||||||
if ( ( dialect instanceof SpatialDialect ) && PostgreSQL82Dialect.class.isAssignableFrom( dialect.getClass() ) ) {
|
if ( ( dialect instanceof SpatialDialect ) && PostgreSQL82Dialect.class.isAssignableFrom( dialect.getClass() ) ) {
|
||||||
//this test works because all postgis dialects ultimately derive of the Postgresql82Dialect
|
//this test works because all postgis dialects ultimately derive of the Postgresql82Dialect
|
||||||
return PostgisTestSupport.class;
|
return PostgisTestSupport.class;
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
package org.hibernate.spatial.testing.dialects.postgis;
|
package org.hibernate.spatial.testing.dialects.postgis;
|
||||||
|
|
||||||
|
|
||||||
|
import org.hibernate.spatial.integration.TestSpatialFunctions;
|
||||||
|
import org.hibernate.spatial.integration.TestSpatialPredicates;
|
||||||
|
import org.hibernate.spatial.integration.TestSpatialRestrictions;
|
||||||
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
|
import org.hibernate.spatial.testing.AbstractExpectationsFactory;
|
||||||
import org.hibernate.spatial.testing.DataSourceUtils;
|
import org.hibernate.spatial.testing.DataSourceUtils;
|
||||||
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
import org.hibernate.spatial.testing.SQLExpressionTemplate;
|
||||||
|
@ -24,8 +27,10 @@ public class PostgisTestSupport extends TestSupport {
|
||||||
|
|
||||||
|
|
||||||
public TestData createTestData(BaseCoreFunctionalTestCase testcase) {
|
public TestData createTestData(BaseCoreFunctionalTestCase testcase) {
|
||||||
if ( testcase.getClass().getCanonicalName().contains( "TestSpatialFunctions" ) ||
|
Class<? extends BaseCoreFunctionalTestCase> testcaseClass = testcase.getClass();
|
||||||
testcase.getClass().getCanonicalName().contains( "TestSpatialRestrictions" ) ) {
|
if ( testcaseClass == TestSpatialFunctions.class ||
|
||||||
|
testcaseClass == TestSpatialRestrictions.class ||
|
||||||
|
testcaseClass == TestSpatialPredicates.class ) {
|
||||||
return TestData.fromFile( "postgis-functions-test.xml" );
|
return TestData.fromFile( "postgis-functions-test.xml" );
|
||||||
}
|
}
|
||||||
return TestData.fromFile( "test-data-set.xml" );
|
return TestData.fromFile( "test-data-set.xml" );
|
||||||
|
|
Loading…
Reference in New Issue