dms_intersect

Geometric functions dms_intersect

syntax

  • dms_intersect(polygon_data_itemA, polygon_data_itemB)
  • dms_intersect(polygon_data_itemA, polygon_data_itemB, grid)

description

dms_intersect(polygon_data_itemA, polygon_data_itemB) results in a data item with the intersection of the two polygon arguments: for each element, the region that lies inside both.

The operator is applied element by element. Both domains need to match, or one of the arguments needs to be a Parameter (void domain). An element with an undefined operand is undefined; an element whose intersection is empty is an empty sequence.

The dms_ prefix of the function name indicates that the implementation is GeoDMS’s own, a snap-rounding sweep, next to the four geometry libraries behind the bp_, bg_, cgal_ and geos_ prefixes. Unlike those it does not require valid input. Its meaning of a polygon is the even-odd rule: a point lies inside the polygon when a ray from that point to infinity crosses the boundary an odd number of times. Rings may self-intersect, self-touch, overlap or touch each other, or fail to close (the last point is connected back to the first), and the orientation of the rings plays no role on input. The result is written in the usual layout, clockwise shells and counter-clockwise holes, without collinear vertices and with the shells and holes ordered by their first vertex, so that A * B and B * A are the same sequence.

the grid

Every vertex and every intersection of the result lies on a grid, and that grid is the tolerance: two vertices closer than a grid cell become one, and a sliver thinner than a cell collapses. Polygon in, polygon out: a collapsed line or point is not in the result.

  • With two arguments the grid is the integer grid for ipoint, spoint, wpoint and upoint coordinates, so no vertex of the input is moved and every vertex of the result is an integer point. For fpoint and dpoint coordinates it is a power of two derived per element pair, the coarser of the unit in the last place of the largest coordinate magnitude and the joint extent of both operands divided by 2^36, which is far below the precision of geographic data.
  • With three arguments, grid is the grid size in coordinate units: a Parameter, one number for the whole attribute so that neighbours snap a shared boundary alike, positive, and a whole number for integer coordinates. This is the form for input that carries slivers or near-coincident vertices that should merge.

The snapping is reported in the trace at minor trace level: the number of crossings snapped to the grid, and the number of extra noding rounds where the snapping created a new incidence that had to be noded again.

applies to

  • Attribute polygon_data_itemA and polygon_data_itemB with a polygon Value type: spoint, ipoint, wpoint, upoint, fpoint or dpoint
  • grid: a float64 Parameter

The value types of both arguments must be the same, and their Values unit must match.

conditions

  1. The composition type of both arguments needs to be polygon.
  2. The domains of the two arguments must match, or one argument must have a void domain (parameter).
  3. grid must be a positive number, a whole number of at least 1 for integer coordinates, and coarse enough for the operands: at most 2^36 cells in either direction over their joint extent. A finer grid is refused with an error that names the extent.

since version

20.20.0

example

attribute<ipoint> overlap (district, polygon) := dms_intersect(district/geometry, municipality/geometry);
// on float64 coordinates, with slivers narrower than 0.01 coordinate units snapped away:
attribute<dpoint> overlap_d (district, polygon) := dms_intersect(district/geometry_d, municipality/geometry_d, 0.01);

See Cleaning invalid polygons for a worked example: cleaning a source, using an invalid ring as an operand, closing slivers with a grid size and cutting a hole.

see also