Skip to content

Commit da67eb3

Browse files
furqaankhanjiayuasu
authored andcommitted
[TASK-61] Add ST_AsHEXEWKB (#158)
* feat: add ST_AsHEXEWKB * fix: snowflake tests
1 parent e69b530 commit da67eb3

File tree

21 files changed

+297
-0
lines changed

21 files changed

+297
-0
lines changed

common/src/main/java/org/apache/sedona/common/Functions.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.locationtech.jts.geom.*;
3333
import org.locationtech.jts.geom.impl.CoordinateArraySequence;
3434
import org.locationtech.jts.geom.util.GeometryFixer;
35+
import org.locationtech.jts.io.ByteOrderValues;
3536
import org.locationtech.jts.io.gml2.GMLWriter;
3637
import org.locationtech.jts.io.kml.KMLWriter;
3738
import org.locationtech.jts.linearref.LengthIndexedLine;
@@ -548,6 +549,19 @@ public static byte[] asEWKB(Geometry geometry) {
548549
return GeomUtils.getEWKB(geometry);
549550
}
550551

552+
public static String asHexEWKB(Geometry geom, String endian) {
553+
if (endian.equalsIgnoreCase("NDR")) {
554+
return GeomUtils.getHexEWKB(geom, ByteOrderValues.LITTLE_ENDIAN);
555+
} else if (endian.equalsIgnoreCase("XDR")) {
556+
return GeomUtils.getHexEWKB(geom, ByteOrderValues.BIG_ENDIAN);
557+
}
558+
throw new IllegalArgumentException("You must select either NDR (little-endian) or XDR (big-endian) as the endian format.");
559+
}
560+
561+
public static String asHexEWKB(Geometry geom) {
562+
return asHexEWKB(geom, "NDR");
563+
}
564+
551565
public static byte[] asWKB(Geometry geometry) {
552566
return GeomUtils.getWKB(geometry);
553567
}

common/src/main/java/org/apache/sedona/common/utils/GeomUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ public static String getWKT(Geometry geometry) {
177177
return new WKTWriter(4).write(geometry);
178178
}
179179

180+
public static String getHexEWKB(Geometry geometry, int endian) {
181+
WKBWriter writer = new WKBWriter(GeomUtils.getDimension(geometry), endian, geometry.getSRID() != 0);
182+
return WKBWriter.toHex(writer.write(geometry));
183+
}
184+
180185
public static byte[] getEWKB(Geometry geometry) {
181186
if (geometry == null) {
182187
return null;

common/src/test/java/org/apache/sedona/common/FunctionsTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,39 @@ public void asWKB() throws Exception{
133133
assertEquals(expected, geometry);
134134
}
135135

136+
@Test
137+
public void asHexEWKB() throws ParseException {
138+
String[] geoms = {
139+
"POINT(1 2)",
140+
"LINESTRING (30 20, 20 25, 20 15, 30 20)",
141+
"POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (5 5, 5 8, 8 8, 8 5, 5 5))"
142+
143+
};
144+
String[] expected = {
145+
//NDR - little endian
146+
"0101000000000000000000F03F0000000000000040",
147+
"0102000000040000000000000000003E4000000000000034400000000000003440000000000000394000000000000034400000000000002E400000000000003E400000000000003440",
148+
"010300000002000000050000000000000000000000000000000000000000000000000024400000000000000000000000000000244000000000000024400000000000000000000000000000244000000000000000000000000000000000050000000000000000001440000000000000144000000000000014400000000000002040000000000000204000000000000020400000000000002040000000000000144000000000000014400000000000001440",
149+
150+
// XDR - big endian
151+
"00000000013FF00000000000004000000000000000",
152+
"000000000200000004403E0000000000004034000000000000403400000000000040390000000000004034000000000000402E000000000000403E0000000000004034000000000000",
153+
"000000000300000002000000050000000000000000000000000000000040240000000000000000000000000000402400000000000040240000000000000000000000000000402400000000000000000000000000000000000000000000000000054014000000000000401400000000000040140000000000004020000000000000402000000000000040200000000000004020000000000000401400000000000040140000000000004014000000000000"
154+
};
155+
testAsHexEWKB(geoms, expected);
156+
}
157+
158+
public void testAsHexEWKB(String[] geoms, String[] expected) throws ParseException {
159+
String[] endians = {"NDR", "XDR"};
160+
int offset = 0;
161+
for (String e: endians) {
162+
for (int i = 0; i < geoms.length; i++) {
163+
assertEquals(expected[i + offset], Functions.asHexEWKB(Constructors.geomFromWKT(geoms[i], 0), e));
164+
}
165+
offset = 3;
166+
}
167+
}
168+
136169
@Test
137170
public void pointFromWKB() throws Exception{
138171
Geometry geometry = GEOMETRY_FACTORY.createPoint(new Coordinate(1.0, 2.0));

docs/api/flink/Function.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,38 @@ Output:
397397
1.0,1.0 8.0,1.0 8.0,8.0 1.0,8.0 1.0,1.0
398398
```
399399

400+
## ST_AsHEXEWKB
401+
402+
Introduction: This function returns the input geometry encoded to a text representation in HEXEWKB format. The HEXEWKB encoding can use either little-endian (NDR) or big-endian (XDR) byte ordering. If no encoding is explicitly specified, the function defaults to using the little-endian (NDR) format.
403+
404+
Format: `ST_AsHEXEWKB(geom: Geometry, endian: String = NDR)`
405+
406+
Since: `vTBD`
407+
408+
SQL Example
409+
410+
```sql
411+
SELECT ST_AsHEXEWKB(ST_GeomFromWKT('POINT(1 2)'), 'XDR')
412+
```
413+
414+
Output:
415+
416+
```
417+
00000000013FF00000000000004000000000000000
418+
```
419+
420+
SQL Example
421+
422+
```sql
423+
SELECT ST_AsHEXEWKB(ST_GeomFromWKT('LINESTRING (30 20, 20 25, 20 15, 30 20)'))
424+
```
425+
426+
Output:
427+
428+
```
429+
0102000000040000000000000000003E4000000000000034400000000000003440000000000000394000000000000034400000000000002E400000000000003E400000000000003440
430+
```
431+
400432
## ST_AsKML
401433

402434
Introduction: Return the [KML](https://www.ogc.org/standards/kml) string representation of a geometry

docs/api/snowflake/vector-data/Function.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,36 @@ SELECT ST_AsGML(polygondf.countyshape)
292292
FROM polygondf
293293
```
294294

295+
## ST_AsHEXEWKB
296+
297+
Introduction: This function returns the input geometry encoded to a text representation in HEXEWKB format. The HEXEWKB encoding can use either little-endian (NDR) or big-endian (XDR) byte ordering. If no encoding is explicitly specified, the function defaults to using the little-endian (NDR) format.
298+
299+
Format: `ST_AsHEXEWKB(geom: Geometry, endian: String = NDR)`
300+
301+
SQL Example
302+
303+
```sql
304+
SELECT ST_AsHEXEWKB(ST_GeomFromWKT('POINT(1 2)'), 'XDR')
305+
```
306+
307+
Output:
308+
309+
```
310+
00000000013FF00000000000004000000000000000
311+
```
312+
313+
SQL Example
314+
315+
```sql
316+
SELECT ST_AsHEXEWKB(ST_GeomFromWKT('LINESTRING (30 20, 20 25, 20 15, 30 20)'))
317+
```
318+
319+
Output:
320+
321+
```
322+
0102000000040000000000000000003E4000000000000034400000000000003440000000000000394000000000000034400000000000002E400000000000003E400000000000003440
323+
```
324+
295325
## ST_AsKML
296326

297327
Introduction: Return the [KML](https://www.ogc.org/standards/kml) string representation of a geometry

docs/api/sql/Function.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,38 @@ Output:
394394
1.0,1.0 8.0,1.0 8.0,8.0 1.0,8.0 1.0,1.0
395395
```
396396

397+
## ST_AsHEXEWKB
398+
399+
Introduction: This function returns the input geometry encoded to a text representation in HEXEWKB format. The HEXEWKB encoding can use either little-endian (NDR) or big-endian (XDR) byte ordering. If no encoding is explicitly specified, the function defaults to using the little-endian (NDR) format.
400+
401+
Format: `ST_AsHEXEWKB(geom: Geometry, endian: String = NDR)`
402+
403+
Since: `vTBD`
404+
405+
SQL Example
406+
407+
```sql
408+
SELECT ST_AsHEXEWKB(ST_GeomFromWKT('POINT(1 2)'), 'XDR')
409+
```
410+
411+
Output:
412+
413+
```
414+
00000000013FF00000000000004000000000000000
415+
```
416+
417+
SQL Example
418+
419+
```sql
420+
SELECT ST_AsHEXEWKB(ST_GeomFromWKT('LINESTRING (30 20, 20 25, 20 15, 30 20)'))
421+
```
422+
423+
Output:
424+
425+
```
426+
0102000000040000000000000000003E4000000000000034400000000000003440000000000000394000000000000034400000000000002E400000000000003E400000000000003440
427+
```
428+
397429
## ST_AsKML
398430

399431
Introduction: Return the [KML](https://www.ogc.org/standards/kml) string representation of a geometry

flink/src/main/java/org/apache/sedona/flink/Catalog.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public static UserDefinedFunction[] getFuncs() {
9696
new Functions.ST_ExteriorRing(),
9797
new Functions.ST_AsEWKT(),
9898
new Functions.ST_AsEWKB(),
99+
new Functions.ST_AsHEXEWKB(),
99100
new Functions.ST_AsText(),
100101
new Functions.ST_AsBinary(),
101102
new Functions.ST_AsGeoJSON(),

flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,21 @@ public byte[] eval(@DataTypeHint(value = "RAW", bridgedTo = org.locationtech.jts
515515
}
516516
}
517517

518+
public static class ST_AsHEXEWKB extends ScalarFunction {
519+
@DataTypeHint("String")
520+
public String eval(@DataTypeHint(value = "RAW", bridgedTo = org.locationtech.jts.geom.Geometry.class) Object o,
521+
@DataTypeHint("String") String endian) {
522+
Geometry geom = (Geometry) o;
523+
return org.apache.sedona.common.Functions.asHexEWKB(geom, endian);
524+
}
525+
526+
@DataTypeHint("String")
527+
public String eval(@DataTypeHint(value = "RAW", bridgedTo = org.locationtech.jts.geom.Geometry.class) Object o) {
528+
Geometry geom = (Geometry) o;
529+
return org.apache.sedona.common.Functions.asHexEWKB(geom);
530+
}
531+
}
532+
518533
public static class ST_AsBinary extends ScalarFunction {
519534
@DataTypeHint("Bytes")
520535
public byte[] eval(@DataTypeHint(value = "RAW", bridgedTo = org.locationtech.jts.geom.Geometry.class) Object o) {

flink/src/test/java/org/apache/sedona/flink/FunctionTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,16 @@ public void testAsEWKB() {
612612
assertEquals("01030000000100000005000000000000000000e0bf000000000000e0bf000000000000e0bf000000000000e03f000000000000e03f000000000000e03f000000000000e03f000000000000e0bf000000000000e0bf000000000000e0bf", result);
613613
}
614614

615+
@Test
616+
public void testAsHEXEWKB() {
617+
Table pointTable = tableEnv.sqlQuery("SELECT ST_GeomFromWKT('POINT (1 2)') AS point");
618+
String result = (String) first(pointTable.select(call(Functions.ST_AsHEXEWKB.class.getSimpleName(), $("point"), "XDR"))).getField(0);
619+
assertEquals("00000000013FF00000000000004000000000000000", result);
620+
621+
result = (String) first(pointTable.select(call(Functions.ST_AsHEXEWKB.class.getSimpleName(), $("point")))).getField(0);
622+
assertEquals("0101000000000000000000F03F0000000000000040", result);
623+
}
624+
615625
@Test
616626
public void testAsBinary() {
617627
Table polygonTable = createPolygonTable(testDataSize);

python/sedona/sql/st_functions.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ def ST_AsEWKB(geometry: ColumnOrName) -> Column:
123123
"""
124124
return _call_st_function("ST_AsEWKB", geometry)
125125

126+
@validate_argument_types
127+
def ST_AsHEXEWKB(geometry: ColumnOrName, endian: Optional[ColumnOrName] = None) -> Column:
128+
"""Generate the Extended Well-Known Binary representation of a geometry as Hex string.
129+
130+
:param geometry: Geometry to generate EWKB for.
131+
:type geometry: ColumnOrName
132+
:return: Extended Well-Known Binary representation of geometry as Hex string.
133+
:rtype: Column
134+
"""
135+
args = (geometry) if endian is None else (geometry, endian)
136+
137+
return _call_st_function("ST_AsHEXEWKB", args)
138+
126139

127140
@validate_argument_types
128141
def ST_AsEWKT(geometry: ColumnOrName) -> Column:

0 commit comments

Comments
 (0)