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){