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 b6b045f35e76d2fc0047b15f4af389499c03e0a9 Author: jsorel <[email protected]> AuthorDate: Thu Sep 17 12:27:57 2026 +0200 feat(Geometry): add default empty geometry classes implementations and factory methods --- .../org/apache/sis/geometries/GeometryFactory.java | 348 +++++++++++++++++++++ .../main/org/apache/sis/geometries/Prism.java | 4 +- .../main/org/apache/sis/geometries/curve/Arc.java | 14 +- .../apache/sis/geometries/curve/BSplineCurve.java | 14 +- .../org/apache/sis/geometries/curve/Bezier.java | 19 +- .../org/apache/sis/geometries/curve/Circle.java | 14 +- .../org/apache/sis/geometries/curve/Clothoid.java | 14 +- .../org/apache/sis/geometries/curve/Conic.java | 14 +- .../apache/sis/geometries/curve/CubicSpline.java | 14 +- .../apache/sis/geometries/curve/EllipticArc.java | 14 +- .../apache/sis/geometries/curve/OffsetCurve.java | 14 +- .../sis/geometries/curve/PolynomialSpline.java | 14 +- .../apache/sis/geometries/curve/ProductCurve.java | 18 +- .../org/apache/sis/geometries/curve/Spiral.java | 14 +- .../sis/geometries/internal/shared/DefaultArc.java | 70 +++++ .../internal/shared/DefaultBSplineCurve.java | 177 +++++++++++ .../internal/shared/DefaultBSplineSolid.java | 177 +++++++++++ .../internal/shared/DefaultBSplineSurface.java | 195 ++++++++++++ .../geometries/internal/shared/DefaultBezier.java | 58 ++++ .../internal/shared/DefaultBilinearGrid.java | 179 +++++++++++ .../geometries/internal/shared/DefaultCircle.java | 54 ++++ .../internal/shared/DefaultClothoid.java | 55 ++++ .../geometries/internal/shared/DefaultConic.java | 107 +++++++ .../internal/shared/DefaultCubicSpline.java | 67 ++++ .../internal/shared/DefaultEllipticArc.java | 43 +++ .../internal/shared/DefaultOffsetCurve.java | 122 ++++++++ .../internal/shared/DefaultPolynomialSpline.java | 198 ++++++++++++ .../geometries/internal/shared/DefaultPrism.java | 98 ++++++ .../internal/shared/DefaultProductCurve.java | 84 +++++ .../geometries/internal/shared/DefaultSpiral.java | 134 ++++++++ .../solid/{BSolidSpline.java => BSplineSolid.java} | 14 +- .../sis/geometries/solid/ParametricCurveSolid.java | 2 +- .../sis/geometries/surface/BSplineSurface.java | 14 +- .../sis/geometries/surface/BilinearGrid.java | 14 +- 34 files changed, 2374 insertions(+), 17 deletions(-) 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 11b8342531..cf42443272 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 @@ -22,24 +22,51 @@ import java.util.Collections; import java.util.List; import java.util.Map; import javax.measure.Unit; +import javax.measure.quantity.Length; +import org.apache.sis.geometries.cs.Projection; +import org.apache.sis.geometries.curve.Arc; import org.apache.sis.geometries.curve.ArcByBulge; import org.apache.sis.geometries.curve.ArcByCenterPoint; +import org.apache.sis.geometries.curve.BSplineCurve; +import org.apache.sis.geometries.curve.Bezier; import org.apache.sis.geometries.curve.Circle; import org.apache.sis.geometries.curve.CircularString; import org.apache.sis.geometries.curve.Clothoid; import org.apache.sis.geometries.curve.CompoundCurve; +import org.apache.sis.geometries.curve.Conic; +import org.apache.sis.geometries.curve.CubicSpline; +import org.apache.sis.geometries.curve.EllipticArc; import org.apache.sis.geometries.curve.Geodesic; +import org.apache.sis.geometries.curve.KnotType; import org.apache.sis.geometries.curve.LineString; import org.apache.sis.geometries.curve.LinearRing; import org.apache.sis.geometries.curve.MultiCurve; import org.apache.sis.geometries.curve.MultiLineString; +import org.apache.sis.geometries.curve.NurbCurve; +import org.apache.sis.geometries.curve.OffsetCurve; +import org.apache.sis.geometries.curve.PolynomialSpline; +import org.apache.sis.geometries.curve.ProductCurve; +import org.apache.sis.geometries.curve.RealFunction; import org.apache.sis.geometries.curve.Rhumb; +import org.apache.sis.geometries.curve.Spiral; +import org.apache.sis.geometries.curve.SplineCurveForm; import org.apache.sis.geometries.internal.shared.ArrayDataPoints; +import org.apache.sis.geometries.internal.shared.DefaultArc; import org.apache.sis.geometries.internal.shared.DefaultArcByBulge; import org.apache.sis.geometries.internal.shared.DefaultArcByCenterPoint; +import org.apache.sis.geometries.internal.shared.DefaultBSplineSolid; +import org.apache.sis.geometries.internal.shared.DefaultBSplineCurve; +import org.apache.sis.geometries.internal.shared.DefaultBSplineSurface; +import org.apache.sis.geometries.internal.shared.DefaultBezier; +import org.apache.sis.geometries.internal.shared.DefaultBilinearGrid; +import org.apache.sis.geometries.internal.shared.DefaultCircle; import org.apache.sis.geometries.internal.shared.DefaultCircularString; +import org.apache.sis.geometries.internal.shared.DefaultClothoid; import org.apache.sis.geometries.internal.shared.DefaultCompoundCurve; +import org.apache.sis.geometries.internal.shared.DefaultConic; +import org.apache.sis.geometries.internal.shared.DefaultCubicSpline; import org.apache.sis.geometries.internal.shared.DefaultCurvePolygon; +import org.apache.sis.geometries.internal.shared.DefaultEllipticArc; import org.apache.sis.geometries.internal.shared.DefaultEmpty; import org.apache.sis.geometries.internal.shared.DefaultGeodesic; import org.apache.sis.geometries.internal.shared.DefaultGeometryCollection; @@ -51,22 +78,33 @@ import org.apache.sis.geometries.internal.shared.DefaultMultiPoint; import org.apache.sis.geometries.internal.shared.DefaultMultiPolygon; import org.apache.sis.geometries.internal.shared.DefaultMultiPolyhedron; import org.apache.sis.geometries.internal.shared.DefaultMultiSurface; +import org.apache.sis.geometries.internal.shared.DefaultNurbCurve; +import org.apache.sis.geometries.internal.shared.DefaultNurbSurface; +import org.apache.sis.geometries.internal.shared.DefaultOffsetCurve; import org.apache.sis.geometries.internal.shared.DefaultPoint; import org.apache.sis.geometries.internal.shared.DefaultPolygon; import org.apache.sis.geometries.internal.shared.DefaultPolyhedralSurface; import org.apache.sis.geometries.internal.shared.DefaultPolyhedron; +import org.apache.sis.geometries.internal.shared.DefaultPolynomialSpline; +import org.apache.sis.geometries.internal.shared.DefaultPrism; +import org.apache.sis.geometries.internal.shared.DefaultProductCurve; import org.apache.sis.geometries.internal.shared.DefaultRawMultiPoint; import org.apache.sis.geometries.internal.shared.DefaultReversedCurve; import org.apache.sis.geometries.internal.shared.DefaultReversedSurface; import org.apache.sis.geometries.internal.shared.DefaultRhumb; +import org.apache.sis.geometries.internal.shared.DefaultSpiral; import org.apache.sis.geometries.internal.shared.DefaultTriangle; import org.apache.sis.geometries.internal.shared.DefaultTriangulatedSurface; import org.apache.sis.geometries.point.MultiPoint; import org.apache.sis.geometries.solid.MultiPolyhedron; import org.apache.sis.geometries.solid.Polyhedron; +import org.apache.sis.geometries.surface.BSplineSurface; +import org.apache.sis.geometries.surface.BSplineSurfaceForm; +import org.apache.sis.geometries.surface.BilinearGrid; import org.apache.sis.geometries.surface.CurvePolygon; import org.apache.sis.geometries.surface.MultiPolygon; import org.apache.sis.geometries.surface.MultiSurface; +import org.apache.sis.geometries.surface.NurbSurface; import org.apache.sis.geometries.surface.Polygon; import org.apache.sis.geometries.surface.PolyhedralSurface; import org.apache.sis.geometries.surface.TIN; @@ -80,8 +118,13 @@ import org.apache.sis.maths.DataType; import org.apache.sis.maths.NDArrays; import org.apache.sis.maths.SampleSystem; import org.apache.sis.maths.Vector; +import org.apache.sis.measure.NumberRange; +import org.apache.sis.measure.Range; import org.apache.sis.setup.GeometryLibrary; +import org.opengis.geometry.DirectPosition; import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.SingleCRS; +import org.apache.sis.geometries.solid.BSplineSolid; /** @@ -251,6 +294,218 @@ public final class GeometryFactory extends org.apache.sis.geometry.wrapper.Geome return new DefaultArcByBulge(points, bulge, normal); } + /* + * Conics, spirals and splines. These are the curves whose interpolation is neither linear nor + * a simple chain of circular arcs, and which ISO 19107 defines by a mathematical construction + * rather than by a list of positions alone. + */ + + /** + * Creates a chain of conic section arcs, each of them determined by five data points. + * + * @param points points lying on the conic. At least five of them, the first one also + * acting as the last one when {@code cycle} is {@code true}. + * @param controlPoints centres of the exponential maps in which the arcs are constructed, + * one per arc, or {@code null} if none. + * @param cycle whether the conic closes on itself. + */ + public static Conic createConic(DataPoints points, Array controlPoints, boolean cycle) { + return new DefaultConic(points, controlPoints, cycle); + } + + /** + * Creates a chain of circular arcs, each of them centred on a control point and joining two + * consecutive data points. + * + * @param points start and end points of the arcs, two consecutive arcs sharing a point. + * There is one more point than there are arcs. + * @param controlPoints centres of the circles carrying the arcs, one per arc. + * @param radius radius vectors giving the plane and the rotation direction of each arc, + * possibly empty. + * @param cycle whether the chain closes on itself. + */ + public static Arc createArc(DataPoints points, Array controlPoints, List<Vector> radius, boolean cycle) { + return new DefaultArc(points, controlPoints, radius, cycle); + } + + /** + * Creates a complete circle, i.e. a chain of circular arcs sharing a single centre and closing + * on itself. + * + * @param points points of the circle, all at the same distance from the centre, + * the first and the last ones being equal. + * @param controlPoints the centre of the circle, repeated once per arc. Because a single arc + * must stay below a full turn, at least two of them are needed. + * @param radius radius vectors of the arcs, possibly empty. + */ + public static Circle createCircle(DataPoints points, Array controlPoints, List<Vector> radius) { + return new DefaultCircle(points, controlPoints, radius); + } + + /** + * Creates a conic without a cross term, therefore an arc of ellipse, each arc being determined + * by four data points instead of five. + * + * @param points points lying on the ellipse. + * @param controlPoints centres of the ellipses of the arcs, or {@code null} if none. + * @param cycle whether the arc closes on itself, making it a complete ellipse. + */ + public static EllipticArc createEllipticArc(DataPoints points, Array controlPoints, boolean cycle) { + return new DefaultEllipticArc(points, controlPoints, cycle); + } + + /** + * Creates a curve defined indirectly by its curvature, and by its torsion when it is not planar. + * + * @param points points of the spiral, the first one being its start point. + * @param curvature curvature as a function of arc length. + * @param torsion torsion as a function of arc length, or {@code null} if the spiral is planar. + * @param startFrame two or three mutually orthogonal unit vectors forming a right-handed frame + * at the start point. + */ + public static Spiral createSpiral(DataPoints points, RealFunction curvature, + RealFunction torsion, List<Vector> startFrame) + { + return new DefaultSpiral(points, curvature, torsion, startFrame); + } + + /** + * Creates a spiral whose curvature varies linearly with arc length, also called a Cornu spiral. + * + * @param points points of the clothoid, the first one being its start point. + * @param curvature curvature as a function of arc length. It shall be linear in the arc + * length measured from the point where the infinite clothoid has zero + * curvature. + * @param startFrame two mutually orthogonal unit vectors forming a right-handed frame at the + * start point, a clothoid being planar. + */ + public static Clothoid createClothoid(DataPoints points, RealFunction curvature, List<Vector> startFrame) { + return new DefaultClothoid(points, curvature, startFrame); + } + + /** + * Creates a spline which interpolates its data points, i.e. a polynomial curve passing through them. + * + * @param points points the spline passes through, in order. + * @param controlPoints control points of the spline, or {@code null} if none. + * @param knots knot values, strictly increasing, one per data point. + * @param degree degree of the interpolating polynomials. + * @param curveForm kind of curve approximated by the spline, or {@code null} if none. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param derivativeAtStart derivative imposed at the start point, or {@code null} if none. + * @param derivativeAtEnd derivative imposed at the end point, or {@code null} if none. + * @param derivativeInterior number of continuous derivatives at the interior knots, + * at most {@code degree} − 1. + */ + public static PolynomialSpline createPolynomialSpline(DataPoints points, Array controlPoints, + double[] knots, int degree, SplineCurveForm curveForm, KnotType knotSpec, + Vector derivativeAtStart, Vector derivativeAtEnd, int derivativeInterior) + { + return new DefaultPolynomialSpline(points, controlPoints, knots, degree, curveForm, + knotSpec, derivativeAtStart, derivativeAtEnd, derivativeInterior); + } + + /** + * Creates a polynomial spline of degree 3, C² everywhere and passing through its data points. + * + * @param points points the spline passes through, in order. + * @param controlPoints control points of the spline, or {@code null} if none. + * @param knots knot values, strictly increasing, one per data point. + * @param curveForm kind of curve approximated by the spline, or {@code null} if none. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param derivativeAtStart tangent imposed at the start point, or {@code null} if none. + * @param derivativeAtEnd tangent imposed at the end point, or {@code null} if none. + */ + public static CubicSpline createCubicSpline(DataPoints points, Array controlPoints, double[] knots, + SplineCurveForm curveForm, KnotType knotSpec, Vector derivativeAtStart, Vector derivativeAtEnd) + { + return new DefaultCubicSpline(points, controlPoints, knots, curveForm, knotSpec, + derivativeAtStart, derivativeAtEnd); + } + + /** + * Creates an approximating spline using the Bézier (Bernstein) polynomials as partition of unity. + * + * @param points end points of the segments of the curve. + * @param controlPoints control points of the curve, each subsequence of {@code degree} + 1 + * points starting at a multiple of {@code degree} defining one segment. + * @param knots knot values. For a Bézier curve the only knots are 0 and 1. + * @param degree degree of the Bernstein polynomials. + * @param curveForm kind of curve approximated by the spline, or {@code null} if none. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param derivativeAtStart derivative imposed at the start point, or {@code null} if none. + * @param derivativeAtEnd derivative imposed at the end point, or {@code null} if none. + */ + public static Bezier createBezier(DataPoints points, Array controlPoints, double[] knots, int degree, + SplineCurveForm curveForm, KnotType knotSpec, Vector derivativeAtStart, Vector derivativeAtEnd) + { + return new DefaultBezier(points, controlPoints, knots, degree, curveForm, knotSpec, + derivativeAtStart, derivativeAtEnd); + } + + /** + * Creates an approximating spline using the b-spline basis functions as partition of unity. + * For the rational flavour carrying a weight per control point, see + * {@link #createNurbCurve(DataPoints, double[], double[], int)}. + * + * @param points points of the curve. + * @param controlPoints control points of the curve, or {@code null} if none. + * @param knots knot values, strictly increasing, repeated knots being expressed by + * their multiplicity rather than by repetition. + * @param degree degree of the b-spline basis functions. + * @param curveForm kind of curve approximated by the spline, or {@code null} if none. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param rational whether the control points are expressed in homogeneous coordinates. + */ + public static BSplineCurve createBSplineCurve(DataPoints points, Array controlPoints, double[] knots, + int degree, SplineCurveForm curveForm, KnotType knotSpec, boolean rational) + { + return new DefaultBSplineCurve(points, controlPoints, knots, degree, curveForm, knotSpec, rational); + } + + /** + * Creates a curve defined by control points, weights, a knot vector and a degree. Depending on + * the given values it is a Bézier curve, a b-spline or a NURBS. + * + * @param points control points of the curve. + * @param weights weight of each control point, making the curve rational. + * @param knots knot values, whose multiplicities make the curve clamped or periodic. + * @param degree degree of the basis functions. + */ + public static NurbCurve createNurbCurve(DataPoints points, double[] weights, double[] knots, int degree) { + return new DefaultNurbCurve(points, weights, knots, degree); + } + + /** + * Creates a curve at a constant distance and bearing from a base curve. + * + * @param baseCurve curve from which the returned curve is offset. It shall have a + * well-defined tangent at every position. + * @param distance constant offset distance. In a 2-dimensional coordinate system, a + * positive distance designates the left side of the base curve with + * respect to the tangent, and a negative distance its right side. + * @param refDirection reference direction of the offset in a 3-dimensional coordinate system, + * or {@code null} if the spatial dimension is 2. + */ + public static OffsetCurve createOffsetCurve(Curve baseCurve, Length distance, Bearing refDirection) { + return new DefaultOffsetCurve(baseCurve, distance, refDirection); + } + + /** + * Creates a curve composed of other curves which all share the same parameter space, each of + * them covering a disjoint projection of the coordinate system. + * + * @param parameterRange interval of the construction parameter shared by all the elements. + * @param projections projections of the coordinate system matching the element curves. + * They are disjoint and together cover the whole coordinate system. + * @param elements projections of the curve, one per projection of the coordinate system. + */ + public static ProductCurve createProductCurve(Range<?> parameterRange, + List<Projection> projections, Curve ... elements) + { + return new DefaultProductCurve(parameterRange, projections, elements); + } + public static CurvePolygon createCurvePolygon(Curve exterior, List<Curve> interiors) { return new DefaultCurvePolygon(exterior, interiors); } @@ -283,6 +538,99 @@ public final class GeometryFactory extends org.apache.sis.geometry.wrapper.Geome return new DefaultMultiPolyhedron(crs, solids); } + /* + * Surfaces and solids defined over a rectangular parameter space, in which fixing all the + * parameters but one yields a family of section curves. + */ + + /** + * Creates a parametric curve surface using polylines as both horizontal and vertical curves, + * each cell of the parameter grid being interpolated bilinearly over the unit square. + * + * @param points positions at the knots of the parameter grid, in row-major order. + * There shall be {@code rows} × {@code columns} of them. + * @param controlPoints control points of the section curves in row-major order, + * or {@code null} if none. + * @param rows number of rows in the parameter grid. + * @param columns number of columns in the parameter grid. + * @param knots knot values, one sequence per surface parameter, or {@code null} if none. + */ + public static BilinearGrid createBilinearGrid(DataPoints points, List<DirectPosition> controlPoints, + int rows, int columns, List<double[]> knots) + { + return new DefaultBilinearGrid(points, controlPoints, rows, columns, knots); + } + + /** + * Creates a rational or polynomial parametric surface represented by control points, b-spline + * basis functions and possibly weights. For the rational flavour carrying a weight per control + * point, see {@link #createNurbSurface(Vector[][], double[][], double[], double[], int)}. + * + * @param points positions at the knots of the parameter grid, in row-major order. + * There shall be {@code rows} × {@code columns} of them. + * @param controlPoints control points in row-major order, or {@code null} if none. + * @param rows number of rows in the parameter grid. + * @param columns number of columns in the parameter grid. + * @param knots exactly two knot sequences, one per surface parameter, knots with a + * multiplicity greater than one being repeated in the sequence. + * @param degree algebraic degree of the b-spline basis functions. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param surfaceForm kind of surface approximated by the spline, or {@code null} if none. + * @param polynomial {@code true} if the surface is polynomial, {@code false} if the control + * points are expressed in homogeneous coordinates, making it rational. + */ + public static BSplineSurface createBSplineSurface(DataPoints points, List<DirectPosition> controlPoints, + int rows, int columns, List<double[]> knots, int degree, KnotType knotSpec, + BSplineSurfaceForm surfaceForm, boolean polynomial) + { + return new DefaultBSplineSurface(points, controlPoints, rows, columns, knots, degree, + knotSpec, surfaceForm, polynomial); + } + + /** + * Creates a NURBS surface, i.e. the tensor product of two directions each having its own knot + * vector, over a grid of weighted control points. + * + * @param controlPoints control points as a grid, the first index running along <var>u</var> + * and the second one along <var>v</var>. + * @param weights weight of each control point, in the same layout as the control points. + * @param knotsU knot values along the <var>u</var> parameter. + * @param knotsV knot values along the <var>v</var> parameter. + * @param degree degree of the basis functions. + */ + public static NurbSurface createNurbSurface(Vector<?>[][] controlPoints, double[][] weights, + double[] knotsU, double[] knotsV, int degree) + { + return new DefaultNurbSurface(controlPoints, weights, knotsU, knotsV, degree); + } + + /** + * Creates a parametric curve solid whose three families of curves are b-splines. + * + * @param points positions at the knots of the parameter grid, in row-major order. + * There shall be {@code rows} × {@code columns} × {@code files} of them. + * @param controlPoints control points in row-major order, or {@code null} if none. + * @param rows number of horizontal rows in the parameter grid. + * @param columns number of vertical columns in the parameter grid. + * @param files number of depth files in the parameter grid. + */ + public static BSplineSolid createBSolidSpline(DataPoints points, List<DirectPosition> controlPoints, + int rows, int columns, int files) + { + return new DefaultBSplineSolid(points, controlPoints, rows, columns, files); + } + + /** + * Creates a prism by extruding the given base shape between two limits. + * + * @param base base shape of the prism, for example a polygon or a circle. + * @param extrusionRange lower and upper limits of the extrusion. + * @param extrusionCrs coordinate reference system of the extrusion range. + */ + public static Prism createPrism(Geometry base, NumberRange<?> extrusionRange, SingleCRS extrusionCrs) { + return new DefaultPrism(base, extrusionRange, extrusionCrs); + } + /** * Returns a curve traversed in the opposite direction to the given one. * This is what a GML {@code gml:OrientableCurve} with {@code orientation="-"} describes. diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Prism.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Prism.java index 3ed022d992..e046881e46 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Prism.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Prism.java @@ -16,6 +16,7 @@ */ package org.apache.sis.geometries; +import org.apache.sis.geometries.internal.shared.DefaultPrism; import org.opengis.referencing.crs.SingleCRS; import org.apache.sis.measure.NumberRange; @@ -26,7 +27,8 @@ import org.apache.sis.measure.NumberRange; * @author Johann Sorel (Geomatys) * @see https://docs.ogc.org/DRAFTS/21-045r1.html#prism */ -public non-sealed interface Prism extends Geometry { +public sealed interface Prism extends Geometry + permits DefaultPrism { static final String TYPE = "PRISM"; diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Arc.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Arc.java index c87fe99bb4..3b87d7c683 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Arc.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Arc.java @@ -19,6 +19,7 @@ package org.apache.sis.geometries.curve; import java.util.List; import org.apache.sis.geometries.CurveInterpolation; import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.internal.shared.DefaultArc; import org.apache.sis.maths.Array; import org.apache.sis.maths.Vector; import static org.opengis.annotation.Specification.ISO_19107; @@ -35,9 +36,20 @@ import org.opengis.annotation.UML; */ @UML(identifier="Arc", specification=ISO_19107) public sealed interface Arc extends Conic - permits Circle + permits Circle, + DefaultArc { + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "ARC"; + + @Override + default String getGeometryType() { + return TYPE; + } + /** * Returns {@link CurveInterpolation#CIRCULAR}. * diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/BSplineCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/BSplineCurve.java index 00e3eb48b3..7a0d8215f0 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/BSplineCurve.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/BSplineCurve.java @@ -17,6 +17,7 @@ package org.apache.sis.geometries.curve; import org.apache.sis.geometries.CurveInterpolation; +import org.apache.sis.geometries.internal.shared.DefaultBSplineCurve; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -46,9 +47,20 @@ import org.opengis.annotation.UML; @UML(identifier="BSplineCurve", specification=ISO_19107) public sealed interface BSplineCurve extends SplineCurve permits Bezier, - NurbCurve + NurbCurve, + DefaultBSplineCurve { + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "BSPLINECURVE"; + + @Override + default String getGeometryType() { + return TYPE; + } + /** * Returns {@link CurveInterpolation#BSPLINE}. * diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Bezier.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Bezier.java index 3b1f487336..4416db9578 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Bezier.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Bezier.java @@ -17,6 +17,7 @@ package org.apache.sis.geometries.curve; import org.apache.sis.geometries.CurveInterpolation; +import org.apache.sis.geometries.internal.shared.DefaultBezier; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -47,7 +48,23 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 7.13.7 */ @UML(identifier="Bezier", specification=ISO_19107) -public non-sealed interface Bezier extends PolynomialSpline, BSplineCurve { +public sealed interface Bezier extends PolynomialSpline, BSplineCurve + permits DefaultBezier{ + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "BEZIER"; + + /** + * Returns {@link #TYPE}. + * This value takes precedence over the types declared by the two parent interfaces, + * a Bézier curve being at the same time a polynomial spline and a b-spline. + */ + @Override + default String getGeometryType() { + return TYPE; + } /** * Returns {@link CurveInterpolation#BEZIER_SPLINE}. diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Circle.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Circle.java index 2b35034f6d..2c2fdfb015 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Circle.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Circle.java @@ -16,6 +16,7 @@ */ package org.apache.sis.geometries.curve; +import org.apache.sis.geometries.internal.shared.DefaultCircle; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -41,7 +42,18 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 7.9.4 */ @UML(identifier="Circle", specification=ISO_19107) -public non-sealed interface Circle extends Arc { +public sealed interface Circle extends Arc + permits DefaultCircle { + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "CIRCLE"; + + @Override + default String getGeometryType() { + return TYPE; + } /** * Returns {@code true}: a circle is a complete curve closing on itself. diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Clothoid.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Clothoid.java index 12be0b05e7..56a1be372e 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Clothoid.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Clothoid.java @@ -17,6 +17,7 @@ package org.apache.sis.geometries.curve; import org.apache.sis.geometries.CurveInterpolation; +import org.apache.sis.geometries.internal.shared.DefaultClothoid; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -46,7 +47,18 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 7.11.3 */ @UML(identifier="Clothoid", specification=ISO_19107) -public non-sealed interface Clothoid extends Spiral { +public sealed interface Clothoid extends Spiral + permits DefaultClothoid { + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "CLOTHOID"; + + @Override + default String getGeometryType() { + return TYPE; + } /** * Returns {@link CurveInterpolation#CLOTHOID}. diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Conic.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Conic.java index e8d7ec1461..ccf2b1040a 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Conic.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Conic.java @@ -19,6 +19,7 @@ package org.apache.sis.geometries.curve; import org.apache.sis.geometries.Curve; import org.apache.sis.geometries.CurveInterpolation; import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.internal.shared.DefaultConic; import org.apache.sis.maths.Array; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -49,9 +50,20 @@ import org.opengis.annotation.UML; @UML(identifier="Conic", specification=ISO_19107) public sealed interface Conic extends Curve permits Arc, - EllipticArc + EllipticArc, + DefaultConic { + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "CONIC"; + + @Override + default String getGeometryType() { + return TYPE; + } + /** * Returns {@link CurveInterpolation#CONIC}. * diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/CubicSpline.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/CubicSpline.java index e68a005f5d..4f21b9e3f2 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/CubicSpline.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/CubicSpline.java @@ -16,6 +16,7 @@ */ package org.apache.sis.geometries.curve; +import org.apache.sis.geometries.internal.shared.DefaultCubicSpline; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -40,7 +41,18 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 7.13.6 */ @UML(identifier="CubicSpline", specification=ISO_19107) -public non-sealed interface CubicSpline extends PolynomialSpline { +public sealed interface CubicSpline extends PolynomialSpline + permits DefaultCubicSpline { + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "CUBICSPLINE"; + + @Override + default String getGeometryType() { + return TYPE; + } /** * Returns 3: a cubic spline is defined by polynomials of degree 3. diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/EllipticArc.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/EllipticArc.java index 5e5ad6116c..6ae57b52f2 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/EllipticArc.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/EllipticArc.java @@ -17,6 +17,7 @@ package org.apache.sis.geometries.curve; import org.apache.sis.geometries.CurveInterpolation; +import org.apache.sis.geometries.internal.shared.DefaultEllipticArc; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -37,7 +38,18 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 7.9.6 */ @UML(identifier="EllipticArc", specification=ISO_19107) -public non-sealed interface EllipticArc extends Conic { +public sealed interface EllipticArc extends Conic + permits DefaultEllipticArc { + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "ELLIPTICARC"; + + @Override + default String getGeometryType() { + return TYPE; + } /** * Returns {@link CurveInterpolation#ELLIPTICAL}. diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/OffsetCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/OffsetCurve.java index c1a0942324..5182e2b2c4 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/OffsetCurve.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/OffsetCurve.java @@ -19,6 +19,7 @@ package org.apache.sis.geometries.curve; import javax.measure.quantity.Length; import org.apache.sis.geometries.Bearing; import org.apache.sis.geometries.Curve; +import org.apache.sis.geometries.internal.shared.DefaultOffsetCurve; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -45,7 +46,18 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 6.4.20 */ @UML(identifier="OffsetCurve", specification=ISO_19107) -public non-sealed interface OffsetCurve extends Curve { +public sealed interface OffsetCurve extends Curve + permits DefaultOffsetCurve { + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "OFFSETCURVE"; + + @Override + default String getGeometryType() { + return TYPE; + } /** * Distance at which this curve is generated from the {@linkplain #getBaseCurve() base curve}. diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/PolynomialSpline.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/PolynomialSpline.java index 95d5cd090a..4446248fa3 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/PolynomialSpline.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/PolynomialSpline.java @@ -17,6 +17,7 @@ package org.apache.sis.geometries.curve; import org.apache.sis.geometries.CurveInterpolation; +import org.apache.sis.geometries.internal.shared.DefaultPolynomialSpline; import org.apache.sis.maths.Vector; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -46,9 +47,20 @@ import org.opengis.annotation.UML; @UML(identifier="PolynomialSpline", specification=ISO_19107) public sealed interface PolynomialSpline extends SplineCurve permits CubicSpline, - Bezier + Bezier, + DefaultPolynomialSpline { + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "POLYNOMIALSPLINE"; + + @Override + default String getGeometryType() { + return TYPE; + } + /** * Returns {@link CurveInterpolation#POLYNOMIAL_SPLINE}. * diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ProductCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ProductCurve.java index 3ad62d5fe8..3afd8210f6 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ProductCurve.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ProductCurve.java @@ -23,6 +23,7 @@ import org.apache.sis.geometries.CurveInterpolation; import org.apache.sis.geometries.GeometryCollection; import org.apache.sis.geometries.GeometryType; import org.apache.sis.geometries.cs.Projection; +import org.apache.sis.geometries.internal.shared.DefaultProductCurve; import org.apache.sis.measure.Range; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -52,7 +53,22 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 6.4.22 */ @UML(identifier="ProductCurve", specification=ISO_19107) -public non-sealed interface ProductCurve extends Curve, GeometryCollection<Curve> { +public sealed interface ProductCurve extends Curve, GeometryCollection<Curve> + permits DefaultProductCurve { + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "PRODUCTCURVE"; + + /** + * Returns {@link #TYPE} rather than the keyword of a plain geometry collection. + * This value resolves the ambiguity between {@link Curve} and {@link GeometryCollection}. + */ + @Override + default String getGeometryType() { + return TYPE; + } /** * Returns {@link CurveInterpolation#PRODUCT_CURVE}: the interpolation of a product curve is diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Spiral.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Spiral.java index 9981805242..87dbb7b1bc 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Spiral.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Spiral.java @@ -19,6 +19,7 @@ package org.apache.sis.geometries.curve; import java.util.List; import org.apache.sis.geometries.Curve; import org.apache.sis.geometries.CurveInterpolation; +import org.apache.sis.geometries.internal.shared.DefaultSpiral; import org.apache.sis.maths.Vector; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -47,9 +48,20 @@ import org.opengis.annotation.UML; */ @UML(identifier="Spiral", specification=ISO_19107) public sealed interface Spiral extends Curve - permits Clothoid + permits Clothoid, + DefaultSpiral { + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "SPIRAL"; + + @Override + default String getGeometryType() { + return TYPE; + } + /** * Returns {@link CurveInterpolation#SPIRAL}. * diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultArc.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultArc.java new file mode 100644 index 0000000000..59aa3b46fe --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultArc.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.List; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.Arc; +import org.apache.sis.maths.Array; +import org.apache.sis.maths.Vector; + + +/** + * A chain of circular arcs, each of them centred on a control point and joining two consecutive + * data points. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultArc extends DefaultConic implements Arc { + + /** + * Radius vectors giving, together with the two end points, the plane and the rotation direction + * of each arc. + */ + protected final List<Vector> radius; + + /** + * Creates a chain of circular arcs. + * + * @param points start and end points of the arcs, two consecutive arcs sharing a point. + * There is one more point than there are arcs. + * @param controlPoints centres of the circles carrying the arcs, one per arc. + * @param radius radius vectors of the arcs, possibly empty. + * @param cycle whether this chain closes on itself. + */ + public DefaultArc(final DataPoints points, final Array controlPoints, + final List<Vector> radius, final boolean cycle) + { + super(points, controlPoints, cycle); + this.radius = (radius == null) ? List.of() : List.copyOf(radius); + } + + /** + * Returns the number of arcs in this chain, which is one less than the number of data points. + */ + @Override + public int getNumArc() { + final int size = points.size(); + return (size == 0) ? 0 : size - 1; + } + + @Override + public List<Vector> getRadius() { + return radius; + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineCurve.java new file mode 100644 index 0000000000..34f150e7fe --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineCurve.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.Objects; +import org.apache.sis.geometries.AttributesType; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.BSplineCurve; +import org.apache.sis.geometries.curve.FunctionArc; +import org.apache.sis.geometries.curve.KnotType; +import org.apache.sis.geometries.curve.SplineCurveForm; +import org.apache.sis.maths.Array; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + + +/** + * An approximating spline using the b-spline basis functions as partition of unity, + * so that the curve stays inside the convex hull of the control points whose weight is + * currently non-zero. + * + * <p>For the rational flavour, which carries a weight per control point and can therefore be + * evaluated, see {@link DefaultNurbCurve}.</p> + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultBSplineCurve extends AbstractGeometry implements BSplineCurve { + + /** + * Points of this curve. + */ + protected final DataPoints points; + + /** + * Control points of this curve, or {@code null} if none. + */ + protected final Array controlPoints; + + /** + * Knot values defining the parameter space and the basis functions, strictly increasing. + */ + protected final double[] knots; + + /** + * Degree of the b-spline basis functions. + */ + protected final int degree; + + /** + * Kind of curve which this spline approximates, or {@code null} if none. + */ + protected final SplineCurveForm curveForm; + + /** + * Distribution of the knots, given for information only. + */ + protected final KnotType knotSpec; + + /** + * Whether this spline uses rational functions, i.e. whether its control points are expressed + * in homogeneous coordinates. + */ + protected final boolean rational; + + /** + * Creates a b-spline curve. + * + * @param points points of this curve. + * @param controlPoints control points of this curve, or {@code null} if none. + * @param knots knot values, strictly increasing, repeated knots being expressed by + * their multiplicity rather than by repetition. + * @param degree degree of the b-spline basis functions. + * @param curveForm kind of curve approximated by this spline, or {@code null} if none. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param rational whether the control points are expressed in homogeneous coordinates. + */ + public DefaultBSplineCurve(final DataPoints points, final Array controlPoints, final double[] knots, + final int degree, final SplineCurveForm curveForm, final KnotType knotSpec, + final boolean rational) + { + this.points = Objects.requireNonNull(points); + this.controlPoints = controlPoints; + this.knots = (knots == null) ? new double[0] : knots.clone(); + this.degree = degree; + this.curveForm = curveForm; + this.knotSpec = knotSpec; + this.rational = rational; + } + + @Override + public SplineCurveForm getCurveForm() { + return curveForm; + } + + @Override + public KnotType getKnotSpec() { + return knotSpec; + } + + @Override + public boolean isRational() { + return rational; + } + + @Override + public int getDegree() { + return degree; + } + + @Override + public double[] getKnots() { + return knots.clone(); + } + + /** + * Returns the number of intervals in the knot array, which is the number of arcs of this curve. + */ + @Override + public Integer getNumArc() { + return Math.max(0, knots.length - 1); + } + + @Override + public FunctionArc getSegment(int idx) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public DataPoints getDataPoints() { + return points; + } + + @Override + public Array getControlPoints() { + return controlPoints; + } + + @Override + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + return points.getCoordinateReferenceSystem(); + } + + @Override + public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) throws IllegalArgumentException { + points.setCoordinateReferenceSystem(crs); + } + + @Override + public AttributesType getAttributesType() { + return points.getAttributesType(); + } + + @Override + public boolean isEmpty() { + return points.isEmpty(); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSolid.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSolid.java new file mode 100644 index 0000000000..431bcb5f99 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSolid.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.List; +import java.util.Objects; +import org.apache.sis.geometries.AttributesType; +import org.apache.sis.geometries.Curve; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.GeometryType; +import org.opengis.geometry.DirectPosition; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.apache.sis.geometries.solid.BSplineSolid; + + +/** + * A parametric curve solid whose three families of curves are b-splines. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultBSplineSolid extends AbstractGeometry implements BSplineSolid { + + /** + * Positions of this solid at the knots of the parameter grid, in row-major order. + */ + protected final DataPoints points; + + /** + * Control points of the section curves, in row-major order, or an empty list if none. + */ + protected final List<DirectPosition> controlPoints; + + /** + * Number of horizontal rows in the parameter grid. + */ + protected final int rows; + + /** + * Number of vertical columns in the parameter grid. + */ + protected final int columns; + + /** + * Number of depth files in the parameter grid. + */ + protected final int files; + + /** + * Creates a b-spline solid over the given parameter grid. + * + * @param points positions at the knots of the parameter grid, in row-major order. + * There shall be {@code rows} × {@code columns} × {@code files} of them. + * @param controlPoints control points in row-major order, or {@code null} if none. + * @param rows number of horizontal rows in the parameter grid. + * @param columns number of vertical columns in the parameter grid. + * @param files number of depth files in the parameter grid. + */ + public DefaultBSplineSolid(final DataPoints points, final List<DirectPosition> controlPoints, + final int rows, final int columns, final int files) + { + this.points = Objects.requireNonNull(points); + this.controlPoints = (controlPoints == null) ? List.of() : List.copyOf(controlPoints); + this.rows = rows; + this.columns = columns; + this.files = files; + } + + @Override + public int getRows() { + return rows; + } + + @Override + public int getColumns() { + return columns; + } + + @Override + public int getFiles() { + return files; + } + + @Override + public DataPoints getDataPoints() { + return points; + } + + @Override + public List<DirectPosition> getControlPoints() { + return controlPoints; + } + + /** + * Returns {@link GeometryType#SPLINECURVE}: the horizontal sections are b-splines. + */ + @Override + public GeometryType getHorizontalCurveType() { + return GeometryType.SPLINECURVE; + } + + /** + * Returns {@link GeometryType#SPLINECURVE}: the vertical sections are b-splines. + */ + @Override + public GeometryType getVerticalCurveType() { + return GeometryType.SPLINECURVE; + } + + /** + * Returns {@link GeometryType#SPLINECURVE}: the depth sections are b-splines. + */ + @Override + public GeometryType getDepthCurveType() { + return GeometryType.SPLINECURVE; + } + + @Override + public Curve getHorizontalCurve(double b, double c) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Curve getVerticalCurve(double a, double c) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Curve getDepthCurve(double a, double b) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public DirectPosition getSurface(double a, double b, double c) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + return points.getCoordinateReferenceSystem(); + } + + @Override + public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) throws IllegalArgumentException { + points.setCoordinateReferenceSystem(crs); + } + + @Override + public AttributesType getAttributesType() { + return points.getAttributesType(); + } + + @Override + public boolean isEmpty() { + return points.isEmpty(); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java new file mode 100644 index 0000000000..2774c512ce --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.List; +import java.util.Objects; +import javax.measure.quantity.Area; +import org.apache.sis.geometries.Curve; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.KnotType; +import org.apache.sis.geometries.surface.BSplineSurface; +import org.apache.sis.geometries.surface.BSplineSurfaceForm; +import org.opengis.geometry.DirectPosition; +import org.opengis.geometry.Envelope; +import org.opengis.metadata.Identifier; + + +/** + * A rational or polynomial parametric surface represented by control points, b-spline basis + * functions and possibly weights. + * + * <p>For the rational flavour, which carries a weight per control point and can therefore be + * evaluated, see {@link DefaultNurbSurface}.</p> + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultBSplineSurface extends AbstractGeometry implements BSplineSurface { + + /** + * Positions of this surface at the knots of the parameter grid, in row-major order. + */ + protected final DataPoints points; + + /** + * Control points of the section curves, in row-major order, or an empty list if none. + */ + protected final List<DirectPosition> controlPoints; + + /** + * Number of rows in the parameter grid. + */ + protected final int rows; + + /** + * Number of columns in the parameter grid. + */ + protected final int columns; + + /** + * The two knot sequences used to define the basis functions, one per surface parameter. + */ + protected final List<double[]> knots; + + /** + * Algebraic degree of the b-spline basis functions. + */ + protected final int degree; + + /** + * Distribution of the knots, given for information only. + */ + protected final KnotType knotSpec; + + /** + * Kind of surface which this spline approximates. + */ + protected final BSplineSurfaceForm surfaceForm; + + /** + * Whether this surface is a polynomial spline rather than a rational one. + */ + protected final boolean polynomial; + + /** + * Creates a b-spline surface over the given parameter grid. + * + * @param points positions at the knots of the parameter grid, in row-major order. + * There shall be {@code rows} × {@code columns} of them. + * @param controlPoints control points in row-major order, or {@code null} if none. + * @param rows number of rows in the parameter grid. + * @param columns number of columns in the parameter grid. + * @param knots exactly two knot sequences, one per surface parameter, knots with a + * multiplicity greater than one being repeated in the sequence. + * @param degree algebraic degree of the b-spline basis functions. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param surfaceForm kind of surface approximated by this spline, or {@code null} if none. + * @param polynomial {@code true} if this surface is polynomial, {@code false} if the + * control points are expressed in homogeneous coordinates, which makes + * it rational. + */ + public DefaultBSplineSurface(final DataPoints points, final List<DirectPosition> controlPoints, + final int rows, final int columns, final List<double[]> knots, final int degree, + final KnotType knotSpec, final BSplineSurfaceForm surfaceForm, final boolean polynomial) + { + this.points = Objects.requireNonNull(points); + this.controlPoints = (controlPoints == null) ? List.of() : List.copyOf(controlPoints); + this.rows = rows; + this.columns = columns; + this.knots = (knots == null) ? List.of() : List.copyOf(knots); + this.degree = degree; + this.knotSpec = knotSpec; + this.surfaceForm = surfaceForm; + this.polynomial = polynomial; + } + + @Override + public int getDegree() { + return degree; + } + + @Override + public List<double[]> getKnots() { + return knots; + } + + @Override + public KnotType getKnotSpec() { + return knotSpec; + } + + @Override + public BSplineSurfaceForm getSurfaceForm() { + return surfaceForm; + } + + @Override + public boolean isPolynomial() { + return polynomial; + } + + @Override + public int getRows() { + return rows; + } + + @Override + public int getColumns() { + return columns; + } + + @Override + public DataPoints getDataPoints() { + return points; + } + + @Override + public List<DirectPosition> getControlPoints() { + return controlPoints; + } + + @Override + public Curve getHorizontalCurve(double v) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Curve getVerticalCurve(double u) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public DirectPosition getSurface(double u, double v) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Area getArea() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Identifier getName() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBezier.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBezier.java new file mode 100644 index 0000000000..9e88f0d055 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBezier.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.Bezier; +import org.apache.sis.geometries.curve.KnotType; +import org.apache.sis.geometries.curve.SplineCurveForm; +import org.apache.sis.maths.Array; +import org.apache.sis.maths.Vector; + + +/** + * An approximating spline using the Bézier (Bernstein) polynomials as partition of unity, + * the curve passing only through its first and last control point. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultBezier extends DefaultPolynomialSpline implements Bezier { + + /** + * Creates a Bézier curve of the given degree. + * + * @param points end points of the segments of this curve. + * @param controlPoints control points of this curve. For a uniform knot sequence of + * degree <var>n</var> there are <var>s</var>⋅<var>n</var> + 1 of + * them, each subsequence of <var>n</var> + 1 points starting at a + * multiple of <var>n</var> defining one segment. + * @param knots knot values. For a Bézier curve the only knots are 0 and 1. + * @param degree degree of the Bernstein polynomials. + * @param curveForm kind of curve approximated by this spline, or {@code null} if none. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param derivativeAtStart derivative imposed at the start point, or {@code null} if none. + * @param derivativeAtEnd derivative imposed at the end point, or {@code null} if none. + */ + public DefaultBezier(final DataPoints points, final Array controlPoints, final double[] knots, + final int degree, final SplineCurveForm curveForm, final KnotType knotSpec, + final Vector derivativeAtStart, final Vector derivativeAtEnd) + { + super(points, controlPoints, knots, degree, curveForm, knotSpec, + derivativeAtStart, derivativeAtEnd, Math.max(0, degree - 1)); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java new file mode 100644 index 0000000000..41fe91c035 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.List; +import java.util.Objects; +import javax.measure.quantity.Area; +import org.apache.sis.geometries.AttributesType; +import org.apache.sis.geometries.Curve; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.GeometryType; +import org.apache.sis.geometries.surface.BilinearGrid; +import org.opengis.geometry.DirectPosition; +import org.opengis.geometry.Envelope; +import org.opengis.metadata.Identifier; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + + +/** + * A parametric curve surface using polylines as both horizontal and vertical curves, each cell of + * the parameter grid being interpolated bilinearly over the unit square. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultBilinearGrid extends AbstractGeometry implements BilinearGrid { + + /** + * Positions of this surface at the knots of the parameter grid, in row-major order. + */ + protected final DataPoints points; + + /** + * Control points of the section curves, in row-major order, or an empty list if none. + */ + protected final List<DirectPosition> controlPoints; + + /** + * Number of rows in the parameter grid. + */ + protected final int rows; + + /** + * Number of columns in the parameter grid. + */ + protected final int columns; + + /** + * Construction parameter values matching the data points, the first sequence being for the + * <var>u</var> parameter and the second one for <var>v</var>. + */ + protected final List<double[]> knots; + + /** + * Creates a bilinear grid over the given parameter grid. + * + * @param points positions at the knots of the parameter grid, in row-major order. + * There shall be {@code rows} × {@code columns} of them. + * @param controlPoints control points of the section curves in row-major order, + * or {@code null} if none. + * @param rows number of rows in the parameter grid. + * @param columns number of columns in the parameter grid. + * @param knots knot values, one sequence per surface parameter, or {@code null} if none. + */ + public DefaultBilinearGrid(final DataPoints points, final List<DirectPosition> controlPoints, + final int rows, final int columns, final List<double[]> knots) + { + this.points = Objects.requireNonNull(points); + this.controlPoints = (controlPoints == null) ? List.of() : List.copyOf(controlPoints); + this.rows = rows; + this.columns = columns; + this.knots = (knots == null) ? List.of() : List.copyOf(knots); + } + + @Override + public int getRows() { + return rows; + } + + @Override + public int getColumns() { + return columns; + } + + @Override + public DataPoints getDataPoints() { + return points; + } + + @Override + public List<DirectPosition> getControlPoints() { + return controlPoints; + } + + @Override + public List<double[]> getKnots() { + return knots; + } + + /** + * Returns {@link GeometryType#LINE}: the horizontal sections of a bilinear grid are polylines. + */ + @Override + public GeometryType getHorizontalCurveType() { + return GeometryType.LINE; + } + + /** + * Returns {@link GeometryType#LINE}: the vertical sections of a bilinear grid are polylines. + */ + @Override + public GeometryType getVerticalCurveType() { + return GeometryType.LINE; + } + + @Override + public Curve getHorizontalCurve(double v) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Curve getVerticalCurve(double u) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public DirectPosition getSurface(double u, double v) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + return points.getCoordinateReferenceSystem(); + } + + @Override + public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) throws IllegalArgumentException { + points.setCoordinateReferenceSystem(crs); + } + + @Override + public AttributesType getAttributesType() { + return points.getAttributesType(); + } + + @Override + public boolean isEmpty() { + return points.isEmpty(); + } + + @Override + public Area getArea() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Identifier getName() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCircle.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCircle.java new file mode 100644 index 0000000000..e55be9dccc --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCircle.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.List; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.Circle; +import org.apache.sis.maths.Array; +import org.apache.sis.maths.Vector; + + +/** + * A complete circle, i.e. a chain of circular arcs sharing a single centre and closing on itself. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultCircle extends DefaultArc implements Circle { + + /** + * Creates a complete circle. + * + * @param points points of the circle, all at the same distance from the centre, + * the first and the last ones being equal. + * @param controlPoints the centre of the circle, repeated once per arc. Because a single arc + * must stay below a full turn, at least two of them are needed. + * @param radius radius vectors of the arcs, possibly empty. + */ + public DefaultCircle(final DataPoints points, final Array controlPoints, final List<Vector> radius) { + super(points, controlPoints, radius, true); + } + + /** + * Returns {@code true}: a circle is a complete curve closing on itself. + */ + @Override + public boolean isCycle() { + return true; + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultClothoid.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultClothoid.java new file mode 100644 index 0000000000..89e15ee4e9 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultClothoid.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.List; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.Clothoid; +import org.apache.sis.geometries.curve.RealFunction; +import org.apache.sis.maths.Vector; + + +/** + * A spiral whose curvature varies linearly with arc length, also called a Cornu spiral. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultClothoid extends DefaultSpiral implements Clothoid { + + /** + * Creates a clothoid from its curvature and the frame at its start point. + * + * @param points points of the clothoid, the first one being its start point. + * @param curvature curvature as a function of arc length. It shall be linear in the arc + * length measured from the point where the infinite clothoid has zero + * curvature. + * @param startFrame two mutually orthogonal unit vectors forming a right-handed frame at the + * start point, a clothoid being planar. + */ + public DefaultClothoid(final DataPoints points, final RealFunction curvature, final List<Vector> startFrame) { + super(points, curvature, null, startFrame); + } + + /** + * Returns {@code null}: a clothoid is a planar spiral. + */ + @Override + public RealFunction getTorsion() { + return null; + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultConic.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultConic.java new file mode 100644 index 0000000000..1050eca09e --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultConic.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.Objects; +import org.apache.sis.geometries.AttributesType; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.Conic; +import org.apache.sis.maths.Array; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + + +/** + * A chain of conic section arcs, each of them determined by five data points and drawn in the + * tangent plane at one control point. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultConic extends AbstractGeometry implements Conic { + + /** + * Points lying on the conic, four of them being consumed by each arc plus the one shared with + * the previous arc. + */ + protected final DataPoints points; + + /** + * Centers of the exponential maps in which the arcs are constructed, one per arc. + * May be {@code null} if this conic declares no control point. + */ + protected final Array controlPoints; + + /** + * Whether this conic closes on itself. + */ + protected final boolean cycle; + + /** + * Creates a conic from the given data points and control points. + * + * @param points points lying on the conic. At least five of them, the first one also + * acting as the last one when {@code cycle} is {@code true}. + * @param controlPoints centers of the exponential maps of the arcs, or {@code null} if none. + * @param cycle whether this conic closes on itself. + */ + public DefaultConic(final DataPoints points, final Array controlPoints, final boolean cycle) { + this.points = Objects.requireNonNull(points); + this.controlPoints = controlPoints; + this.cycle = cycle; + } + + @Override + public DataPoints getDataPoints() { + return points; + } + + @Override + public Array getControlPoints() { + return controlPoints; + } + + @Override + public boolean isCycle() { + return cycle; + } + + @Override + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + return points.getCoordinateReferenceSystem(); + } + + @Override + public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) throws IllegalArgumentException { + points.setCoordinateReferenceSystem(crs); + } + + @Override + public AttributesType getAttributesType() { + return points.getAttributesType(); + } + + @Override + public boolean isEmpty() { + return points.isEmpty(); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCubicSpline.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCubicSpline.java new file mode 100644 index 0000000000..56823c435d --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCubicSpline.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.CubicSpline; +import org.apache.sis.geometries.curve.KnotType; +import org.apache.sis.geometries.curve.SplineCurveForm; +import org.apache.sis.maths.Array; +import org.apache.sis.maths.Vector; + + +/** + * A polynomial spline of degree 3, C² everywhere and passing through its data points. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultCubicSpline extends DefaultPolynomialSpline implements CubicSpline { + + /** + * Number of continuous derivatives at the interior knots of a cubic spline, + * which is its degree minus one. + */ + private static final int DERIVATIVE_INTERIOR = 2; + + /** + * Creates a cubic spline interpolating the given data points. + * + * @param points points this spline passes through, in order. + * @param controlPoints control points of this spline, or {@code null} if none. + * @param knots knot values, strictly increasing, one per data point. + * @param curveForm kind of curve approximated by this spline, or {@code null} if none. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param derivativeAtStart tangent imposed at the start point, or {@code null} if none. + * @param derivativeAtEnd tangent imposed at the end point, or {@code null} if none. + */ + public DefaultCubicSpline(final DataPoints points, final Array controlPoints, final double[] knots, + final SplineCurveForm curveForm, final KnotType knotSpec, + final Vector derivativeAtStart, final Vector derivativeAtEnd) + { + super(points, controlPoints, knots, 3, curveForm, knotSpec, + derivativeAtStart, derivativeAtEnd, DERIVATIVE_INTERIOR); + } + + /** + * Returns 3: a cubic spline is defined by polynomials of degree 3. + */ + @Override + public int getDegree() { + return 3; + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultEllipticArc.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultEllipticArc.java new file mode 100644 index 0000000000..1082193172 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultEllipticArc.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.EllipticArc; +import org.apache.sis.maths.Array; + + +/** + * A conic without a cross term, therefore an arc of ellipse, each arc being determined by four data + * points instead of the five needed by a general conic. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultEllipticArc extends DefaultConic implements EllipticArc { + + /** + * Creates an elliptic arc from the given data points and control points. + * + * @param points points lying on the ellipse. Four of them determine each arc. + * @param controlPoints centers of the ellipses of the arcs, or {@code null} if none. + * @param cycle whether this arc closes on itself, making it a complete ellipse. + */ + public DefaultEllipticArc(final DataPoints points, final Array controlPoints, final boolean cycle) { + super(points, controlPoints, cycle); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultOffsetCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultOffsetCurve.java new file mode 100644 index 0000000000..b89bf050c6 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultOffsetCurve.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.Objects; +import javax.measure.quantity.Length; +import org.apache.sis.geometries.AttributesType; +import org.apache.sis.geometries.Bearing; +import org.apache.sis.geometries.Curve; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.OffsetCurve; +import org.apache.sis.maths.Array; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + + +/** + * A curve at a constant distance and bearing from a base curve. All the non-positional attributes, + * such as the coordinate reference system, are those of the base curve. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultOffsetCurve extends AbstractGeometry implements OffsetCurve { + + /** + * Curve from which this curve is defined as an offset. + */ + protected final Curve baseCurve; + + /** + * Distance at which this curve is generated from the base curve. + */ + protected final Length distance; + + /** + * Direction in which this curve is offset, or {@code null} if the spatial dimension is 2. + */ + protected final Bearing refDirection; + + /** + * Creates a curve offset from the given base curve. + * + * @param baseCurve curve from which this curve is offset. It shall have a well-defined + * tangent at every position. + * @param distance constant offset distance. In a 2-dimensional coordinate system, a + * positive distance designates the left side of the base curve with + * respect to the tangent, and a negative distance its right side. + * @param refDirection reference direction of the offset, whose cross product with the tangent + * of the base curve gives the offset direction in a 3-dimensional + * coordinate system, or {@code null} if the spatial dimension is 2. + */ + public DefaultOffsetCurve(final Curve baseCurve, final Length distance, final Bearing refDirection) { + this.baseCurve = Objects.requireNonNull(baseCurve); + this.distance = Objects.requireNonNull(distance); + this.refDirection = refDirection; + } + + @Override + public Curve getBaseCurve() { + return baseCurve; + } + + @Override + public Length getDistance() { + return distance; + } + + @Override + public Bearing getRefDirection() { + return refDirection; + } + + @Override + public DataPoints getDataPoints() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Array getControlPoints() { + return baseCurve.getControlPoints(); + } + + @Override + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + return baseCurve.getCoordinateReferenceSystem(); + } + + @Override + public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) throws IllegalArgumentException { + baseCurve.setCoordinateReferenceSystem(crs); + } + + @Override + public AttributesType getAttributesType() { + return baseCurve.getAttributesType(); + } + + @Override + public boolean isEmpty() { + return baseCurve.isEmpty(); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolynomialSpline.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolynomialSpline.java new file mode 100644 index 0000000000..71719bbe04 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolynomialSpline.java @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.Objects; +import org.apache.sis.geometries.AttributesType; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.FunctionArc; +import org.apache.sis.geometries.curve.KnotType; +import org.apache.sis.geometries.curve.PolynomialSpline; +import org.apache.sis.geometries.curve.SplineCurveForm; +import org.apache.sis.maths.Array; +import org.apache.sis.maths.Vector; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + + +/** + * A spline which interpolates its data points, i.e. a polynomial curve passing through them, + * defined piecewise between knot values by a polynomial per coordinate offset. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultPolynomialSpline extends AbstractGeometry implements PolynomialSpline { + + /** + * Points this spline passes through. + */ + protected final DataPoints points; + + /** + * Control points of this spline, or {@code null} if none. + */ + protected final Array controlPoints; + + /** + * Knot values defining the parameter space, strictly increasing, one per data point. + */ + protected final double[] knots; + + /** + * Degree of the polynomials defining the interpolation. + */ + protected final int degree; + + /** + * Kind of curve which this spline approximates, or {@code null} if none. + */ + protected final SplineCurveForm curveForm; + + /** + * Distribution of the knots, given for information only. + */ + protected final KnotType knotSpec; + + /** + * Derivative imposed at the start point. + */ + protected final Vector derivativeAtStart; + + /** + * Derivative imposed at the end point. + */ + protected final Vector derivativeAtEnd; + + /** + * Number of continuous derivatives guaranteed at the interior knots. + */ + protected final int derivativeInterior; + + /** + * Creates a polynomial spline interpolating the given data points. + * + * @param points points this spline passes through, in order. + * @param controlPoints control points of this spline, or {@code null} if none. + * @param knots knot values, strictly increasing, one per data point. + * @param degree degree of the interpolating polynomials. + * @param curveForm kind of curve approximated by this spline, or {@code null} if none. + * @param knotSpec distribution of the knots, or {@code null} if unspecified. + * @param derivativeAtStart derivative imposed at the start point, or {@code null} if none. + * @param derivativeAtEnd derivative imposed at the end point, or {@code null} if none. + * @param derivativeInterior number of continuous derivatives at the interior knots, + * at most {@code degree} − 1. + */ + public DefaultPolynomialSpline(final DataPoints points, final Array controlPoints, + final double[] knots, final int degree, final SplineCurveForm curveForm, + final KnotType knotSpec, final Vector derivativeAtStart, final Vector derivativeAtEnd, + final int derivativeInterior) + { + this.points = Objects.requireNonNull(points); + this.controlPoints = controlPoints; + this.knots = (knots == null) ? new double[0] : knots.clone(); + this.degree = degree; + this.curveForm = curveForm; + this.knotSpec = knotSpec; + this.derivativeAtStart = derivativeAtStart; + this.derivativeAtEnd = derivativeAtEnd; + this.derivativeInterior = derivativeInterior; + } + + @Override + public Vector getDerivativeAtStart() { + return derivativeAtStart; + } + + @Override + public Vector getDerivativeAtEnd() { + return derivativeAtEnd; + } + + @Override + public int getDerivativeInterior() { + return derivativeInterior; + } + + @Override + public SplineCurveForm getCurveForm() { + return curveForm; + } + + @Override + public KnotType getKnotSpec() { + return knotSpec; + } + + @Override + public int getDegree() { + return degree; + } + + @Override + public double[] getKnots() { + return knots.clone(); + } + + /** + * Returns the number of intervals in the knot array, which is the number of arcs of this spline. + */ + @Override + public Integer getNumArc() { + return Math.max(0, knots.length - 1); + } + + @Override + public FunctionArc getSegment(int idx) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public DataPoints getDataPoints() { + return points; + } + + @Override + public Array getControlPoints() { + return controlPoints; + } + + @Override + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + return points.getCoordinateReferenceSystem(); + } + + @Override + public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) throws IllegalArgumentException { + points.setCoordinateReferenceSystem(crs); + } + + @Override + public AttributesType getAttributesType() { + return points.getAttributesType(); + } + + @Override + public boolean isEmpty() { + return points.isEmpty(); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPrism.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPrism.java new file mode 100644 index 0000000000..01f768a578 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPrism.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.Objects; +import org.apache.sis.geometries.Geometry; +import org.apache.sis.geometries.Prism; +import org.apache.sis.measure.NumberRange; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.SingleCRS; + + +/** + * A base shape extruded from an optional lower limit to an upper limit. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultPrism extends AbstractGeometry implements Prism { + + /** + * Base shape which is extruded. + */ + protected final Geometry base; + + /** + * Lower and upper limits of the extrusion. + */ + protected final NumberRange<?> extrusionRange; + + /** + * Coordinate reference system in which the extrusion range is expressed. + */ + protected final SingleCRS extrusionCrs; + + /** + * Creates a prism by extruding the given base shape. + * + * @param base base shape of the prism, for example a polygon or a circle. + * @param extrusionRange lower and upper limits of the extrusion. + * @param extrusionCrs coordinate reference system of the extrusion range. + */ + public DefaultPrism(final Geometry base, final NumberRange<?> extrusionRange, final SingleCRS extrusionCrs) { + this.base = Objects.requireNonNull(base); + this.extrusionRange = Objects.requireNonNull(extrusionRange); + this.extrusionCrs = extrusionCrs; + } + + @Override + public Geometry getBase() { + return base; + } + + @Override + public NumberRange<?> getExtrusionRange() { + return extrusionRange; + } + + @Override + public SingleCRS getExtrusionCrs() { + return extrusionCrs; + } + + @Override + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + return base.getCoordinateReferenceSystem(); + } + + @Override + public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) throws IllegalArgumentException { + base.setCoordinateReferenceSystem(crs); + } + + @Override + public boolean isEmpty() { + return base.isEmpty(); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultProductCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultProductCurve.java new file mode 100644 index 0000000000..6be8db6890 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultProductCurve.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.List; +import org.apache.sis.geometries.Curve; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.cs.Projection; +import org.apache.sis.geometries.curve.ProductCurve; +import org.apache.sis.maths.Array; +import org.apache.sis.measure.Range; + + +/** + * A curve composed of other curves which all share the same parameter space, each of them covering + * a disjoint projection of the coordinate system. It is therefore both a set of curves in the + * various projections of the coordinate reference system, and a single curve in the complete system. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultProductCurve extends DefaultGeometryCollection<Curve> implements ProductCurve { + + /** + * Interval of the construction parameter shared by this curve and its projections. + */ + protected final Range<?> parameterRange; + + /** + * Projections of the coordinate system, in the same order as the element curves. + */ + protected final List<Projection> projections; + + /** + * Creates a product curve from the given element curves. + * + * @param parameterRange interval of the construction parameter shared by all the elements. + * @param projections projections of the coordinate system matching the element curves. + * The projections are disjoint and together cover the whole system. + * @param elements projections of this curve, one per projection of the coordinate system. + * They all share the knot array and the construction parameters of this curve. + */ + public DefaultProductCurve(final Range<?> parameterRange, final List<Projection> projections, + final Curve... elements) + { + super(elements); + this.parameterRange = parameterRange; + this.projections = (projections == null) ? List.of() : List.copyOf(projections); + } + + @Override + public Range<?> getParameterRange() { + return parameterRange; + } + + @Override + public List<Projection> getProjection() { + return projections; + } + + @Override + public DataPoints getDataPoints() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Array getControlPoints() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultSpiral.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultSpiral.java new file mode 100644 index 0000000000..4f8b8d8881 --- /dev/null +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultSpiral.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.geometries.internal.shared; + +import java.util.List; +import java.util.Objects; +import org.apache.sis.geometries.AttributesType; +import org.apache.sis.geometries.DataPoints; +import org.apache.sis.geometries.curve.RealFunction; +import org.apache.sis.geometries.curve.Spiral; +import org.apache.sis.maths.Array; +import org.apache.sis.maths.Vector; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + + +/** + * A curve defined indirectly by its curvature, and by its torsion when it is not planar. + * The spiral is built in the tangent space at its start point, then projected on the geometric + * reference surface. + * + * @author Johann Sorel (Geomatys) + */ +public non-sealed class DefaultSpiral extends AbstractGeometry implements Spiral { + + /** + * Points of the spiral, the first one being the start point in whose tangent space the spiral + * is constructed. + */ + protected final DataPoints points; + + /** + * Curvature of this spiral as a function of arc length. + */ + protected final RealFunction curvature; + + /** + * Torsion of this spiral as a function of arc length, or {@code null} if this spiral is planar. + */ + protected final RealFunction torsion; + + /** + * Orthonormal frame located at the start point, made of two vectors if this spiral is planar + * and of three vectors otherwise. + */ + protected final List<Vector> startFrame; + + /** + * Creates a spiral from its curvature, its torsion and the frame at its start point. + * + * @param points points of the spiral, the first one being its start point. + * @param curvature curvature as a function of arc length, measured from a fixed point of the + * infinite spiral which is not necessarily on this curve. + * @param torsion torsion as a function of arc length, or {@code null} if this spiral is planar. + * @param startFrame two or three mutually orthogonal unit vectors forming a right-handed frame + * at the start point. + */ + public DefaultSpiral(final DataPoints points, final RealFunction curvature, + final RealFunction torsion, final List<Vector> startFrame) + { + this.points = Objects.requireNonNull(points); + this.curvature = Objects.requireNonNull(curvature); + this.torsion = torsion; + this.startFrame = (startFrame == null) ? List.of() : List.copyOf(startFrame); + } + + @Override + public RealFunction getCurvature() { + return curvature; + } + + @Override + public RealFunction getTorsion() { + return torsion; + } + + @Override + public List<Vector> getStartFrame() { + return startFrame; + } + + @Override + public DataPoints getDataPoints() { + return points; + } + + /** + * Returns {@code null}: a spiral is defined by its curvature, not by control points. + */ + @Override + public Array getControlPoints() { + return null; + } + + @Override + public CoordinateReferenceSystem getCoordinateReferenceSystem() { + return points.getCoordinateReferenceSystem(); + } + + @Override + public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) throws IllegalArgumentException { + points.setCoordinateReferenceSystem(crs); + } + + @Override + public AttributesType getAttributesType() { + return points.getAttributesType(); + } + + @Override + public boolean isEmpty() { + return points.isEmpty(); + } + + @Override + public Envelope getEnvelope() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/BSolidSpline.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/BSplineSolid.java similarity index 84% rename from incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/BSolidSpline.java rename to incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/BSplineSolid.java index bf3a72c6af..5417895337 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/BSolidSpline.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/BSplineSolid.java @@ -17,6 +17,7 @@ package org.apache.sis.geometries.solid; import org.apache.sis.geometries.SolidInterpolation; +import org.apache.sis.geometries.internal.shared.DefaultBSplineSolid; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -38,7 +39,18 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 9.3.2 */ @UML(identifier="BSolidSpline", specification=ISO_19107) -public non-sealed interface BSolidSpline extends ParametricCurveSolid { +public sealed interface BSplineSolid extends ParametricCurveSolid + permits DefaultBSplineSolid { + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "BSOLIDSPLINE"; + + @Override + default String getGeometryType() { + return TYPE; + } /** * Returns {@link SolidInterpolation#BSPLINE}: the three families of curves defining the diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/ParametricCurveSolid.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/ParametricCurveSolid.java index 2feff2cc92..ebeec96f2d 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/ParametricCurveSolid.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/ParametricCurveSolid.java @@ -46,7 +46,7 @@ import org.opengis.geometry.DirectPosition; */ @UML(identifier="ParametricCurveSolid", specification=ISO_19107) public sealed interface ParametricCurveSolid extends Solid - permits BSolidSpline + permits BSplineSolid { /** diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/BSplineSurface.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/BSplineSurface.java index 8dbbe73c00..cf22e0fc66 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/BSplineSurface.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/BSplineSurface.java @@ -21,6 +21,7 @@ import org.apache.sis.geometries.AttributesType; import org.apache.sis.geometries.GeometryType; import org.apache.sis.geometries.SurfaceInterpolation; import org.apache.sis.geometries.curve.KnotType; +import org.apache.sis.geometries.internal.shared.DefaultBSplineSurface; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; import org.opengis.referencing.crs.CoordinateReferenceSystem; @@ -47,9 +48,20 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem; */ @UML(identifier="BSplineSurface", specification=ISO_19107) public sealed interface BSplineSurface extends ParametricCurveSurface - permits NurbSurface + permits NurbSurface, + DefaultBSplineSurface { + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "BSPLINESURFACE"; + + @Override + default String getGeometryType() { + return TYPE; + } + /** * Algebraic degree of the b-spline basis functions of this surface. * diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/BilinearGrid.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/BilinearGrid.java index fda24ad98b..1b155b057e 100644 --- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/BilinearGrid.java +++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/BilinearGrid.java @@ -18,6 +18,7 @@ package org.apache.sis.geometries.surface; import java.util.List; import org.apache.sis.geometries.SurfaceInterpolation; +import org.apache.sis.geometries.internal.shared.DefaultBilinearGrid; import static org.opengis.annotation.Specification.ISO_19107; import org.opengis.annotation.UML; @@ -49,7 +50,18 @@ import org.opengis.annotation.UML; * @see ISO 19107:2019 - 8.3.4 */ @UML(identifier="BilinearGrid", specification=ISO_19107) -public non-sealed interface BilinearGrid extends ParametricCurveSurface { +public sealed interface BilinearGrid extends ParametricCurveSurface + permits DefaultBilinearGrid { + + /** + * Well-known text keyword of this geometry type. + */ + static final String TYPE = "BILINEARGRID"; + + @Override + default String getGeometryType() { + return TYPE; + } /** * Returns {@link SurfaceInterpolation#LINEAR}: each cell of the grid is interpolated
