Skip to content

Commit a2df42d

Browse files
mpertierrambasmanova
authored andcommitted
Add ST_GeomFromWKB and ST_AsBinary functions
1 parent 412e989 commit a2df42d

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

presto-docs/src/main/sphinx/functions/geospatial.rst

+8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Presto Geospatial functions support the Well-Known Text (WKT) form of spatial ob
2222
Constructors
2323
------------
2424

25+
.. function:: ST_AsBinary(Geometry) -> varbinary
26+
27+
Returns the WKB representation of the geometry.
28+
2529
.. function:: ST_AsText(Geometry) -> varchar
2630

2731
Returns the WKT representation of the geometry. For empty geometries,
@@ -32,6 +36,10 @@ Constructors
3236

3337
Returns a geometry type object from WKT representation.
3438

39+
.. function:: ST_GeomFromBinary(varbinary) -> Geometry
40+
41+
Returns a geometry type object from WKB representation.
42+
3543
.. function:: ST_LineFromText(varchar) -> LineString
3644

3745
Returns a geometry type linestring object from WKT representation.

presto-geospatial/src/main/java/com/facebook/presto/plugin/geospatial/GeoFunctions.java

+32
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,15 @@
8080
import static com.facebook.presto.spi.type.StandardTypes.INTEGER;
8181
import static com.google.common.base.Preconditions.checkArgument;
8282
import static io.airlift.slice.Slices.utf8Slice;
83+
import static io.airlift.slice.Slices.wrappedBuffer;
8384
import static java.lang.Math.atan2;
8485
import static java.lang.Math.cos;
8586
import static java.lang.Math.sin;
8687
import static java.lang.Math.sqrt;
8788
import static java.lang.Math.toIntExact;
8889
import static java.lang.Math.toRadians;
8990
import static java.lang.String.format;
91+
import static java.util.Objects.requireNonNull;
9092
import static org.locationtech.jts.simplify.TopologyPreservingSimplifier.simplify;
9193

9294
public final class GeoFunctions
@@ -169,6 +171,14 @@ public static Slice stGeometryFromText(@SqlType(StandardTypes.VARCHAR) Slice inp
169171
return serialize(geometryFromText(input));
170172
}
171173

174+
@Description("Returns a Geometry type object from Well-Known Binary representation (WKB)")
175+
@ScalarFunction("ST_GeomFromBinary")
176+
@SqlType(GEOMETRY_TYPE_NAME)
177+
public static Slice stGeomFromBinary(@SqlType(StandardTypes.VARBINARY) Slice input)
178+
{
179+
return serialize(geomFromBinary(input));
180+
}
181+
172182
@Description("Returns the Well-Known Text (WKT) representation of the geometry")
173183
@ScalarFunction("ST_AsText")
174184
@SqlType(StandardTypes.VARCHAR)
@@ -177,6 +187,14 @@ public static Slice stAsText(@SqlType(GEOMETRY_TYPE_NAME) Slice input)
177187
return utf8Slice(deserialize(input).asText());
178188
}
179189

190+
@Description("Returns the Well-Known Binary (WKB) representation of the geometry")
191+
@ScalarFunction("ST_AsBinary")
192+
@SqlType(StandardTypes.VARBINARY)
193+
public static Slice stAsBinary(@SqlType(GEOMETRY_TYPE_NAME) Slice input)
194+
{
195+
return wrappedBuffer(deserialize(input).asBinary());
196+
}
197+
180198
@SqlNullable
181199
@Description("Returns the geometry that represents all points whose distance from the specified geometry is less than or equal to the specified distance")
182200
@ScalarFunction("ST_Buffer")
@@ -1044,6 +1062,20 @@ private static OGCGeometry geometryFromText(Slice input)
10441062
return geometry;
10451063
}
10461064

1065+
private static OGCGeometry geomFromBinary(Slice input)
1066+
{
1067+
requireNonNull(input, "input is null");
1068+
OGCGeometry geometry;
1069+
try {
1070+
geometry = OGCGeometry.fromBinary(input.toByteBuffer());
1071+
}
1072+
catch (IllegalArgumentException | IndexOutOfBoundsException e) {
1073+
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Invalid WKB", e);
1074+
}
1075+
geometry.setSpatialReference(null);
1076+
return geometry;
1077+
}
1078+
10471079
private static void validateType(String function, OGCGeometry geometry, Set<GeometryType> validTypes)
10481080
{
10491081
GeometryType type = GeometryType.getForEsriGeometryType(geometry.geometryType());

presto-geospatial/src/test/java/com/facebook/presto/plugin/geospatial/TestGeoFunctions.java

+37
Original file line numberDiff line numberDiff line change
@@ -1010,4 +1010,41 @@ public void testSTGeometryType()
10101010
assertFunction("ST_GeometryType(ST_GeometryFromText('GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6, 7 10))'))", VARCHAR, "ST_GeomCollection");
10111011
assertFunction("ST_GeometryType(ST_Envelope(ST_GeometryFromText('LINESTRING (1 1, 2 2)')))", VARCHAR, "ST_Polygon");
10121012
}
1013+
1014+
@Test
1015+
public void testSTGeometryFromBinary()
1016+
{
1017+
assertFunction("ST_GeomFromBinary(null)", GEOMETRY, null);
1018+
1019+
// empty geometries
1020+
assertGeomFromBinary("POINT EMPTY");
1021+
assertGeomFromBinary("MULTIPOINT EMPTY");
1022+
assertGeomFromBinary("LINESTRING EMPTY");
1023+
assertGeomFromBinary("MULTILINESTRING EMPTY");
1024+
assertGeomFromBinary("POLYGON EMPTY");
1025+
assertGeomFromBinary("MULTIPOLYGON EMPTY");
1026+
assertGeomFromBinary("GEOMETRYCOLLECTION EMPTY");
1027+
1028+
// valid nonempty geometries
1029+
assertGeomFromBinary("POINT (1 2)");
1030+
assertGeomFromBinary("MULTIPOINT ((1 2), (3 4))");
1031+
assertGeomFromBinary("LINESTRING (0 0, 1 2, 3 4)");
1032+
assertGeomFromBinary("MULTILINESTRING ((1 1, 5 1), (2 4, 4 4))");
1033+
assertGeomFromBinary("POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))");
1034+
assertGeomFromBinary("POLYGON ((0 0, 3 0, 3 3, 0 3, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1))");
1035+
assertGeomFromBinary("MULTIPOLYGON (((1 1, 3 1, 3 3, 1 3, 1 1)), ((2 4, 6 4, 6 6, 2 6, 2 4)))");
1036+
assertGeomFromBinary("GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (0 0, 1 2, 3 4), POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)))");
1037+
1038+
// invalid geometries
1039+
assertGeomFromBinary("MULTIPOINT ((0 0), (0 1), (1 1), (0 1))");
1040+
assertGeomFromBinary("LINESTRING (0 0, 0 1, 0 1, 1 1, 1 0, 0 0)");
1041+
1042+
// invalid binary
1043+
assertInvalidFunction("ST_GeomFromBinary(from_hex('deadbeef'))", "Invalid WKB");
1044+
}
1045+
1046+
private void assertGeomFromBinary(String wkt)
1047+
{
1048+
assertFunction(format("ST_AsText(ST_GeomFromBinary(ST_AsBinary(ST_GeometryFromText('%s'))))", wkt), VARCHAR, wkt);
1049+
}
10131050
}

0 commit comments

Comments
 (0)