A link is an analysis input: master-plan D8 puts places in the hash with a
versioned binary codec, and every analysis runs on the decoded geometry, so a
link reproduces its numbers rather than approximating them. R needs to read those
links, which is why this is the twin of the app's placeCodec.ts rather than a
second design.
Arguments
- x
a place, or a list of places. A place is a list with
kind:"geom"(name,geometry, optionalprecision),"zone"(set,keys) or"upload"(name,digest).- unwrap
normalize each geometry with
unwrap_polygon()before encoding (TRUE, the default).FALSEis the strict byte-level behaviour.- hash
the hash value, with or without a leading
#
Value
place_encode() a hash string; place_decode() a list of places, each
with kind and, for "geom", geometry as an sfc plus precision
Details
place_encode_strict() is the BYTE-LEVEL encoder, the twin of the app's
encodeGeometry(). It refuses a ring that still has a consecutive-vertex step
of more than 180 degrees, with code wrapped — because such a ring is ambiguous,
and a codec that quietly repaired it would make the byte stream depend on which
language wrote it. place_encode() is the high-level entry: it runs
unwrap_polygon() first and then calls this, exactly as a TypeScript caller goes
normalizeForAnalysis() then encodeGeometry(). So the same high-level call
yields the same token on both sides, and the same low-level call yields the same
error.
place_encode(unwrap = FALSE) is the strict path for a whole hash.
The format
#pl = place ("~" place)*, each place one of
g1.name.b64url(bytes)a drawn or uploaded geometry
z.set.key,keyzone keys,
setinpa|pl|er|sr— the vintage comes from the RELEASE, never from the tokenu.name.sha256_8an upload too large to carry, naming what to re-upload
name is percent-encoded UTF-8 over A-Za-z0-9_- (so ., ~, , and %, all
structural here, cannot survive raw), at most 60 encoded characters.
The bytes are 0x10, precision:u8, npoly:varint, then per polygon
nring:varint and per ring npt:varint followed by its vertices as
zigzag-varint dlon, dlat in units of 10^-precision. The closing vertex is
omitted. The delta cursor starts at (0,0) and runs ACROSS rings and polygons —
resetting it per ring is a bug that still decodes, into a different place.
Longitudes are stored unwrapped (a Bering polygon runs 170..190), so a decoder
needs no antimeridian guess; unwrap_ring() is what puts them that way, and
place_encode() applies it.
Precision
3 by default, 4 when the bounding box is under 0.5 degrees, so the deviation is at
most 0.5 * 10^-precision — about 55 m at precision 3 and 5.5 m at precision 4.
Two entries, one byte stream
place_encode() normalizes then encodes; place_encode_strict() only encodes,
and rejects a ring that is still wrapped (code wrapped). See the details
below — the split is master-plan D8 addendum ruling 2, after the two languages
were found to disagree about the same geometry.