From 6475353f3d81dc57cca5c6b40654098e0635bbda Mon Sep 17 00:00:00 2001 From: Jia Yu Date: Wed, 29 Jul 2026 00:17:31 -0700 Subject: [PATCH] [GH-3200] Serialize empty Geography LineStrings as valid WKB --- .../sedona/common/S2Geography/WKBWriter.java | 4 ++++ .../common/S2Geography/WKBGeographyTest.java | 14 ++++++++++++++ .../sedona/common/S2Geography/WKBWriterTest.java | 12 ++++++++++++ 3 files changed, 30 insertions(+) diff --git a/common/src/main/java/org/apache/sedona/common/S2Geography/WKBWriter.java b/common/src/main/java/org/apache/sedona/common/S2Geography/WKBWriter.java index 32a8651270b..1559a8aa6d5 100644 --- a/common/src/main/java/org/apache/sedona/common/S2Geography/WKBWriter.java +++ b/common/src/main/java/org/apache/sedona/common/S2Geography/WKBWriter.java @@ -250,6 +250,10 @@ private void writePolyline(int geometryType, SinglePolylineGeography polyline, O writeByteOrder(os); writeGeometryType(geometryType, polyline, os); List s2line = polyline.getPolylines(); + if (s2line.isEmpty()) { + writeInt(0, os); + return; + } for (S2Polyline s2 : s2line) { List verts = s2.vertices(); writeInt(verts.size(), os); diff --git a/common/src/test/java/org/apache/sedona/common/S2Geography/WKBGeographyTest.java b/common/src/test/java/org/apache/sedona/common/S2Geography/WKBGeographyTest.java index 165cdecd9bb..dae3aae79a6 100644 --- a/common/src/test/java/org/apache/sedona/common/S2Geography/WKBGeographyTest.java +++ b/common/src/test/java/org/apache/sedona/common/S2Geography/WKBGeographyTest.java @@ -28,6 +28,7 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.Point; import org.locationtech.jts.io.ByteOrderValues; import org.locationtech.jts.io.ParseException; @@ -137,6 +138,19 @@ public void fromS2Geography_point() { assertSame(s2Geog, roundTrip); } + @Test + public void fromS2Geography_emptyLineString_roundTripsToJTS() { + Geography s2Geog = new SinglePolylineGeography(); + s2Geog.setSRID(4326); + + WKBGeography geog = WKBGeography.fromS2Geography(s2Geog); + Geometry jts = geog.getJTSGeometry(); + + assertTrue(jts instanceof LineString); + assertTrue(jts.isEmpty()); + assertEquals(4326, jts.getSRID()); + } + // ─── Lazy S2 delegation ────────────────────────────────────────────────── @Test diff --git a/common/src/test/java/org/apache/sedona/common/S2Geography/WKBWriterTest.java b/common/src/test/java/org/apache/sedona/common/S2Geography/WKBWriterTest.java index d905635ca45..3b4c2ac3c45 100644 --- a/common/src/test/java/org/apache/sedona/common/S2Geography/WKBWriterTest.java +++ b/common/src/test/java/org/apache/sedona/common/S2Geography/WKBWriterTest.java @@ -90,6 +90,18 @@ public void PolylineGeographyToHexTest() throws IOException, ParseException { } } + @Test + public void EmptySinglePolylineWritesValidWKB() throws IOException, ParseException { + Geography inputLine = new SinglePolylineGeography(); + + byte[] wkb = new WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN, false).write(inputLine); + + assertEquals("010200000000000000", WKBWriter.toHex(wkb)); + Geography outputLine = new WKBReader().read(wkb); + assertTrue(outputLine instanceof SinglePolylineGeography); + assertEquals(0, outputLine.numShapes()); + } + @Test public void MultiPointTest() throws ParseException, IOException { String wkt = "MULTIPOINT ((10 40), (40 30))";