Mapping - ObjectVision/GeoDMS GitHub Wiki
Relational functions mapping
- mapping(SrcUnit, DstUnit)
mapping(SrcUnit, DstUnit) results in a relation with the index numbers of the domain unit DstUnit. The resulting attribute has as values unit DstUnit and as domain unit SrcUnit.
mapping(SrcUnit, DstUnit) is equivalent with convert(id (SrcUnit), DstUnit), but requires less memory: id would first materialise the coordinates of every SrcUnit cell for convert to read, whereas mapping generates them.
If only the number of SrcUnit cells per DstUnit cell is needed, use mapping_count rather than [pcount]: it produces neither the SrcUnit-sized relation nor a materialised result.
The result takes part in tile pipelining: under multi-threading level 3 — MT3, /S3 for GeoDmsRun — it is a virtual data segment with segment-level ownership and lifetime rather than a materialised array. When the result has more than one tile, tiles are produced on demand and held only for as long as a consumer needs them: a released tile is recomputed when it is asked for again. Without MT3 the result is calculated as a whole instead.
For a coordinate separable transformation (see below) what is retained between those recomputations is not the relation but the two transformed coordinate arrays — one transformed x per SrcUnit column and one transformed y per row. A cell (r, c) is then read back as (x[c], y[r]). For a W × H domain that is W + H retained values instead of W · H, and refilling a released tile costs no coordinate transformation at all — which is what makes releasing it cheap enough to be the default. Measured on a 49 M cell grid, filling the tiles from those two arrays is indistinguishable from merely enumerating the domain.
The SrcUnit and the DstUnit need not share a SpatialReference. Three cases are distinguished, in increasing cost. The first two are handled the same way — through the two transformed coordinate arrays — and differ only in whether PROJ is needed to fill those arrays:
-
Same SpatialReference, different Projection. Two grids over the same coordinate unit that differ only in grid size and offset — the usual grid-to-grid case. The conversion is the per-axis affine composed from the two
UnitProjections, which is separable by construction: no PROJ call is made at all, and the transformed coordinate arrays are used just as they are in case 2. -
Different SpatialReference, coordinate separable. GDAL/PROJ is used, but the transformation is recognised as one whose easting is a function of the longitude alone and whose northing is a function of the latitude alone. Only one transformed x per SrcUnit column and one transformed y per row are computed: W + H PROJ calls for the whole domain instead of W · H. The prime example is Web Mercator (
EPSG:3857) to and from LatLong (EPSG:4326), both over the WGS 84 datum. Also recognised: Mercator (merc, e.g.EPSG:3395), Equirectangular / Plate Carrée (eqc), Miller (mill) and Cylindrical Equal Area (cea), each against an unchanged datum. -
Different SpatialReference, not separable. Every cell is transformed individually, in batches. This covers Transverse Mercator and UTM (whose easting reads the latitude too), oblique Mercator, the conic and azimuthal projections (Lambert, Albers, Stereographic), the pseudo-cylindrical ones (Mollweide, Sinusoidal, Robinson), and any transformation involving a datum shift — a Helmert or grid-shift step passes through geocentric XYZ, where every output ordinate reads every input ordinate.
Separability is never assumed from the SpatialReference alone. The candidate pair is first screened structurally (unchanged datum plus a recognised projection method) and then verified numerically and exactly on a lattice of probe points; any disagreement, even by one unit in the last place, makes the calculation fall back to case 3. This is deliberate: a merely nearly separable transformation, such as UTM over a narrow bounding box, would otherwise pass a tolerance-based test and silently produce different results.
Note that the axis order is taken from the SpatialReference and not assumed. EPSG:4326 is defined in authority order (latitude, longitude) while EPSG:3857 is (easting, northing), so for that pair the transformed column values come from the row coordinate and vice versa. Which coordinate feeds which is determined from the data, so both directions work.
The transformed coordinate arrays are addressed at absolute grid positions, so each tile reads exactly the entries belonging to its own cells. A GeoDMS Default Tiling domain and an irregularly tiled one — a TiledUnit over a sparse study area, whose tiles cover only part of their bounding rectangle — are therefore handled the same way: cells that lie in no tile are simply never read. This is unlike mapping_count, which aggregates over the source and must account for those gaps explicitly.
- SrcUnit, DstUnit units with value types of the group CanBeDomainUnit
7.119
20.13.0: tile pipelining (MT3) of the result, and the coordinate-array treatment of every separable transformation described above — both the same-SpatialReference affine and separable CRS conversions.
unit<uint32> RegionSrc: nrofrows = 5;
unit<uint32> RegionDst: nrofrows = 5;
attribute<RegionDst> RegionDst_rel (RegionSrc) := mapping(RegionSrc, RegionDst);
| RegionDst_rel |
|---|
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
domain RegionSrc, nr of rows = 5