What tools that read or colour map-generator's maps (such as
Maphue) can rely on. Every map declares the
version it follows on its root element, data-mapgen-contract="1". The API also reports it
in the X-Mapgen-Contract header and at /api/v1/version.
crates/mapgen-data/tests/contract.rs checks these rules on the golden fixture and every
gallery map.
<svg>haswidth,heightandviewBox="0 0 width height"(pixels), anddata-mapgen-contract.data-boundary-yearanddata-source-releaseare present when the boundary version is known.<title>holds the map title, when given.<desc id="description">holds a description for screen readers (alt), and<desc id="attribution">the data credit, when there are any.- With a visible title (
show-title), a 40 px band above the map holdstext#map-title.mg-title, and theviewBoxstarts aty = -40. The map keeps its coordinates:0,0is always its top-left corner. With acaption,text#caption.mg-captionsits in a band under the map. Neither is inside a layer group.
Main-map groups, bottom to top, by id (a group is absent when empty):
| id | Content |
|---|---|
background |
a rect |
water |
a path |
context |
neighbouring countries |
context-borders |
their borders |
land |
the regions being mapped |
lakes |
lakes |
disputed-areas |
hatched disputed areas |
borders |
borders, one path per kind |
places |
capitals, when drawn (capitals) |
labels |
labels |
Insets are g.mg-inset groups (ids inset-1, inset-2…) after the main layers. They
contain the same layers as classes (g.mg-land, g.mg-labels…), plus a rect.mg-inset-frame.
Every region of the mapped area is exactly one path with the class mg-land, in #land
or an inset's .mg-land, with:
| Attribute | Content |
|---|---|
id |
unique, valid XML id derived from the code |
data-code |
the region's code as in the data: ISO 3166-2 (FR-75), FIPS (US-31109), ADM0_A3 (FRA)… |
data-name |
its name |
data-parent |
code of the enclosing unit (FR-IDF, US-31), when known |
data-parent-name |
its name, when known (only together with data-parent) |
data-unit |
space-separated data units the region belongs to, when set |
data-wikidata |
the region's Wikidata item (Q142), when known (Natural Earth layers) |
class |
mg-land, the feature class (subdivision, country, region…), and the lowercase ISO 3166-1 alpha-2 code of its country (fr) when known |
Each region has a <title> child for tooltips ("Lancaster, Nebraska").
With capitals, each capital is a circle.mg-place in #places, with the class
mg-capital (national) or mg-region-capital, and data-name, data-country (lowercase
ISO 3166-1 alpha-2) and data-wikidata when known, plus a <title>. Regional capitals are
drawn only inside the mapped regions. Their names are text.mg-place-label, and with
context-labels the names of neighbouring countries are text.mg-context-label, both in
#labels after the region labels (text.mg-label). Colouring tools should leave them alone.
Neighbouring countries are path.mg-context in #context (or .mg-context), with the same
attributes.
- Colours are defined only in the
<style>block, through.mg-*classes. Region and neighbour paths have nofillorstyleattribute. - So a consumer can colour regions with its own CSS (
[data-code="FR-75"]{fill:#c00},[class~="fr"]{…}) or inline styles, and they override the map's colours. - With
css-vars, every colour isvar(--mg-<slot>, <fallback>). The slots are listed at/api/v1/themesand bymapgen themes.
- Labels are only in
#labels(or an inset's.mg-labels), with the classmg-label. - Multilingual labels are
<switch>elements whose children carrysystemLanguage, with the default name last. - Curved labels are rotated letters in
g.mg-label[aria-label](thecommonstarget) ortextPath(thewebtarget).
These can change in any release, without a contract version bump:
- path data (simplification, precision, coordinates), and the order of elements within a layer;
- label positions, sizes and which labels fit;
- theme colours and stroke widths (use CSS or
css-varsto set your own); - element ids other than layers, insets and regions.
- Adding an attribute, class or layer keeps the version.
- Removing one, or changing what it means, increments the version and is noted in the
changelog. The API keeps serving the previous version under its
/api/v1path until that path's announced sunset.