Skip to content

Commit

Permalink
GIS #462: added functions to query geometry properties
Browse files Browse the repository at this point in the history
  • Loading branch information
danylokravchenko committed Dec 10, 2023
1 parent abd2240 commit b9c6a88
Show file tree
Hide file tree
Showing 11 changed files with 658 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,21 @@ public Expression implement( RexToLixTranslator translator, RexCall call, List<E
winAggMap.put( OperatorRegistry.getAgg( OperatorName.REGR_COUNT ), constructorSupplier( CountWinImplementor.class ) );

// geo functions
defineMethod( OperatorRegistry.get( OperatorName.ST_GEOFROMTEXT ), BuiltInMethod.ST_GEO_FROM_TEXT.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_GEOFROMTEXT ), BuiltInMethod.ST_GEOFROMTEXT.method, NullPolicy.STRICT );
// Common properties
defineMethod( OperatorRegistry.get( OperatorName.ST_ISSIMPLE ), BuiltInMethod.ST_ISSIMPLE.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_ISEMPTY ), BuiltInMethod.ST_ISEMPTY.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_NUMPOINTS ), BuiltInMethod.ST_NUMPOINTS.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_DIMENSION ), BuiltInMethod.ST_DIMENSION.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_LENGTH ), BuiltInMethod.ST_LENGTH.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_AREA ), BuiltInMethod.ST_AREA.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_ENVELOPE ), BuiltInMethod.ST_ENVELOPE.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_BOUNDARY ), BuiltInMethod.ST_BOUNDARY.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_BOUNDARYDIMENSION ), BuiltInMethod.ST_BOUNDARYDIMENSION.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_CONVEXHULL ), BuiltInMethod.ST_CONVEXHULL.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_CENTROID ), BuiltInMethod.ST_CENTROID.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_REVERSE ), BuiltInMethod.ST_REVERSE.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_BUFFER ), BuiltInMethod.ST_BUFFER.method, NullPolicy.STRICT );
// on Points
defineMethod( OperatorRegistry.get( OperatorName.ST_X ), BuiltInMethod.ST_X.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_Y ), BuiltInMethod.ST_Y.method, NullPolicy.STRICT );
Expand All @@ -384,6 +398,9 @@ public Expression implement( RexToLixTranslator translator, RexCall call, List<E
defineMethod( OperatorRegistry.get( OperatorName.ST_EXTERIORRING ), BuiltInMethod.ST_EXTERIORRING.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_NUMINTERIORRING ), BuiltInMethod.ST_NUMINTERIORRING.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_INTERIORRINGN ), BuiltInMethod.ST_INTERIORRINGN.method, NullPolicy.STRICT );
// on GeometryCollection
defineMethod( OperatorRegistry.get( OperatorName.ST_NUMGEOMETRIES ), BuiltInMethod.ST_NUMGEOMETRIES.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_GEOMETRYN ), BuiltInMethod.ST_GEOMETRYN.method, NullPolicy.STRICT );
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,73 @@ public enum OperatorName {
*/
ST_GEOFROMTEXT( Function.class ),

// Common properties

/**
* The <code>ST_IsSimple</code> operator function: check that {@link org.polypheny.db.type.entity.spatial.PolyGeometry} is simple
*/
ST_ISSIMPLE( Function.class ),

/**
* The <code>ST_IsEmpty</code> operator function: check that {@link org.polypheny.db.type.entity.spatial.PolyGeometry} is empty
*/
ST_ISEMPTY( Function.class ),

/**
* The <code>ST_NumPoints</code> operator function: receive the number of points in the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_NUMPOINTS( Function.class ),

/**
* The <code>ST_Dimension</code> operator function: receive the dimension of the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_DIMENSION( Function.class ),

/**
* The <code>ST_Length</code> operator function: receive the length of the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_LENGTH( Function.class ),

/**
* The <code>ST_Area</code> operator function: receive the area of the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_AREA( Function.class ),

/**
* The <code>ST_Envelope</code> operator function: receive the minimum bounding box {@link org.polypheny.db.type.entity.spatial.PolyGeometry} that would include the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_ENVELOPE( Function.class ),

/**
* The <code>ST_Boundary</code> operator function: receive the boundary of the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_BOUNDARY( Function.class ),

/**
* The <code>ST_BoundaryDimension</code> operator function: receive the boundary dimension of the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_BOUNDARYDIMENSION( Function.class ),

/**
* The <code>ST_ConvexHull</code> operator function: receive the convex full of the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_CONVEXHULL( Function.class ),

/**
* The <code>ST_Centroid</code> operator function: receive the centroid of the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_CENTROID( Function.class ),

/**
* The <code>ST_Reverse</code> operator function: reverse the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_REVERSE( Function.class ),

/**
* The <code>ST_Buffer</code> operator function: receive the buffer {@link org.polypheny.db.type.entity.spatial.PolyGeometry} around the {@link org.polypheny.db.type.entity.spatial.PolyGeometry}
*/
ST_BUFFER( Function.class ),

// Functions on Points

/**
Expand Down Expand Up @@ -1358,6 +1425,7 @@ public enum OperatorName {
ST_ENDPOINT( Function.class ),

// Functions on Polygons

/**
* The <code>ST_IsRectangle</code> operator function: check that {@link org.polypheny.db.type.entity.spatial.PolyPolygon} is rectangle
*/
Expand All @@ -1378,6 +1446,17 @@ public enum OperatorName {
*/
ST_INTERIORRINGN( Function.class ),

// Functions on GeometryCollection
/**
* The <code>ST_NumGeometries</code> operator function: return the number of {@link org.polypheny.db.type.entity.spatial.PolyGeometry} in {@link org.polypheny.db.type.entity.spatial.PolyGeometryCollection}
*/
ST_NUMGEOMETRIES( Function.class ),

/**
* The <code>ST_GeometryN</code> operator function: return the nth geometry in the {@link org.polypheny.db.type.entity.spatial.PolyGeometryCollection}
*/
ST_GEOMETRYN( Function.class ),

//-------------------------------------------------------------
// SET OPERATORS
//-------------------------------------------------------------
Expand Down Expand Up @@ -1511,20 +1590,12 @@ public enum OperatorName {
EXTRACT_NAME( LangFunctionOperator.class );


final public static List<OperatorName> MQL_OPERATORS = Arrays.asList( MQL_EQUALS, MQL_GT, MQL_GTE, MQL_LT, MQL_LTE );
@Getter
private final Class<? extends Operator> clazz;


OperatorName( Class<? extends Operator> clazz ) {
this.clazz = clazz;
}


final public static List<OperatorName> MQL_OPERATORS = Arrays.asList(
MQL_EQUALS,
MQL_GT,
MQL_GTE,
MQL_LT,
MQL_LTE
);
}
121 changes: 121 additions & 0 deletions core/src/main/java/org/polypheny/db/functions/GeoFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.polypheny.db.type.entity.category.PolyNumber;
import org.polypheny.db.type.entity.spatial.InvalidGeometryException;
import org.polypheny.db.type.entity.spatial.PolyGeometry;
import org.polypheny.db.type.entity.spatial.PolyGeometryType.BufferCapStyle;

/**
* Implementations of Geo functions
Expand All @@ -34,12 +35,17 @@ public class GeoFunctions {
private static final String POINT_RESTRICTION = "This function could be applied only to points";
private static final String LINE_STRING_RESTRICTION = "This function could be applied only to line strings";
private static final String POLYGON_RESTRICTION = "This function could be applied only to polygons";
private static final String GEOMETRY_COLLECTION_RESTRICTION = "This function could be applied only to geometry collections";


private GeoFunctions() {
// empty on purpose
}

/*
* Create Geometry
*/


@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stGeoFromText( PolyString wkt ) {
Expand All @@ -60,6 +66,89 @@ public static PolyGeometry stGeoFromText( PolyString wkt, PolyNumber srid ) {
}
}

/*
* Common properties
*/
@SuppressWarnings("UnusedDeclaration")
public static PolyBoolean stIsSimple( PolyGeometry geometry ) {
return PolyBoolean.of( geometry.isSimple() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyBoolean stIsEmpty( PolyGeometry geometry ) {
return PolyBoolean.of( geometry.isEmpty() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyInteger stNumPoints( PolyGeometry geometry ) {
return PolyInteger.of( geometry.getNumPoints() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyInteger stDimension( PolyGeometry geometry ) {
return PolyInteger.of( geometry.getDimension() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyFloat stLength( PolyGeometry geometry ) {
return PolyFloat.of( geometry.getLength() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyFloat stArea( PolyGeometry geometry ) {
return PolyFloat.of( geometry.getArea() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stEnvelope( PolyGeometry geometry ) {
return geometry.getEnvelope();
}

@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stBoundary( PolyGeometry geometry ) {
return geometry.getBoundary();
}

@SuppressWarnings("UnusedDeclaration")
public static PolyInteger stBoundaryDimension( PolyGeometry geometry ) {
return PolyInteger.of (geometry.getBoundaryDimension() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stConvexHull( PolyGeometry geometry ) {
return geometry.convexHull();
}

@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stCentroid( PolyGeometry geometry ) {
return geometry.getCentroid();
}

@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stReverse( PolyGeometry geometry ) {
return geometry.reverse();
}

@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stBuffer( PolyGeometry geometry, PolyNumber distance ) {
return geometry.buffer( distance.doubleValue() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stBuffer( PolyGeometry geometry, PolyNumber distance, PolyNumber quadrantSegments ) {
return geometry.buffer( distance.doubleValue(), quadrantSegments.intValue() );
}

@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stBuffer( PolyGeometry geometry, PolyNumber distance, PolyNumber quadrantSegments, PolyString endCapStyle ) {
return geometry.buffer( distance.doubleValue(), quadrantSegments.intValue(), BufferCapStyle.of( endCapStyle.value ) );
}


/*
* Geometry Specific Functions
*/

/*
* on Points
*/
Expand Down Expand Up @@ -128,6 +217,7 @@ public static PolyGeometry stEndPoint( PolyGeometry geometry ) {
/*
* on Polygons
*/

@SuppressWarnings("UnusedDeclaration")
public static PolyBoolean stIsRectangle( PolyGeometry geometry ) {
restrictToPolygons( geometry );
Expand All @@ -141,18 +231,41 @@ public static PolyGeometry stExteriorRing( PolyGeometry geometry ) {
return geometry.asPolygon().getExteriorRing();
}


@SuppressWarnings("UnusedDeclaration")
public static PolyInteger stNumInteriorRing( PolyGeometry geometry ) {
restrictToPolygons( geometry );
return PolyInteger.of( geometry.asPolygon().getNumInteriorRing() );
}


@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stInteriorRingN( PolyGeometry geometry, PolyNumber n ) {
restrictToPolygons( geometry );
return PolyGeometry.of( geometry.asPolygon().getInteriorRingN( n.intValue() ).getJtsGeometry() );
}

/*
* on GeometryCollection
*/


@SuppressWarnings("UnusedDeclaration")
public static PolyInteger stNumGeometries( PolyGeometry geometry ) {
restrictToGeometryCollection( geometry );
return PolyInteger.of( geometry.asGeometryCollection().getNumGeometries() );
}


@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stGeometryN( PolyGeometry geometry, PolyNumber n ) {
restrictToGeometryCollection( geometry );
return geometry.asGeometryCollection().getGeometryN( n.intValue() );
}

/*
* Helpers
*/

private static void restrictToPoints( PolyGeometry geometry ) {
if ( !geometry.isPoint() ) {
Expand All @@ -167,10 +280,18 @@ private static void restrictToLineStrings( PolyGeometry geometry ) {
}
}


private static void restrictToPolygons( PolyGeometry geometry ) {
if ( !geometry.isPolygon() ) {
throw toUnchecked( new InvalidGeometryException( POLYGON_RESTRICTION ) );
}
}


private static void restrictToGeometryCollection( PolyGeometry geometry ) {
if ( !geometry.isGeometryCollection() ) {
throw toUnchecked( new InvalidGeometryException( GEOMETRY_COLLECTION_RESTRICTION ) );
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ public interface PolyphenyDbResource {
@BaseMessage("Expected a multimedia type")
ExInst<ValidatorException> expectedMultimedia();

@BaseMessage("Expected a geo type")
ExInst<ValidatorException> expectedGeometry();

@BaseMessage("ELSE clause or at least one THEN clause must be non-NULL")
ExInst<ValidatorException> mustNotNullInElse();

Expand Down
7 changes: 7 additions & 0 deletions core/src/main/java/org/polypheny/db/type/PolyTypeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,13 @@ public static boolean inBooleanFamily( AlgDataType type ) {
return type.getFamily() == PolyTypeFamily.BOOLEAN;
}

/**
* @return true if type is in SqlTypeFamily.Geo
*/
public static boolean inGeoFamily( AlgDataType type ) {
return type.getFamily() == PolyTypeFamily.GEO;
}


/**
* @return true if two types are in same type family
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ public PolyPoint getCentroid() {
* @return a {@link PolyPolygon} that represent buffer region around this {@link PolyGeometry}
*/
public PolyGeometry buffer( double distance ) {
return PolyPoint.of( jtsGeometry.buffer( distance ) );
return PolyGeometry.of( jtsGeometry.buffer( distance ) );
}


Expand All @@ -400,7 +400,7 @@ public PolyGeometry buffer( double distance ) {
* @return a {@link PolyPolygon} that represent buffer region around this {@link PolyGeometry}
*/
public PolyGeometry buffer( double distance, int quadrantSegments ) {
return PolyPoint.of( jtsGeometry.buffer( distance, quadrantSegments ) );
return PolyGeometry.of( jtsGeometry.buffer( distance, quadrantSegments ) );
}


Expand All @@ -417,7 +417,7 @@ public PolyGeometry buffer( double distance, int quadrantSegments ) {
* @return a {@link PolyPolygon} that represent buffer region around this {@link PolyGeometry}
*/
public PolyGeometry buffer( double distance, int quadrantSegments, BufferCapStyle endCapStyle ) {
return PolyPoint.of( jtsGeometry.buffer( distance, quadrantSegments, endCapStyle.code ) );
return PolyGeometry.of( jtsGeometry.buffer( distance, quadrantSegments, endCapStyle.code ) );
}


Expand Down
Loading

0 comments on commit b9c6a88

Please sign in to comment.