Skip to content

Commit

Permalink
GIS #462: added some functions on Polygons
Browse files Browse the repository at this point in the history
  • Loading branch information
danylokravchenko committed Nov 9, 2023
1 parent 352d96b commit ded05a0
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,11 @@ public Expression implement( RexToLixTranslator translator, RexCall call, List<E
defineMethod( OperatorRegistry.get( OperatorName.ST_ISCOORDINATE ), BuiltInMethod.ST_ISCOORDINATE.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_STARTPOINT ), BuiltInMethod.ST_STARTPOINT.method, NullPolicy.STRICT );
defineMethod( OperatorRegistry.get( OperatorName.ST_ENDPOINT ), BuiltInMethod.ST_ENDPOINT.method, NullPolicy.STRICT );
// on Polygons
defineMethod( OperatorRegistry.get( OperatorName.ST_ISRECTANGLE ), BuiltInMethod.ST_ISRECTANGLE.method, NullPolicy.STRICT );
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 );
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,27 @@ 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
*/
ST_ISRECTANGLE( Function.class ),

/**
* The <code>ST_ExteriorRing</code> operator function: return the exterior ring {@link org.polypheny.db.type.entity.spatial.PolyGeometry} of the {@link org.polypheny.db.type.entity.spatial.PolyPolygon}
*/
ST_EXTERIORRING( Function.class ),

/**
* The <code>ST_NumInteriorRing</code> operator function: return the number of interior rings of the {@link org.polypheny.db.type.entity.spatial.PolyPolygon}
*/
ST_NUMINTERIORRING( Function.class ),

/**
* The <code>ST_InteriorRingN</code> operator function: return the nth interior ring of the {@link org.polypheny.db.type.entity.spatial.PolyPolygon}
*/
ST_INTERIORRINGN( Function.class ),

//-------------------------------------------------------------
// SET OPERATORS
//-------------------------------------------------------------
Expand Down
44 changes: 44 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 @@ -20,6 +20,7 @@

import org.polypheny.db.type.entity.PolyBoolean;
import org.polypheny.db.type.entity.PolyFloat;
import org.polypheny.db.type.entity.PolyInteger;
import org.polypheny.db.type.entity.PolyString;
import org.polypheny.db.type.entity.category.PolyNumber;
import org.polypheny.db.type.entity.spatial.InvalidGeometryException;
Expand All @@ -32,6 +33,7 @@ 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 GeoFunctions() {
Expand All @@ -58,6 +60,10 @@ public static PolyGeometry stGeoFromText( PolyString wkt, PolyNumber srid ) {
}
}

/*
* on Points
*/


@SuppressWarnings("UnusedDeclaration")
public static PolyFloat stX( PolyGeometry geometry ) {
Expand All @@ -79,6 +85,10 @@ public static PolyFloat stZ( PolyGeometry geometry ) {
return PolyFloat.of( geometry.asPoint().getZ() );
}

/*
* on LineStrings
*/


@SuppressWarnings("UnusedDeclaration")
public static PolyBoolean stIsClosed( PolyGeometry geometry ) {
Expand Down Expand Up @@ -115,6 +125,34 @@ public static PolyGeometry stEndPoint( PolyGeometry geometry ) {
return PolyGeometry.of( geometry.asLineString().getEndPoint().getJtsGeometry() );
}

/*
* on Polygons
*/
@SuppressWarnings("UnusedDeclaration")
public static PolyBoolean stIsRectangle( PolyGeometry geometry ) {
restrictToPolygons( geometry );
return PolyBoolean.of( geometry.asPolygon().isRectangle() );
}


@SuppressWarnings("UnusedDeclaration")
public static PolyGeometry stExteriorRing( PolyGeometry geometry ) {
restrictToPolygons( 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() );
}


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

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ public Consistency getConsistency() {

public static final PolySingleOperandTypeChecker GEOMETRY = family( PolyTypeFamily.GEO );
public static final PolySingleOperandTypeChecker GEOMETRY_GEOMETRY = family( PolyTypeFamily.GEO, PolyTypeFamily.GEO );
public static final PolySingleOperandTypeChecker GEOMETRY_INTEGER = family( PolyTypeFamily.GEO, PolyTypeFamily.INTEGER );

/**
* Checks that returns whether a value is a multiset or an array. Cf Java, where list and set are collections but a map is not.
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/org/polypheny/db/util/BuiltInMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
import org.polypheny.db.type.PolyType;
import org.polypheny.db.type.entity.PolyBoolean;
import org.polypheny.db.type.entity.PolyDate;
import org.polypheny.db.type.entity.PolyInteger;
import org.polypheny.db.type.entity.PolyInterval;
import org.polypheny.db.type.entity.PolyList;
import org.polypheny.db.type.entity.PolyString;
Expand Down Expand Up @@ -454,6 +455,11 @@ public enum BuiltInMethod {
ST_ISCOORDINATE( GeoFunctions.class, "stIsCoordinate", PolyGeometry.class, PolyGeometry.class ),
ST_STARTPOINT( GeoFunctions.class, "stStartPoint", PolyGeometry.class ),
ST_ENDPOINT( GeoFunctions.class, "stEndPoint", PolyGeometry.class ),
// on Polygons
ST_ISRECTANGLE( GeoFunctions.class, "stIsRectangle", PolyGeometry.class ),
ST_EXTERIORRING( GeoFunctions.class, "stExteriorRing", PolyGeometry.class ),
ST_NUMINTERIORRING( GeoFunctions.class, "stNumInteriorRing", PolyGeometry.class ),
ST_INTERIORRINGN( GeoFunctions.class, "stInteriorRingN", PolyGeometry.class, PolyInteger.class ),
/// MQL BUILT-IN METHODS
MQL_EQ( MqlFunctions.class, "docEq", PolyValue.class, PolyValue.class ),
MQL_GT( MqlFunctions.class, "docGt", PolyValue.class, PolyValue.class ),
Expand Down
34 changes: 34 additions & 0 deletions dbms/src/test/java/org/polypheny/db/sql/fun/GeoFunctionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,38 @@ public void lineStringsFunctions() throws SQLException {
}
}


@Test
public void polygonFunctions() throws SQLException {
try ( TestHelper.JdbcConnection polyphenyDbConnection = new TestHelper.JdbcConnection( true ) ) {
Connection connection = polyphenyDbConnection.getConnection();
try ( Statement statement = connection.createStatement() ) {
// test if polygon is rectangle
TestHelper.checkResultSet(
statement.executeQuery( "SELECT ST_IsRectangle(ST_GeoFromText('POLYGON ( (-1 -1, 2 2, -1 2, -1 -1 ) )'))" ),
ImmutableList.of(
new Object[]{ false }
) );
// retrieve the exterior ring of the polygon
TestHelper.checkResultSet(
statement.executeQuery( "SELECT ST_ExteriorRing(ST_GeoFromText('POLYGON ( (-1 -1, 2 2, -1 2, -1 -1 ) )'))" ),
ImmutableList.of(
new Object[]{ "SRID=0;LINEARRING (-1 -1, 2 2, -1 2, -1 -1)" }
) );
// retrieve the number of interior ring of the polygon
TestHelper.checkResultSet(
statement.executeQuery( "SELECT ST_NumInteriorRing(ST_GeoFromText('POLYGON((0.5 0.5,5 0,5 5,0 5,0.5 0.5), (1.5 1,4 3,4 1,1.5 1))'))" ),
ImmutableList.of(
new Object[]{ 1 }
) );
// retrieve the nth interior ring of the polygon
TestHelper.checkResultSet(
statement.executeQuery( "SELECT ST_InteriorRingN(ST_GeoFromText('POLYGON((0.5 0.5,5 0,5 5,0 5,0.5 0.5), (1.5 1,4 3,4 1,1.5 1))'), 0)" ),
ImmutableList.of(
new Object[]{ "SRID=0;LINEARRING (1.5 1, 4 3, 4 1, 1.5 1)" }
) );
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2571,6 +2571,47 @@ public void unparse( SqlWriter writer, SqlCall call, int leftPrec, int rightPrec
OperandTypes.GEOMETRY,
FunctionCategory.GEOMETRY ) );

// on Polygons
register(
OperatorName.ST_ISRECTANGLE,
new SqlFunction(
"ST_ISRECTANGLE",
Kind.GEO,
ReturnTypes.BOOLEAN,
InferTypes.GEOMETRY,
OperandTypes.GEOMETRY,
FunctionCategory.GEOMETRY ) );

register(
OperatorName.ST_EXTERIORRING,
new SqlFunction(
"ST_EXTERIORRING",
Kind.GEO,
ReturnTypes.GEOMETRY,
InferTypes.GEOMETRY,
OperandTypes.GEOMETRY,
FunctionCategory.GEOMETRY ) );

register(
OperatorName.ST_NUMINTERIORRING,
new SqlFunction(
"ST_NUMINTERIORRING",
Kind.GEO,
ReturnTypes.INTEGER,
InferTypes.GEOMETRY,
OperandTypes.GEOMETRY,
FunctionCategory.GEOMETRY ) );

register(
OperatorName.ST_INTERIORRINGN,
new SqlFunction(
"ST_INTERIORRINGN",
Kind.GEO,
ReturnTypes.GEOMETRY,
InferTypes.GEOMETRY,
OperandTypes.GEOMETRY_INTEGER,
FunctionCategory.GEOMETRY ) );

isInit = true;
}

Expand Down

0 comments on commit ded05a0

Please sign in to comment.