points2polygon - ObjectVision/GeoDMS GitHub Wiki
Constructs a point attribute with composition type polygon from a point table.
See points2sequence for the full description, arguments and examples.
Variants:
- points2polygon
- points2polygon_p
- points2polygon_po
- points2polygon_ps
- points2polygon_pso
It assembles the point sequence exactly as configured and stops there. It is a re-arrangement, not a geometry construction: nothing about the result is checked or repaired. In particular it does not
- close rings — the first point is not repeated at the end unless your point table repeats it;
- fix the point order — a counter-clockwise exterior ring stays counter-clockwise, and every operator downstream will read it as a hole (see Point order in polygons);
- remove duplicate points or spikes;
- resolve self-intersections, or make the result a valid polygon in any other sense;
- decide which ring is a shell and which is a hole, or check that holes lie inside their shell.
Whatever you feed in is what gets stored. Errors of this kind therefore do not surface here but somewhere downstream, often as a wrong area rather than as a message.
A feature with one ring may be left open. Every polygon reader closes its own working copy, so
points2polygon output with n corner points and no repeated start point is valid input.
Before GeoDMS 20.18.0 that was not true in a Debug build: the readers asserted that incoming rings were closed, and aborted on an open one, while a Release build of the same version computed the correct answer. If you hit that, see issue #1219.
A feature with more than one ring must close each ring. Rings inside one sequence are delimited by the repeat of the ring's own start point — that repeat is the only thing that marks where one ring ends and the next begins. Leave it out and the whole sequence is read as a single ring, silently. So a polygon with a hole, or a multi-polygon, needs its point table to repeat each ring's first point:
| points in the table | read as |
|---|---|
a b c |
one open ring a b c
|
a b c a |
one closed ring |
a b c a d e f d |
two rings |
a b c d e f |
one ring of six points — not what you meant |
Null values are not ring separators. They separate sub-geometries of arcs and multipoint compositions; inside a polygon ring a null is an error, and the message says so.
Build the geometry with points2polygon, then repair or verify it explicitly:
| goal | use |
|---|---|
| test whether the point order is right |
has_correct_winding — a per-element bool; better than area(g) < 0, which misses a feature where only one lake is turned the wrong way |
| repair the point order | fix_winding_order — derives shell/hole from ring nesting, so it also repairs a half-flipped multi-polygon |
| repair order and validity |
fix_polygon — fix_winding_order plus GEOS MakeValid, which resolves self-intersections |
| clean and validate with one backend | geos_polygon, bg_polygon, cgal_polygon, bp_polygon |
// assemble, then repair, then use
attribute<dpoint> raw (district, polygon) := points2polygon(pnt/xy, pnt/district_rel, pnt/ordinal);
attribute<dpoint> geom (district, polygon) := fix_polygon(raw);
// or check first, and let the run fail if the source is not what you assumed
attribute<bool> wound (district) := has_correct_winding(raw);
parameter<bool> all_wound := all(wound), IntegrityCheck = "all_wound == True";
The check in that second form is worth the two lines: it turns a silently wrong area into a failed run, at the point where the source is read rather than three operators later.
- points2sequence - the full description, arguments and examples
- Point order in polygons
- fix_polygon, fix_winding_order, has_correct_winding
- geos_polygon, bg_polygon, cgal_polygon, bp_polygon