Kontinuation commented on code in PR #2298:
URL: https://github.com/apache/sedona/pull/2298#discussion_r2286898407


##########
common/src/test/java/org/apache/sedona/common/Geography/ConstructorsTest.java:
##########
@@ -245,4 +245,27 @@ public void polygon_threeHoles() throws Exception {
     assertEquals(expected, got.toString());
     assertEquals(0, got.getSRID());
   }
+
+  @Test
+  public void geomToGeography() throws Exception {
+    String wkt =
+        "MULTIPOLYGON ("
+            +
+            // Component A: outer shell + lake
+            "((10 10, 70 10, 70 70, 10 70, 10 10),"
+            + " (20 20, 60 20, 60 60, 20 60, 20 20)),"
+            +
+            // Component B: island with a pond
+            " ((30 30, 50 30, 50 50, 30 50, 30 30),"
+            + " (36 36, 44 36, 44 44, 36 44, 36 36))"
+            + ")";
+    Geometry g = new org.locationtech.jts.io.WKTReader().read(wkt);
+    g.setSRID(4326);
+    Geography got = Constructors.geomToGeography(g);
+    String expected = "SRID=4326; " + wkt;
+    assertEquals(4326, got.getSRID());
+    org.locationtech.jts.io.WKTWriter wktWriter = new 
org.locationtech.jts.io.WKTWriter();
+    wktWriter.setPrecisionModel(new PrecisionModel(PrecisionModel.FIXED));
+    assertEquals(expected, got.toString());
+  }

Review Comment:
   We need more tests to achieve full coverage of geometry types and their 
internal structures.



##########
common/src/main/java/org/apache/sedona/common/geography/Constructors.java:
##########
@@ -264,4 +264,271 @@ private static Geometry collectionToGeom(Geography g, 
GeometryFactory gf) {
     }
     return gf.createGeometryCollection(gs);
   }
+
+  public static Geography geomToGeography(Geometry geom) throws IOException {
+    if (geom == null) {
+      return null;
+    }
+    String type = geom.getGeometryType();
+    if ("Point".equalsIgnoreCase(type)) {
+      return pointToGeog(geom);
+    } else if ("MultiPoint".equalsIgnoreCase(type)) {
+      return mPointToGeog(geom);
+    } else if ("LineString".equalsIgnoreCase(type)) {
+      return lineToGeog(geom);
+    } else if ("MultiLineString".equalsIgnoreCase(type)) {
+      return mLineToGeog(geom);
+    } else if ("Polygon".equalsIgnoreCase(type)) {
+      return polyToGeog(geom);
+    } else if ("MultiPolygon".equalsIgnoreCase(type)) {
+      return mPolyToGeog(geom);
+    } else if ("GeometryCollection".equalsIgnoreCase(type)) {
+      return geomCollToGeog(geom);
+    } else {
+      throw new UnsupportedOperationException("Unsupported geometry type: " + 
type);
+    }
+  }
+
+  private static Geography pointToGeog(Geometry geom) throws IOException {
+    Coordinate[] pts = geom.getCoordinates();
+    if (pts.length == 0 || Double.isNaN(pts[0].x) || Double.isNaN(pts[0].y)) {
+      return new SinglePointGeography();
+    }
+    double lon = pts[0].x;
+    double lat = pts[0].y;
+
+    S2Point s2Point = S2LatLng.fromDegrees(lat, lon).toPoint();
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PointVectorLayer layer = new S2PointVectorLayer();
+    builder.startLayer(layer);
+    builder.addPoint(s2Point);
+
+    S2Error error = new S2Error();
+    if (!builder.build(error)) {
+      throw new IOException("Failed to build S2 point layer: " + error.text());
+    }
+    List<S2Point> points = layer.getPointVector();
+    if (points.isEmpty()) {
+      return new SinglePointGeography();
+    }
+    return new SinglePointGeography(points.get(0));
+  }
+
+  private static Geography mPointToGeog(Geometry geom) throws IOException {
+    Coordinate[] pts = geom.getCoordinates();
+    if (pts.length == 0 || Double.isNaN(pts[0].x) || Double.isNaN(pts[0].y)) {
+      return new PointGeography();
+    }
+    List<S2Point> points = new ArrayList<>(pts.length);
+    // Build via S2Builder + S2PointVectorLayer
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PointVectorLayer layer = new S2PointVectorLayer();
+    // must call build() before reading out the points
+    S2Error error = new S2Error();
+    for (int i = 0; i < pts.length; i++) {
+      double lon = pts[i].x;
+      double lat = pts[i].y;
+      S2Point s2Point = S2LatLng.fromDegrees(lat, lon).toPoint();
+
+      builder.startLayer(layer);
+      builder.addPoint(s2Point);
+
+      if (!builder.build(error)) {
+        throw new IOException("Failed to build S2 point layer: " + 
error.text());
+      }
+    }
+    for (int i = 0; i < layer.getPointVector().size(); i++) {
+      // Extract the resulting points
+      points.add(layer.getPointVector().get(i));
+    }
+    return new PointGeography(points);
+  }
+
+  private static Geography lineToGeog(Geometry geom) throws IOException {
+    LineString ls = (LineString) geom;
+
+    // Build S2 points
+    List<S2Point> pts = toS2Points(ls.getCoordinates());
+    if (pts.size() < 2) {
+      // empty or degenerate → empty single polyline
+      SinglePolylineGeography empty = new SinglePolylineGeography();
+      empty.setSRID(geom.getSRID());
+      return empty;
+    }
+
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PolylineLayer layer = new S2PolylineLayer();
+    builder.startLayer(layer);
+
+    builder.addPolyline(new S2Polyline(pts));
+
+    S2Error error = new S2Error();
+    if (!builder.build(error)) {
+      throw new IOException("Failed to build S2 polyline: " + error.text());
+    }
+    S2Polyline s2poly = layer.getPolyline();
+    return new SinglePolylineGeography(s2poly);
+  }
+
+  private static Geography mLineToGeog(Geometry geom) throws IOException {
+    MultiLineString mls = (MultiLineString) geom;
+    List<S2Polyline> features = new ArrayList<>();
+    for (int i = 0; i < mls.getNumGeometries(); i++) {
+      LineString ls = (LineString) mls.getGeometryN(i);
+      List<S2Point> pts = toS2Points(ls.getCoordinates());
+      if (pts.size() >= 2) {
+        S2Builder builder = new S2Builder.Builder().build();
+        S2PolylineLayer layer = new S2PolylineLayer();
+        builder.startLayer(layer);
+        builder.addPolyline(new S2Polyline(pts));
+        S2Error error = new S2Error();
+        if (!builder.build(error)) {
+          throw new IOException("Failed to build S2 polyline: " + 
error.text());
+        }
+        features.add(layer.getPolyline());
+      }
+      // Empty/degenerate parts are skipped
+    }
+    return new PolylineGeography(features);
+  }
+
+  private static Geography polyToGeog(Geometry geom) throws IOException {
+    // Build S2 loops: exterior + holes
+    Polygon poly = (Polygon) geom;
+    // Construct S2 polygon (parity handles holes automatically)
+    S2Polygon s2poly = toS2Polygon(poly);
+    PolygonGeography g = new PolygonGeography(s2poly);
+    g.setSRID(geom.getSRID());
+    return g;
+  }
+
+  private static Geography mPolyToGeog(Geometry geom) throws IOException {
+    final List<S2Polygon> polys = new ArrayList<>();
+
+    MultiPolygon mp = (MultiPolygon) geom;
+    for (int i = 0; i < mp.getNumGeometries(); i++) {
+      Polygon p = (Polygon) mp.getGeometryN(i);
+      S2Polygon s2 = toS2Polygon(p);
+      if (s2 != null && !s2.isEmpty()) polys.add(s2);
+    }
+
+    MultiPolygonGeography out =
+        new MultiPolygonGeography(
+            Geography.GeographyKind.MULTIPOLYGON, 
Collections.unmodifiableList(polys));
+    out.setSRID(geom.getSRID());
+    return out;
+  }
+
+  private static Geography geomCollToGeog(Geometry geom) throws IOException {
+    if (!(geom instanceof GeometryCollection)) {
+      throw new IllegalArgumentException(
+          "geomCollToGeog expects GeometryCollection, got " + 
geom.getGeometryType());
+    }
+    GeographyCollection coll = new GeographyCollection();
+
+    GeometryCollection gc = (GeometryCollection) geom;
+    for (int i = 0; i < gc.getNumGeometries(); i++) {
+      Geometry g = gc.getGeometryN(i);
+      Geography sub = null;
+
+      if (g instanceof Point) {
+        sub = pointToGeog((Point) g);
+      } else if (g instanceof MultiPoint) {
+        MultiPoint mp = (MultiPoint) g;
+        for (int k = 0; k < mp.getNumGeometries(); k++) {
+          coll.features.add(pointToGeog((Point) mp.getGeometryN(k)));
+        }
+        continue;
+      } else if (g instanceof LineString) {
+        sub = lineToGeog(g);
+      } else if (g instanceof MultiLineString) {
+        sub = mLineToGeog(g);
+      } else if (g instanceof Polygon) {
+        sub = polyToGeog(g);
+      } else if (g instanceof MultiPolygon) {
+        sub = mPolyToGeog(g);
+      } else if (g instanceof GeometryCollection) {
+        sub = geomCollToGeog(g);
+      }
+      if (sub != null) coll.features.add(sub);

Review Comment:
   Why not call `geomToGeography` but replicate the code here?



##########
common/src/main/java/org/apache/sedona/common/geography/Constructors.java:
##########
@@ -264,4 +264,271 @@ private static Geometry collectionToGeom(Geography g, 
GeometryFactory gf) {
     }
     return gf.createGeometryCollection(gs);
   }
+
+  public static Geography geomToGeography(Geometry geom) throws IOException {
+    if (geom == null) {
+      return null;
+    }
+    String type = geom.getGeometryType();
+    if ("Point".equalsIgnoreCase(type)) {
+      return pointToGeog(geom);
+    } else if ("MultiPoint".equalsIgnoreCase(type)) {
+      return mPointToGeog(geom);
+    } else if ("LineString".equalsIgnoreCase(type)) {
+      return lineToGeog(geom);
+    } else if ("MultiLineString".equalsIgnoreCase(type)) {
+      return mLineToGeog(geom);
+    } else if ("Polygon".equalsIgnoreCase(type)) {
+      return polyToGeog(geom);
+    } else if ("MultiPolygon".equalsIgnoreCase(type)) {
+      return mPolyToGeog(geom);
+    } else if ("GeometryCollection".equalsIgnoreCase(type)) {
+      return geomCollToGeog(geom);
+    } else {

Review Comment:
   I prefer directly using `instanceof` to check the geometry type. Reference: 
https://github.com/apache/sedona/blob/658bf60548be0fa3c60ea8b0a9637dabab4b30bc/common/src/main/java/org/apache/sedona/common/geometrySerde/GeometrySerializer.java#L42-L59
   
   The order of the checks is important. We need to check for 
GeometryCollection last because Multi geometries are subclasses of 
GeometryCollection.



##########
common/src/main/java/org/apache/sedona/common/geography/Constructors.java:
##########
@@ -264,4 +264,271 @@ private static Geometry collectionToGeom(Geography g, 
GeometryFactory gf) {
     }
     return gf.createGeometryCollection(gs);
   }
+
+  public static Geography geomToGeography(Geometry geom) throws IOException {
+    if (geom == null) {
+      return null;
+    }
+    String type = geom.getGeometryType();
+    if ("Point".equalsIgnoreCase(type)) {
+      return pointToGeog(geom);
+    } else if ("MultiPoint".equalsIgnoreCase(type)) {
+      return mPointToGeog(geom);
+    } else if ("LineString".equalsIgnoreCase(type)) {
+      return lineToGeog(geom);
+    } else if ("MultiLineString".equalsIgnoreCase(type)) {
+      return mLineToGeog(geom);
+    } else if ("Polygon".equalsIgnoreCase(type)) {
+      return polyToGeog(geom);
+    } else if ("MultiPolygon".equalsIgnoreCase(type)) {
+      return mPolyToGeog(geom);
+    } else if ("GeometryCollection".equalsIgnoreCase(type)) {
+      return geomCollToGeog(geom);
+    } else {
+      throw new UnsupportedOperationException("Unsupported geometry type: " + 
type);
+    }
+  }
+
+  private static Geography pointToGeog(Geometry geom) throws IOException {
+    Coordinate[] pts = geom.getCoordinates();
+    if (pts.length == 0 || Double.isNaN(pts[0].x) || Double.isNaN(pts[0].y)) {
+      return new SinglePointGeography();
+    }
+    double lon = pts[0].x;
+    double lat = pts[0].y;
+
+    S2Point s2Point = S2LatLng.fromDegrees(lat, lon).toPoint();
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PointVectorLayer layer = new S2PointVectorLayer();
+    builder.startLayer(layer);
+    builder.addPoint(s2Point);
+
+    S2Error error = new S2Error();
+    if (!builder.build(error)) {
+      throw new IOException("Failed to build S2 point layer: " + error.text());
+    }
+    List<S2Point> points = layer.getPointVector();
+    if (points.isEmpty()) {
+      return new SinglePointGeography();
+    }
+    return new SinglePointGeography(points.get(0));
+  }
+
+  private static Geography mPointToGeog(Geometry geom) throws IOException {
+    Coordinate[] pts = geom.getCoordinates();
+    if (pts.length == 0 || Double.isNaN(pts[0].x) || Double.isNaN(pts[0].y)) {
+      return new PointGeography();
+    }
+    List<S2Point> points = new ArrayList<>(pts.length);
+    // Build via S2Builder + S2PointVectorLayer
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PointVectorLayer layer = new S2PointVectorLayer();
+    // must call build() before reading out the points
+    S2Error error = new S2Error();
+    for (int i = 0; i < pts.length; i++) {
+      double lon = pts[i].x;
+      double lat = pts[i].y;
+      S2Point s2Point = S2LatLng.fromDegrees(lat, lon).toPoint();
+
+      builder.startLayer(layer);
+      builder.addPoint(s2Point);
+
+      if (!builder.build(error)) {
+        throw new IOException("Failed to build S2 point layer: " + 
error.text());
+      }
+    }
+    for (int i = 0; i < layer.getPointVector().size(); i++) {
+      // Extract the resulting points
+      points.add(layer.getPointVector().get(i));
+    }
+    return new PointGeography(points);
+  }
+
+  private static Geography lineToGeog(Geometry geom) throws IOException {
+    LineString ls = (LineString) geom;
+
+    // Build S2 points
+    List<S2Point> pts = toS2Points(ls.getCoordinates());
+    if (pts.size() < 2) {
+      // empty or degenerate → empty single polyline
+      SinglePolylineGeography empty = new SinglePolylineGeography();
+      empty.setSRID(geom.getSRID());

Review Comment:
   SRID is only handled in this place but not other places. We can set SRID in 
`geomToGeography` instead of setting it everywhere.



##########
common/src/main/java/org/apache/sedona/common/geography/Constructors.java:
##########
@@ -264,4 +264,271 @@ private static Geometry collectionToGeom(Geography g, 
GeometryFactory gf) {
     }
     return gf.createGeometryCollection(gs);
   }
+
+  public static Geography geomToGeography(Geometry geom) throws IOException {
+    if (geom == null) {
+      return null;
+    }
+    String type = geom.getGeometryType();
+    if ("Point".equalsIgnoreCase(type)) {
+      return pointToGeog(geom);
+    } else if ("MultiPoint".equalsIgnoreCase(type)) {
+      return mPointToGeog(geom);
+    } else if ("LineString".equalsIgnoreCase(type)) {
+      return lineToGeog(geom);
+    } else if ("MultiLineString".equalsIgnoreCase(type)) {
+      return mLineToGeog(geom);
+    } else if ("Polygon".equalsIgnoreCase(type)) {
+      return polyToGeog(geom);
+    } else if ("MultiPolygon".equalsIgnoreCase(type)) {
+      return mPolyToGeog(geom);
+    } else if ("GeometryCollection".equalsIgnoreCase(type)) {
+      return geomCollToGeog(geom);
+    } else {
+      throw new UnsupportedOperationException("Unsupported geometry type: " + 
type);
+    }
+  }
+
+  private static Geography pointToGeog(Geometry geom) throws IOException {
+    Coordinate[] pts = geom.getCoordinates();
+    if (pts.length == 0 || Double.isNaN(pts[0].x) || Double.isNaN(pts[0].y)) {
+      return new SinglePointGeography();
+    }
+    double lon = pts[0].x;
+    double lat = pts[0].y;
+
+    S2Point s2Point = S2LatLng.fromDegrees(lat, lon).toPoint();
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PointVectorLayer layer = new S2PointVectorLayer();
+    builder.startLayer(layer);
+    builder.addPoint(s2Point);
+
+    S2Error error = new S2Error();
+    if (!builder.build(error)) {
+      throw new IOException("Failed to build S2 point layer: " + error.text());
+    }
+    List<S2Point> points = layer.getPointVector();
+    if (points.isEmpty()) {
+      return new SinglePointGeography();
+    }
+    return new SinglePointGeography(points.get(0));
+  }
+
+  private static Geography mPointToGeog(Geometry geom) throws IOException {
+    Coordinate[] pts = geom.getCoordinates();
+    if (pts.length == 0 || Double.isNaN(pts[0].x) || Double.isNaN(pts[0].y)) {
+      return new PointGeography();
+    }
+    List<S2Point> points = new ArrayList<>(pts.length);
+    // Build via S2Builder + S2PointVectorLayer
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PointVectorLayer layer = new S2PointVectorLayer();
+    // must call build() before reading out the points
+    S2Error error = new S2Error();
+    for (int i = 0; i < pts.length; i++) {
+      double lon = pts[i].x;
+      double lat = pts[i].y;
+      S2Point s2Point = S2LatLng.fromDegrees(lat, lon).toPoint();
+
+      builder.startLayer(layer);

Review Comment:
   Adding the same layer repeatedly does not look correct.



##########
common/src/main/java/org/apache/sedona/common/geography/Constructors.java:
##########
@@ -264,4 +264,271 @@ private static Geometry collectionToGeom(Geography g, 
GeometryFactory gf) {
     }
     return gf.createGeometryCollection(gs);
   }
+
+  public static Geography geomToGeography(Geometry geom) throws IOException {
+    if (geom == null) {
+      return null;
+    }
+    String type = geom.getGeometryType();
+    if ("Point".equalsIgnoreCase(type)) {
+      return pointToGeog(geom);
+    } else if ("MultiPoint".equalsIgnoreCase(type)) {
+      return mPointToGeog(geom);
+    } else if ("LineString".equalsIgnoreCase(type)) {
+      return lineToGeog(geom);
+    } else if ("MultiLineString".equalsIgnoreCase(type)) {
+      return mLineToGeog(geom);
+    } else if ("Polygon".equalsIgnoreCase(type)) {
+      return polyToGeog(geom);
+    } else if ("MultiPolygon".equalsIgnoreCase(type)) {
+      return mPolyToGeog(geom);
+    } else if ("GeometryCollection".equalsIgnoreCase(type)) {
+      return geomCollToGeog(geom);
+    } else {
+      throw new UnsupportedOperationException("Unsupported geometry type: " + 
type);
+    }
+  }
+
+  private static Geography pointToGeog(Geometry geom) throws IOException {
+    Coordinate[] pts = geom.getCoordinates();
+    if (pts.length == 0 || Double.isNaN(pts[0].x) || Double.isNaN(pts[0].y)) {
+      return new SinglePointGeography();
+    }
+    double lon = pts[0].x;
+    double lat = pts[0].y;
+
+    S2Point s2Point = S2LatLng.fromDegrees(lat, lon).toPoint();
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PointVectorLayer layer = new S2PointVectorLayer();
+    builder.startLayer(layer);
+    builder.addPoint(s2Point);
+
+    S2Error error = new S2Error();
+    if (!builder.build(error)) {
+      throw new IOException("Failed to build S2 point layer: " + error.text());
+    }
+    List<S2Point> points = layer.getPointVector();
+    if (points.isEmpty()) {
+      return new SinglePointGeography();
+    }
+    return new SinglePointGeography(points.get(0));
+  }
+
+  private static Geography mPointToGeog(Geometry geom) throws IOException {
+    Coordinate[] pts = geom.getCoordinates();
+    if (pts.length == 0 || Double.isNaN(pts[0].x) || Double.isNaN(pts[0].y)) {
+      return new PointGeography();
+    }
+    List<S2Point> points = new ArrayList<>(pts.length);
+    // Build via S2Builder + S2PointVectorLayer
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PointVectorLayer layer = new S2PointVectorLayer();
+    // must call build() before reading out the points
+    S2Error error = new S2Error();
+    for (int i = 0; i < pts.length; i++) {
+      double lon = pts[i].x;
+      double lat = pts[i].y;
+      S2Point s2Point = S2LatLng.fromDegrees(lat, lon).toPoint();
+
+      builder.startLayer(layer);
+      builder.addPoint(s2Point);
+
+      if (!builder.build(error)) {
+        throw new IOException("Failed to build S2 point layer: " + 
error.text());
+      }
+    }
+    for (int i = 0; i < layer.getPointVector().size(); i++) {
+      // Extract the resulting points
+      points.add(layer.getPointVector().get(i));
+    }
+    return new PointGeography(points);
+  }
+
+  private static Geography lineToGeog(Geometry geom) throws IOException {
+    LineString ls = (LineString) geom;
+
+    // Build S2 points
+    List<S2Point> pts = toS2Points(ls.getCoordinates());
+    if (pts.size() < 2) {
+      // empty or degenerate → empty single polyline
+      SinglePolylineGeography empty = new SinglePolylineGeography();
+      empty.setSRID(geom.getSRID());
+      return empty;
+    }
+
+    S2Builder builder = new S2Builder.Builder().build();
+    S2PolylineLayer layer = new S2PolylineLayer();
+    builder.startLayer(layer);
+
+    builder.addPolyline(new S2Polyline(pts));
+
+    S2Error error = new S2Error();
+    if (!builder.build(error)) {
+      throw new IOException("Failed to build S2 polyline: " + error.text());
+    }
+    S2Polyline s2poly = layer.getPolyline();
+    return new SinglePolylineGeography(s2poly);
+  }
+
+  private static Geography mLineToGeog(Geometry geom) throws IOException {
+    MultiLineString mls = (MultiLineString) geom;
+    List<S2Polyline> features = new ArrayList<>();
+    for (int i = 0; i < mls.getNumGeometries(); i++) {
+      LineString ls = (LineString) mls.getGeometryN(i);
+      List<S2Point> pts = toS2Points(ls.getCoordinates());
+      if (pts.size() >= 2) {
+        S2Builder builder = new S2Builder.Builder().build();
+        S2PolylineLayer layer = new S2PolylineLayer();
+        builder.startLayer(layer);
+        builder.addPolyline(new S2Polyline(pts));
+        S2Error error = new S2Error();
+        if (!builder.build(error)) {
+          throw new IOException("Failed to build S2 polyline: " + 
error.text());
+        }
+        features.add(layer.getPolyline());
+      }
+      // Empty/degenerate parts are skipped
+    }
+    return new PolylineGeography(features);
+  }
+
+  private static Geography polyToGeog(Geometry geom) throws IOException {
+    // Build S2 loops: exterior + holes
+    Polygon poly = (Polygon) geom;
+    // Construct S2 polygon (parity handles holes automatically)
+    S2Polygon s2poly = toS2Polygon(poly);
+    PolygonGeography g = new PolygonGeography(s2poly);
+    g.setSRID(geom.getSRID());
+    return g;
+  }
+
+  private static Geography mPolyToGeog(Geometry geom) throws IOException {
+    final List<S2Polygon> polys = new ArrayList<>();
+
+    MultiPolygon mp = (MultiPolygon) geom;
+    for (int i = 0; i < mp.getNumGeometries(); i++) {
+      Polygon p = (Polygon) mp.getGeometryN(i);
+      S2Polygon s2 = toS2Polygon(p);
+      if (s2 != null && !s2.isEmpty()) polys.add(s2);
+    }
+
+    MultiPolygonGeography out =
+        new MultiPolygonGeography(
+            Geography.GeographyKind.MULTIPOLYGON, 
Collections.unmodifiableList(polys));
+    out.setSRID(geom.getSRID());
+    return out;
+  }
+
+  private static Geography geomCollToGeog(Geometry geom) throws IOException {
+    if (!(geom instanceof GeometryCollection)) {
+      throw new IllegalArgumentException(
+          "geomCollToGeog expects GeometryCollection, got " + 
geom.getGeometryType());
+    }
+    GeographyCollection coll = new GeographyCollection();
+
+    GeometryCollection gc = (GeometryCollection) geom;
+    for (int i = 0; i < gc.getNumGeometries(); i++) {
+      Geometry g = gc.getGeometryN(i);
+      Geography sub = null;
+
+      if (g instanceof Point) {
+        sub = pointToGeog((Point) g);
+      } else if (g instanceof MultiPoint) {
+        MultiPoint mp = (MultiPoint) g;
+        for (int k = 0; k < mp.getNumGeometries(); k++) {
+          coll.features.add(pointToGeog((Point) mp.getGeometryN(k)));
+        }

Review Comment:
   This flattens multi point as separate geography objects instead of a single 
PointGeography. This does not look right.



##########
common/src/main/java/org/apache/sedona/common/geography/Constructors.java:
##########
@@ -264,4 +264,271 @@ private static Geometry collectionToGeom(Geography g, 
GeometryFactory gf) {
     }
     return gf.createGeometryCollection(gs);
   }
+
+  public static Geography geomToGeography(Geometry geom) throws IOException {

Review Comment:
   We are not doing IO here so IOException is not a proper exception type.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to