This is an automated email from the ASF dual-hosted git repository.

jsorel pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 95b256597d Add CurvePolygon geometry type interface
95b256597d is described below

commit 95b256597dcf5217eba9b80ce0d7910245e4a79c
Author: jsorel <[email protected]>
AuthorDate: Fri Jul 25 09:16:22 2025 +0200

    Add CurvePolygon geometry type interface
---
 .../geometries/{Polygon.java => CurvePolygon.java} | 25 +++++++---------------
 .../org/apache/sis/geometries/GeometryFactory.java |  2 +-
 .../org/apache/sis/geometries/MultiPolygon.java    |  2 +-
 .../main/org/apache/sis/geometries/Polygon.java    |  9 ++++----
 .../main/org/apache/sis/geometries/Triangle.java   |  2 +-
 .../sis/geometries/privy/DefaultPolygon.java       |  8 +++----
 .../processor/spatialedition/Transform.java        |  8 +++----
 .../processor/spatialrelations2d/Contains.java     | 11 ++--------
 .../sis/geometries/triangulate/EarClipping.java    | 14 ++++++------
 9 files changed, 32 insertions(+), 49 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Polygon.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/CurvePolygon.java
similarity index 72%
copy from 
incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Polygon.java
copy to 
incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/CurvePolygon.java
index fa1f1cf2aa..a026e5e542 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Polygon.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/CurvePolygon.java
@@ -24,30 +24,21 @@ import org.apache.sis.geometries.privy.AbstractGeometry;
 
 
 /**
- * A Polygon is a planar Surface defined by 1 exterior boundary and 0 or more 
interior boundaries.
- * Each interior boundary defines a hole in the Polygon. A Triangle is a 
polygon with 3 distinct, non-collinear
- * vertices and no interior boundary.
+ * A curve polygon is a surface where each ring is a closed line string, 
circular string, or compound curve.
+ * The first ring is the exterior boundary and, all other rings are interior 
boundaries.
  *
- * The exterior boundary LinearRing defines the “top” of the surface which is 
the side of the surface from which
- * the exterior boundary appears to traverse the boundary in a counter 
clockwise direction.
- * The interior LinearRings will have the opposite orientation, and appear as 
clockwise when viewed from the “top”,
- *
- * The assertions for Polygons (the rules that define valid Polygons) are as 
follows:
- *
- * a) Polygons are topologically closed;
- * b) The boundary of a Polygon consists of a set of LinearRings that make up 
its exterior and interior boundaries;
- * c) No two Rings in the boundary cross and the Rings in the boundary of a 
Polygon may intersect at a Point but only as a tangent.
- * d) A Polygon may not have cut lines, spikes or punctures
- * e) The interior of every Polygon is a connected point set;
- * f) The exterior of a Polygon with 1 or more holes is not connected. Each 
hole defines a connected component of the exterior.
+ * @todo is Polygon a subclass of CurvePolygon ?
+ * ISO-19107 use the name Polygon for CurvePolygon
+ * OGC Features and Geometries JSON separates them
+ * In practice most geometry library have only polygon with straight lines
  *
  * @author Johann Sorel (Geomatys)
  * @see https://docs.ogc.org/DRAFTS/21-045r1.html#curve_polygon
  */
 @UML(identifier="Polygon", specification=ISO_19107) // section 8.1.2
-public interface Polygon extends Surface {
+public interface CurvePolygon extends Surface {
 
-    public static final String TYPE = "POLYGON";
+    public static final String TYPE = "CURVEPOLYGON";
 
     @Override
     public default String getGeometryType() {
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
index 4585ced299..628413d177 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
@@ -130,6 +130,7 @@ public final class GeometryFactory extends 
org.apache.sis.geometry.wrapper.Geome
             case CLOTHOID : return Clothoid.class;
             case COMPOUNDCURVE : return CompoundCurve.class;
             case CURVE : return Curve.class;
+            case CURVEPOLYGON : return CurvePolygon.class;
             case GEOMETRY : return Geometry.class;
             case GEOMETRYCOLLECTION : return GeometryCollection.class;
             case LINESTRING : return LineString.class;
@@ -147,7 +148,6 @@ public final class GeometryFactory extends 
org.apache.sis.geometry.wrapper.Geome
             //todo
             case BREPSOLID :
             case COMPOUNDSURFACE :
-            case CURVEPOLYGON :
             case ELLIPTICALCURVE :
             case GEODESICSTRING :
             case NURBSCURVE :
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/MultiPolygon.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/MultiPolygon.java
index 8c39f0959e..dfadb5ebec 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/MultiPolygon.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/MultiPolygon.java
@@ -55,7 +55,7 @@ public interface MultiPolygon extends MultiSurface<Polygon> {
             for (int i = 0, n = polygon.getNumInteriorRing(); i < n; i++) {
                 if (i != 0) sb.append(',');
                 sb.append('(');
-                AbstractGeometry.toText(sb, 
polygon.getInteriorRingN(i).asLine(null, null).getPoints());
+                AbstractGeometry.toText(sb, 
polygon.getInteriorRingN(i).getPoints());
                 sb.append(')');
             }
             sb.append(')');
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Polygon.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Polygon.java
index fa1f1cf2aa..7ae783294d 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Polygon.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Polygon.java
@@ -42,7 +42,6 @@ import org.apache.sis.geometries.privy.AbstractGeometry;
  * f) The exterior of a Polygon with 1 or more holes is not connected. Each 
hole defines a connected component of the exterior.
  *
  * @author Johann Sorel (Geomatys)
- * @see https://docs.ogc.org/DRAFTS/21-045r1.html#curve_polygon
  */
 @UML(identifier="Polygon", specification=ISO_19107) // section 8.1.2
 public interface Polygon extends Surface {
@@ -60,7 +59,7 @@ public interface Polygon extends Surface {
     }
 
     @UML(identifier="rings", specification=ISO_19107) // section 8.1 figure 28
-    List<Curve> getInteriorRings();
+    List<LinearRing> getInteriorRings();
 
     /**
      * Returns the exterior ring of this Polygon.
@@ -69,7 +68,7 @@ public interface Polygon extends Surface {
      * @return exterior ring of this Polygon.
      */
     @UML(identifier="exteriorRing", specification=ISO_19107) // section 8.1 
figure 28
-    Curve getExteriorRing();
+    LinearRing getExteriorRing();
 
     /**
      * Returns the number of interior rings in this Polygon.
@@ -90,7 +89,7 @@ public interface Polygon extends Surface {
      * @return interior ring for this Polygon.
      */
     @UML(identifier="interiorRingN", specification=ISO_19107) // section 8.1 
figure 28
-    default Curve getInteriorRingN(int n) {
+    default LinearRing getInteriorRingN(int n) {
         return getInteriorRings().get(n);
     }
 
@@ -108,7 +107,7 @@ public interface Polygon extends Surface {
         for (int i = 0, n = getNumInteriorRing(); i < n; i++) {
             if (i != 0) sb.append(',');
             sb.append('(');
-            AbstractGeometry.toText(sb, getInteriorRingN(i).asLine(null, 
null).getPoints());
+            AbstractGeometry.toText(sb, getInteriorRingN(i).getPoints());
             sb.append(')');
         }
         sb.append(')');
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Triangle.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Triangle.java
index fabf57e021..a5345f6f62 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Triangle.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Triangle.java
@@ -56,7 +56,7 @@ public interface Triangle extends Polygon {
     LinearRing getExteriorRing();
 
     @Override
-    default List<Curve> getInteriorRings() {
+    default List<LinearRing> getInteriorRings() {
         return Collections.emptyList();
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/privy/DefaultPolygon.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/privy/DefaultPolygon.java
index 0d875e2594..b16e83e6ee 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/privy/DefaultPolygon.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/privy/DefaultPolygon.java
@@ -34,8 +34,8 @@ import org.apache.sis.util.privy.UnmodifiableArrayList;
  */
 public class DefaultPolygon extends AbstractGeometry implements Polygon {
 
-    protected final Curve exterior;
-    protected final List<Curve> interiors;
+    protected final LinearRing exterior;
+    protected final List<LinearRing> interiors;
 
     public DefaultPolygon(LinearRing exterior) {
         this(exterior, null);
@@ -72,12 +72,12 @@ public class DefaultPolygon extends AbstractGeometry 
implements Polygon {
     }
 
     @Override
-    public Curve getExteriorRing() {
+    public LinearRing getExteriorRing() {
         return exterior;
     }
 
     @Override
-    public List<Curve> getInteriorRings() {
+    public List<LinearRing> getInteriorRings() {
         return interiors;
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialedition/Transform.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialedition/Transform.java
index 43bc6e286d..521e92f0c0 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialedition/Transform.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialedition/Transform.java
@@ -119,14 +119,14 @@ public final class Transform {
         public void 
process(org.apache.sis.geometries.operation.spatialedition.Transform operation) 
throws OperationException {
             final org.apache.sis.geometries.Polygon p = 
(org.apache.sis.geometries.Polygon) operation.geometry;
 
-            Curve exterior = (Curve) 
GeometryOperations.SpatialEdition.transform(p.getExteriorRing(), operation.crs, 
operation.transform);
+            org.apache.sis.geometries.LinearRing exterior = 
(org.apache.sis.geometries.LinearRing) 
GeometryOperations.SpatialEdition.transform(p.getExteriorRing(), operation.crs, 
operation.transform);
 
-            final List<Curve> interiors = new 
ArrayList<>(p.getInteriorRings());
+            final List<org.apache.sis.geometries.LinearRing> interiors = new 
ArrayList<>(p.getInteriorRings());
             for (int i = 0, n = interiors.size(); i < n; i++) {
-                interiors.set(i, (Curve) 
GeometryOperations.SpatialEdition.transform(interiors.get(i), operation.crs, 
operation.transform));
+                interiors.set(i, (org.apache.sis.geometries.LinearRing) 
GeometryOperations.SpatialEdition.transform(interiors.get(i), operation.crs, 
operation.transform));
             }
 
-            operation.result = 
GeometryFactory.createPolygon((org.apache.sis.geometries.LinearRing) exterior, 
(List) interiors);
+            operation.result = GeometryFactory.createPolygon(exterior, 
interiors);
         }
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialrelations2d/Contains.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialrelations2d/Contains.java
index e5427ba297..b0cac29631 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialrelations2d/Contains.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialrelations2d/Contains.java
@@ -110,7 +110,7 @@ public final class Contains {
 
 
             { //check exterior
-                final TupleArray coords = 
asLineString(polygon.getExteriorRing()).getPoints().getAttributeArray(AttributesType.ATT_POSITION);
+                final TupleArray coords = 
polygon.getExteriorRing().getPoints().getAttributeArray(AttributesType.ATT_POSITION);
                 if (!contains(coords, candidate.getPosition())) {
                     //point is outside the exterior ring
                     operation.result = false;
@@ -120,7 +120,7 @@ public final class Contains {
 
             { //check holes
                 for (int i = 0, n = polygon.getNumInteriorRing(); i < n; i++) {
-                    final LineString hole = 
asLineString(polygon.getInteriorRingN(i));
+                    final LineString hole = polygon.getInteriorRingN(i);
                     final TupleArray coords = 
hole.getPoints().getAttributeArray(AttributesType.ATT_POSITION);
                     if (contains(coords, candidate.getPosition())) {
                         //point is within a hole
@@ -135,11 +135,4 @@ public final class Contains {
         }
     }
 
-    private static LineString asLineString(Curve curve) {
-        if (curve instanceof LineString ls) {
-            return ls;
-        }
-        throw new OperationException("Curve type not supported");
-    }
-
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/triangulate/EarClipping.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/triangulate/EarClipping.java
index 917063025e..01a6138a77 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/triangulate/EarClipping.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/triangulate/EarClipping.java
@@ -110,12 +110,12 @@ public class EarClipping {
 
         final SimplePolygon part = new SimplePolygon();
         //copy collection to avoid modifications
-        part.outter = (LineString) ((Polygon)geometry).getExteriorRing();
+        part.outter = geometry.getExteriorRing();
 
-        final int nbHole = ((Polygon)geometry).getNumInteriorRing();
+        final int nbHole = geometry.getNumInteriorRing();
 
         for(int i=0;i<nbHole;i++){
-            final LineString inner = (LineString) 
((Polygon)geometry).getInteriorRingN(i);
+            final LineString inner = geometry.getInteriorRingN(i);
             part.inners.add(inner);
         }
 
@@ -157,7 +157,7 @@ public class EarClipping {
             //we must find the minimum x coordinate in the inner loop
             final List<Tuple> loop = 
part.inners.get(i).getPoints().getAttributeArray(AttributesType.ATT_POSITION).stream(false).toList();
             int index = 0;
-            Tuple min = (Tuple) loop.get(index);
+            Tuple min = loop.get(index);
             for(int k=1,p=loop.size();k<p;k++){
                 Tuple candidate = (Tuple) loop.get(1);
                 if (candidate.get(0) < min.get(0)) {
@@ -192,9 +192,9 @@ public class EarClipping {
         }
 
         //remove any neighor points overlaping
-        Tuple t = (Tuple) borderCoords.get(0);
+        Tuple t = borderCoords.get(0);
         for(int i=1,n=borderCoords.size();i<n;i++){
-            Tuple candidate = (Tuple) borderCoords.get(i);
+            Tuple candidate = borderCoords.get(i);
             if(candidate.equals(t)){
                 borderCoords.remove(i);
                 i--;
@@ -210,7 +210,7 @@ public class EarClipping {
 
         nbCoords = borderCoords.size();
         coordType = new int[nbCoords];
-        coords = borderCoords.toArray(new Tuple[0]);
+        coords = borderCoords.toArray(Tuple[]::new);
 
         //flip coordinates if not clockwise
         if(!clockwise){

Reply via email to