GeometryNoder: Add collection noding with per-member identity#1460
GeometryNoder: Add collection noding with per-member identity#1460pramsey wants to merge 1 commit into
Conversation
Extend GeometryNoder with a new nodeCollection() API that nodes a vector of geometries against each other while preserving 1:1 input/output identity: output element i is the noded form of input element i, as a MultiLineString (or MultiCurve for curved members). This is distinct from the existing node() path, which dissolves all input into a single flat MultiLineString. Shared linework is retained in every member that touches it; point members yield empty MultiLineString slots; areal members contribute their boundary rings as noded linework, consistent with the existing single-geometry behaviour. Snap-rounding (gridSize > 0) is supported for linear input. When any member is curved, gridSize is ignored and exact arc noding runs instead, so curve support is inherited from the existing SimpleNoder / ArcIntersectionAdder / CurveRebuilder machinery at no extra cost. Expose the new functionality in the C API as GEOSNodeCollection(input, gridSize). A non-collection input is treated as a one-member collection.
| geoms[i] = input->getGeometryN(i); | ||
| } | ||
|
|
||
| auto noded = geos::noding::GeometryNoder::nodeCollection(geoms, gridSize); |
There was a problem hiding this comment.
Does the conversion to a vector buy anything here? It seems like nodeCollection could take a collection as an argument instead of a vector. That would also clean up GeometryNoder by not having both argGeom1 and argColl members, and would remove the need for the collectionHasCurves helper.
There was a problem hiding this comment.
CoverageSimplifier is the analogue I was looking at, which has
std::vector<std::unique_ptr<Geometry>>
CoverageSimplifier::simplify(
std::vector<const Geometry*>& coverage,
double tolerance)
as its main entry point. On the flip in the C API the entry point is
Geometry*
GEOSCoverageSimplifyVW(
const Geometry* input,
double tolerance,
int preserveBoundary)
so.... what would you prefer?
There was a problem hiding this comment.
geom.hasCurvedComponents() in place of collectionHasCurves() I presume
There was a problem hiding this comment.
No strong preference I guess, it would just be nice if there was some way to not have all of argGeom1, argGeom2, and argColl (whose name implies a collection but is not...)
| if (argGeomHasCurves) { | ||
| // Snap-rounding cannot node arcs; curved input always uses | ||
| // exact arc noding and ignores any requested gridSize. | ||
| noder = std::make_unique<SimpleNoder>(); |
There was a problem hiding this comment.
Maybe better to error instead of ignoring the parameter.
| // The arc slot stays curved: a MultiCurve of two CircularStrings. | ||
| ensure_equals("arc slot type", result[1]->getGeometryTypeId(), geos::geom::GEOS_MULTICURVE); | ||
| ensure_equals("arc split count", result[1]->getNumGeometries(), 2u); | ||
| for (std::size_t i = 0; i < result[1]->getNumGeometries(); i++) { |
There was a problem hiding this comment.
Loop from i = 0 to i = 1 seems unnecessary
Extend GeometryNoder with a new nodeCollection() API that nodes a vector of geometries against each other while preserving 1:1 input/output identity: output element i is the noded form of input element i, as a MultiLineString (or MultiCurve for curved members).
This is distinct from the existing node() path, which dissolves all input into a single flat MultiLineString. Shared linework is retained in every member that touches it; point members yield empty MultiLineString slots; areal members contribute their boundary rings as noded linework, consistent with the existing single-geometry behaviour.
Snap-rounding (gridSize > 0) is supported for linear input. When any member is curved, gridSize is ignored and exact arc noding runs instead, so curve support is inherited from the existing SimpleNoder / ArcIntersectionAdder / CurveRebuilder machinery at no extra cost.
Expose the new functionality in the C API as GEOSNodeCollection(input, gridSize). A non-collection input is treated as a one-member collection.