Skip to content

Geometry: add getLinearized(), getCurved()#1382

Draft
dbaston wants to merge 9 commits intolibgeos:mainfrom
dbaston:linearize
Draft

Geometry: add getLinearized(), getCurved()#1382
dbaston wants to merge 9 commits intolibgeos:mainfrom
dbaston:linearize

Conversation

@dbaston
Copy link
Copy Markdown
Member

@dbaston dbaston commented Jan 29, 2026

TODO:

  • Test Z/M handling
  • Review / incorporate GDAL tests from ogr_geom.py
  • Add support for maximum-deviation tolerance
  • C API

@dbaston dbaston added Enhancement New feature or feature improvement. Curves labels Jan 29, 2026
@dbaston dbaston force-pushed the linearize branch 2 times, most recently from 9b03e93 to a4e5105 Compare February 13, 2026 13:46
@dbaston dbaston force-pushed the linearize branch 3 times, most recently from 78207c4 to ea99660 Compare March 8, 2026 01:15
@dbaston dbaston added this to the 3.15.0 milestone Mar 9, 2026
@dbaston dbaston force-pushed the linearize branch 14 times, most recently from 2311650 to 58da56f Compare March 13, 2026 16:54
@dbaston
Copy link
Copy Markdown
Member Author

dbaston commented Mar 17, 2026

I've updated the C API to provide for manual or automatic conversion between curved and linear geometry types.

Manual conversion

Uses the curve conversion functions GEOSCurveToLine and GEOSLineToCurve.

GEOSCurveToLine is a simplified version of the PostGIS/QGIS ST_CurveToLine. It divides an arc into fixed-angle sections using either a maximum angle or a maximum deviation. The API allows for other tolerance types to be added in the future, as long as they fit the signature of GEOSCurveToLine_setTolerance(int toleranceType, double toleranceValue).

GEOSLineToCurve generally follows PostGIS ST_LineToCurve. It exposes three tolerances, all of which simultaneously apply:

  • Radius tolerance: maximum relative difference between a point and the radius of the first three points in the candidate arc. Defaults to 1e-6. Here PostGIS uses a hardcoded absolute difference of 1e-8. QGIS also uses an absolute difference.
  • Maximum arc step size: Corresponds to the same parameter in GEOSCurveToLine. Hardcoded in PostGIS at ~45 degrees, depending on the total angle of arc. (2 edges/quadrant). Defaults in GEOS to the same.
  • Maximum exterior angle difference between successive vertices. Hardcoded in PostGIS at 1e-8 radians. Much looser default in GEOS: 1e-2 radians.

Each of these tolerances is set with a separate function:

GEOSLineToCurveParams_setRadiusTolerance
GEOSLineToCurveParams_setMaxStepDegrees
GEOSLineToCurveParams_setMaxAngleDifferenceDegrees

To me, this better indicates that the three tolerances apply simultaneously, unlike the GEOSCurveToLine tolerance. But the three functions could be replaced with a GEOSLineToCurve_setTolerance(int toleranceType, double toleranceValue).

Automatic conversion

Functions that do not natively support curved types have been modified to optionally convert inputs/outputs from/to curved types. This allows a client like QGIS to delegate an operation to GEOS without having to know if the linked version of GEOS supports curved inputs for that operation.

Curve conversion is enabled at the context handle level.

Setting the curve-to-line parameters on the context (GEOSContext_setCurveToLineParams_r) will cause input curved types to be converted to linear types, if needed.

Setting line-to-curve parameters on the context (GEOSContext_setLineToCurveParams) will cause output linear types to be converted to curved types, if the inputs were themselves converted from curves.

Automatic curve conversion is not enabled on the non-reentrant API. (Should it be?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Curves Enhancement New feature or feature improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant