Documentation
¶
Overview ¶
Command mapgen converts the vendored world-atlas TopoJSON into Go source.
This is the generate-time half of D63. The fetched TopoJSON is a *vendored* file — pinned, checksummed, verified by `make verify-assets`. What this command writes is *generated output*, committed the way sqlc's dbgen is committed, and re-running it on an unchanged tree must produce no diff. That is the property `make sqlc` is held to and this is held to the same one.
Conversion happens here and never at request time. The server renders inline SVG from Go data it already holds, so `ui` stays stdlib-only, nothing parses TopoJSON on a dashboard request, and the CSP is untouched.
The projection ¶
**Equirectangular (plate carrée)**, named rather than left implicit, because a choropleth's shapes are an argument about the world and an unnamed projection is an argument nobody can check. Longitude maps linearly to x and latitude linearly to y, at one uniform scale in both axes.
It is the honest choice for this particular chart. The map is read as a lookup table — "which countries clicked this link" — rather than for area or distance, and equirectangular is the only projection where a reader can point at a pixel and name its coordinates. Web Mercator would have made Greenland argue with Africa about a number neither of them is displaying.
Latitude is clipped to [-58, 84] and Antarctica is dropped. 84°N is where the northernmost land ends (Greenland reaches 83.6°N); -58° is south of Cape Horn at -55.9°. The band below that is Antarctica and empty ocean, and in an equirectangular frame it is a third of the height for a landmass that has never produced a click. Clipping is a clamp, not a cut: no shape outside the dropped continent reaches either bound, so nothing is truncated.
Winding order and the antimeridian ¶
TopoJSON follows the shapefile convention — exterior rings clockwise, holes counter-clockwise — and SVG's default `nonzero` fill rule would need that to be right in the emitted path or Lesotho would fill in solid inside South Africa. Rather than depend on upstream winding surviving arc reversal, every country is emitted as one path rendered with **fill-rule="evenodd"**, under which a ring inside another ring is a hole whichever way round it is wound. The template carries the attribute; geo.FillRule is where it comes from.
The antimeridian **does** need special handling, and the first version of this comment claimed otherwise (F210). world-atlas does not cut its rings at ±180: Fiji's ring and two of Russia's (the mainland, and Wrangel Island) cross it whole, every coordinate staying inside [-180, 180] while consecutive points jump ~360° — so the off-the-sphere check below never fires, the projected path wraps 180→-180, and its fill sweeps the frame as a horizontal band at that ring's latitudes. splitRings is the handling: any ring whose consecutive longitudes jump more than 180° is unwrapped into continuous longitude, clipped against the meridian, and emitted as one ring per side, with the crossing points interpolated onto ±180 exactly. Rings that do not cross pass through untouched, so the fix cannot move any other country.
Why the paths are relative ¶
One absolute M per subpath and relative l steps after it. At 110m resolution almost every step is under one unit, so "l.4,-.3" replaces "L643.8,165.9" and both the generated file and the markup on the wire shrink by about a third: measured, 120,457 to 81,312 bytes in the file, and a rendered link page from 213,940 to 174,792 bytes. The map is still ~86 KB of inline SVG on every view of a link that has geography, and nothing compresses it on the way out — that cost is stated in docs/usage.md rather than hidden. Deltas are computed between coordinates already quantized to the emitted precision, so the encoding is exact rather than merely close: there is no accumulating error to drift.