This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 6b00476a2d48fa4123a971f5f02712c9b4d25260 Author: jsorel <[email protected]> AuthorDate: Mon Sep 14 16:02:18 2026 +0200 feat(Geometry): implement several small methods --- .../main/org/apache/sis/geometries/Curve.java | 56 +++++++++++++++++----- .../main/org/apache/sis/geometries/Geometry.java | 33 ++++++++++--- .../main/org/apache/sis/geometries/Point.java | 23 +++++++++ .../main/org/apache/sis/geometries/Primitive.java | 18 +++++++ 4 files changed, 112 insertions(+), 18 deletions(-) diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java index c120566a77..82df3a4fb9 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java @@ -33,6 +33,8 @@ import org.apache.sis.geometries.curve.Spiral; import org.apache.sis.geometries.internal.shared.DefaultReversedCurve; import org.apache.sis.maths.Array; import org.apache.sis.maths.Vector; +import org.apache.sis.measure.Quantities; +import org.apache.sis.measure.Units; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; import org.opengis.geometry.DirectPosition; @@ -201,6 +203,24 @@ public sealed interface Curve extends Orientable return isCycle() && isSimple(); } + /** + * Returns the two end points of this curve, or the empty geometry when this curve is + * {@linkplain #isClosed() closed} and therefore has no end. + * + * @return boundary of this curve. + * + * @see OGC Simple Feature Access 1.2.1 - 6.1.6.2 + * @see ISO 19107:2019 - 6.4.4.7 + */ + @UML(identifier="boundary", specification=ISO_19107) + @Override + default Geometry boundary() { + if (isEmpty() || isClosed()) { + return GeometryFactory.createEmpty(getCoordinateReferenceSystem()); + } + return GeometryFactory.createMultiPoint(getStartPoint(), getEndPoint()); + } + /** * Positions used to build the geometry of this curve, the way they are used depending on the interpolation. * @@ -314,8 +334,12 @@ public sealed interface Curve extends Orientable */ @UML(identifier="startParam", specification=ISO_19107) default Length getStartParam() { - //TODO - throw new UnsupportedOperationException(); + /* + * Zero, since the arc length parameterization of a curve spans [0 … length] as stated by + * `getLength()`. A curve which is a segment of another one, and which therefore starts + * where the preceding segment ended, has to override. + */ + return Quantities.create(0, Units.METRE); } /** @@ -334,8 +358,14 @@ public sealed interface Curve extends Orientable */ @UML(identifier="endParam", specification=ISO_19107) default Length getEndParam() { - //TODO - throw new UnsupportedOperationException(); + /* + * The constraint above: the difference with the start parameter is the length of the + * curve. This holds whatever the start parameter, so a segment which overrides + * `getStartParam()` gets the right answer without overriding this method. + */ + final Length start = getStartParam(); + final Length length = getLength(); + return Quantities.castOrCopy(start.add(length)); } /** @@ -349,8 +379,7 @@ public sealed interface Curve extends Orientable */ @UML(identifier="numDerivativesInterior", specification=ISO_19107) default Integer getNumDerivativesInterior() { - //TODO - throw new UnsupportedOperationException(); + return 0; // C⁰, which a curve always is since it is connected. } /** @@ -364,8 +393,7 @@ public sealed interface Curve extends Orientable */ @UML(identifier="numDerivativesStart", specification=ISO_19107) default Integer getNumDerivativesStart() { - //TODO - throw new UnsupportedOperationException(); + return 0; // C⁰, the weakest continuity, which is what a junction guarantees. } /** @@ -379,8 +407,7 @@ public sealed interface Curve extends Orientable */ @UML(identifier="numDerivativesEnd", specification=ISO_19107) default Integer getNumDerivativesEnd() { - //TODO - throw new UnsupportedOperationException(); + return 0; // C⁰, the weakest continuity, which is what a junction guarantees. } /** @@ -395,8 +422,13 @@ public sealed interface Curve extends Orientable @UML(identifier="reverse", specification=ISO_19107) @Override default Curve getReverse() { - //TODO - throw new UnsupportedOperationException(); + /* + * A view of this curve carrying the opposite orientation sign. It is a view and not a copy + * because reversing changes no coordinate: which end is the start one is an orientation, + * not a geometry. `DefaultReversedCurve` returns this curve back from its own `getReverse()`, + * so wrapping never nests. + */ + return GeometryFactory.createReversed(this); } /** diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java index bbcf9ae742..70e5938beb 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java @@ -125,13 +125,17 @@ public sealed interface Geometry * <p>Difference with ISO 19107: we return a single Metadata instead of a list of URI, * whose first element would point to the normative document describing this geometry.</p> * - * @return metadata about this geometry. + * @return metadata about this geometry, or {@code null} if none. * * @see ISO 19107:2019 - 6.4.4.18 */ @UML(identifier="metadata", specification=ISO_19107) default Metadata getMetadata() { - throw new UnsupportedOperationException(); + /* + * Absent, which the standard defines as meaning that ISO 19107 itself is the applicable + * documentation. Implementations departing from the standard should say so here. + */ + return null; } /** @@ -176,6 +180,15 @@ public sealed interface Geometry */ @UML(identifier="dimension", specification=ISO_19107) default int getDimension(DirectPosition point) { + if (point == null) { + /* + * The dimension of the whole geometry, which is what `getTopologicDimension()` returns. + * A position is needed only because an aggregate may mix components of different + * dimensions; every homogeneous geometry answers the same at every interior position, + * which is what `Primitive` relies on. + */ + return getTopologicDimension(); + } throw new UnsupportedOperationException(); } @@ -354,8 +367,12 @@ public sealed interface Geometry */ @UML(identifier="closure", specification=ISO_19107) default Geometry getClosure() { - //TODO remove this method default when all classes implement it. - throw new UnsupportedOperationException(); + /* + * Every geometry of this package is metrically closed, as stated in the constraints of + * this interface: a curve contains its end points, a surface its boundary curves and a + * solid its boundary surfaces. A geometry is therefore its own closure. + */ + return this; } /** @@ -375,8 +392,12 @@ public sealed interface Geometry */ @UML(identifier="maximalComplex", specification=ISO_19107) default Geometry getMaximalComplex() { - //TODO remove this method default when all classes implement it. - throw new UnsupportedOperationException(); + /* + * This package has no notion of complex: it declares no type for a set of geometries + * closed under the boundary operation, which is what ISO 19107 calls a complex. + * The standard defines null as the answer in that case. + */ + return null; } /** diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Point.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Point.java index 444fb9c3af..57f9f103f5 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Point.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Point.java @@ -202,6 +202,29 @@ public sealed interface Point extends Primitive return true; } + /** + * Returns {@code true}: a single location satisfies every constraint a point can have. + * + * @see ISO 19107:2019 - 6.4.4.16 + */ + @UML(identifier="isValid", specification=ISO_19107) + @Override + default boolean isValid() { + return true; + } + + /** + * Returns the empty geometry: the boundary of a point is the empty set. + * + * @see OGC Simple Feature Access 1.2.1 - 6.1.2.2 + * @see ISO 19107:2019 - 6.4.4.7 + */ + @UML(identifier="boundary", specification=ISO_19107) + @Override + default Geometry boundary() { + return GeometryFactory.createEmpty(getCoordinateReferenceSystem()); + } + /** * Returns {@code this}: a point is its own centroid. * diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Primitive.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Primitive.java index 750cbde8d5..b4bac83149 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Primitive.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Primitive.java @@ -19,6 +19,7 @@ package org.apache.sis.geometries; import java.util.List; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; +import org.opengis.geometry.DirectPosition; /** @@ -65,6 +66,23 @@ public sealed interface Primitive extends Geometry return BoundaryType.METRIC; } + /** + * Returns the {@linkplain #getTopologicDimension() topological dimension} of this primitive, + * whatever the given position: a primitive has a uniform dimension at each of its interior + * points, which is what makes it a primitive. Only an aggregate needs the position, because + * it may mix components of different dimensions. + * + * @param point ignored, since the answer is the same everywhere. + * @return topological dimension of this primitive. + * + * @see ISO 19107:2019 - 6.4.4.25 + */ + @UML(identifier="dimension", specification=ISO_19107) + @Override + default int getDimension(DirectPosition point) { + return getTopologicDimension(); + } + /** * Smaller primitives of the same dimension contained in this primitive, * each of them defining a portion of it.
