Repository navigation
Story: Implement CIRCULARSTRING spatial type #24
Description
Implement CIRCULARSTRING spatial type
As a developer using spatial-types,
I want CIRCULARSTRING to be fully implemented as a concrete spatial type,
so that circular curves can be represented according to the spatial model and consumed by downstream libraries such as the EWKT decoder.
Context
CIRCULARSTRING is an instantiable subtype of CURVE.
It is required for the spatial-types 1.0.0 release because it belongs to the geometry set required to complete the targeted EWKT decoding support in spatial-decoder.
According to ISO/IEC 13249-3, a CircularString consists of one or more circular arc segments connected end to end.
The first arc segment is defined by three points:
- its start point;
- an intermediate point on the arc;
- its end point.
Each subsequent arc segment shares the previous segment's end point as its start point and is therefore represented by two additional points: its intermediate point and its end point.
Consequently, a non-empty CircularString contains at least three points and its number of points follows the form:
3 + 2n
where n >= 0.
A CircularString containing exactly three points represents a single circular arc.
A CircularString may also represent a complete circle when the start and end points of an arc segment coincide.
If the start, intermediate and end points of an arc segment are collinear, the segment degenerates to the straight line connecting its start and end points. This is a valid CircularString segment and must not be rejected solely because the three points are collinear.
A CircularString that is both closed and simple represents a circular ring.
Functional Requirements
CIRCULARSTRING must follow the existing spatial-types architecture and expose the public contracts appropriate for an instantiable CURVE.
The implementation must support the coordinate dimensions supported by the LongitudeOne spatial model:
XY;XYZ;XYM;XYZM.
All points belonging to a CircularString must satisfy the dimensional and spatial-reference consistency rules already established by spatial-types.
An empty CircularString must be representable consistently with the existing empty-geometry model.
For a non-empty CircularString:
- at least three points are required;
- the number of points must be odd;
- the first three points define the first circular arc segment;
- each pair of subsequent points defines the intermediate and end points of the next segment;
- adjacent arc segments are implicitly contiguous because the end point of one segment is the start point of the next.
The implementation must not approximate circular arcs using linear segments. The stored points represent the defining points of the circular interpolation.
Normative Behavior
The implementation must preserve the following ISO/IEC 13249-3 semantics:
CIRCULARSTRINGis an instantiable subtype ofCURVE;- interpolation between its defining points is circular;
- a three-point CircularString represents one circular arc;
- multiple arcs share their connecting endpoint;
- a complete circular arc may have coincident start and end points;
- a collinear start, intermediate and end point defines a degenerate straight-line arc and remains valid;
- a CircularString that is closed and simple is a circular ring.
The implementation must not introduce additional validity restrictions that contradict these semantics.
Public Contract
The implementation must provide the same architectural guarantees as the other concrete curve types exposed by spatial-types.
The public API must allow consumers to:
- construct an empty CircularString;
- construct a CircularString from valid points;
- access its defining points;
- determine its coordinate dimension;
- determine its spatial reference according to the existing spatial type contracts;
- identify its geometry type as
CIRCULARSTRING; - use it through the applicable spatial and curve interfaces.
The API must not expose implementation details that would unnecessarily constrain future internal evolution after spatial-types 1.0.0.
Validation
Validation must reject a non-empty CircularString when:
- it contains fewer than three points;
- its number of points is even;
- its points do not satisfy the required coordinate-dimension consistency;
- its points do not satisfy the required spatial-reference consistency;
- another existing invariant inherited from the applicable
spatial-typescontracts is violated.
Validation must not reject a CircularString solely because the three defining points of an arc are collinear.
The complete-circle case must be supported when permitted by the normative model.
Implementation Status
Once this Story is completed, CIRCULARSTRING is no longer considered a not-yet-implemented geometry type.
SpatialTypeImplementationStatus::isFullyImplemented() must return true for GeometryTypeEnum::CIRCULARSTRING.
Acceptance Criteria
- A public concrete implementation exists for
CIRCULARSTRING. -
CIRCULARSTRINGfollows the applicableCURVEand spatial type contracts. - Empty CircularStrings are supported consistently with the existing empty-geometry model.
-
XYCircularStrings are supported. -
XYZCircularStrings are supported. -
XYMCircularStrings are supported. -
XYZMCircularStrings are supported. - A non-empty CircularString requires at least three points.
- A non-empty CircularString requires an odd number of points.
- A CircularString containing exactly three points represents one circular arc.
- CircularStrings containing multiple connected arc segments are supported.
- Complete-circle arc segments with coincident start and end points are supported.
- Collinear defining points are accepted and represent a degenerate straight-line arc as specified by ISO/IEC 13249-3.
- Existing coordinate-dimension consistency rules are enforced.
- Existing spatial-reference consistency rules are enforced.
- The geometry type is reported as
CIRCULARSTRING. -
SpatialTypeImplementationStatus::isFullyImplemented()returnstrueforCIRCULARSTRING. - Unit tests cover empty, single-arc, multiple-arc, complete-circle and degenerate collinear cases.
- Unit tests cover
XY,XYZ,XYMandXYZM. - Invalid point counts are covered by tests.
- Dimension and spatial-reference inconsistencies are covered by tests.
- The public implementation can be consumed without relying on internal APIs.
- The complete test suite passes.
- All project quality checks pass.
Out of Scope
This Story does not implement:
COMPOUNDCURVE;CURVEPOLYGON;- other curve types;
- EWKT parsing or decoding;
- WKT, WKB, EWKB or other serialization formats;
- linear approximation or rendering of circular arcs.
Those concerns belong to their respective libraries or subsequent Stories.
Activity
spatial-types1.0.0 #23spatial-types1.0.0 #26COMPOUNDCURVEspatial type #25Alexandre-T commentedon Oct 4, 2026
API Gate approved.
Introduce a common CurveInterface as part of this Story.
LineStringInterface and the new CircularStringInterface must extend CurveInterface. Update the existing LineStringInterface contract accordingly and remove or update the documentation that explicitly states that no common curve interface currently exists.
Keep CurveInterface minimal. Do not introduce speculative operations solely to model every possible future curve type. It must contain only contracts that are genuinely common to the curve abstractions supported by the current architecture and that we are prepared to stabilize for 1.0.0.
CircularStringInterface must expose the CircularString-specific contract, while its concrete Geometry and Geography implementations must follow the existing immutable architecture and dimensional/SRID conventions.
This decision is also intended to provide the abstraction required by the upcoming CompoundCurve implementation. CompoundCurve must eventually be able to depend on CurveInterface rather than on a LineStringInterface|CircularStringInterface union.
This approval does not authorize unrelated public API changes. If introducing CurveInterface reveals another public-contract decision that cannot be derived from the existing architecture or normative requirements, stop at that API Gate and request approval.
[-]Implement `CIRCULARSTRING` spatial type[/-][+]Story: Implement `CIRCULARSTRING` spatial type[/+]