The galaxy basemap was localizable all along: its label keys use an underscore, not a colon

exp-shepherd found research-dashboard rendering ENDONYMS in every locale — 中国 and Türkiye on a Russian
page — and fetching a glyph range for every script on screen. The reading was that its basemap carries no
localized names and the choice was to swap the basemap or give up on its labels. Measured against the live
tiles, neither is necessary: the names are there, under keys this chain never tried.

The galaxy style is VersaTiles Colorful on the SHORTBREAD schema, whose label keys are name_ar / name_de /
name_en, not name:ar. This coalesce only tried the colon spelling, so all 43 of that style's label layers
fell through to `name` — the local name — while the localizer ran and reported success. A running fix that
cannot reach its data looks exactly like a missing feature.

MEASURED, six z3/z4 tiles across Europe, Asia and Africa, identical key sets on every one: name_ar,
name_de, name_el, name_en, name_es, name_fr, name_it, name_nl, name_pl, name_pt, name_uk. Of the eleven
locales we ship that is SEVEN in their own language — ar, de, en, es, fr, it, pt — with no change to the
basemap the Driver chose and no change to how the map looks.

hi, ro, ru and zh are genuinely absent from those tiles, so they now take name_en: one Latin script rather
than mixed CJK and Devanagari endonyms, which is also the single-script glyph saving. That is the same role
name:latin already plays for the OpenFreeMap styles, so it sits in the same position in the chain rather
than becoming a special case.

NOTHING CHANGES FOR THE OPENFREEMAP STYLES, by construction: the colon spelling stays first, so their
name:<lang> or name:latin still wins and the underscore entries are never reached. The order is also what
keeps the already-rewritten sentinel working — it tests for a chain beginning ["coalesce",["get","name:,
which this still is. Verified both, rather than assumed.

WHAT I DID NOT DO: swap the basemap. galaxy resolves to VersaTiles Colorful because the Driver asked for
blue oceans like the Mapbox map and that style's water measured closest (#bfd9f2; OpenFreeMap Liberty is
#9ebdff, noticeably stronger). Trading a look he chose for four locales' labels is his call, not mine, and
with this change those four get readable Latin labels anyway.

Verified: gates:pre 12/12. NOT measured here: glyph KB per locale, which needs a browser — rega has the
instrument and the before numbers.
This commit is contained in:
Doxa Maps 2026-09-28 03:52:50 +00:00
parent daffaa6ef5
commit 5f053d992c

View file

@ -61,7 +61,31 @@ export function localizeBasemapLabels(map, lang) {
// English too, not the style's own bilingual labels ("Россия" under "Russia"): those drew every
// native script at world view, so an English page fetched 13 extra glyph ranges (~600 KB, rega:
// Prayer Progress 18 requests / 777 KB in en against 5 / 185 KB in ar). One language per label.
const next = ['coalesce', ['get', 'name:' + code], ['get', 'name:latin'], ['get', 'name']]
// ★ AND THE UNDERSCORE SPELLING, because one of our basemaps writes it that way. The galaxy
// style (research-dashboard, my-upg-100-list) is VersaTiles Colorful on the Shortbread schema,
// whose label keys are name_ar / name_de / name_en …, NOT name:ar. This chain only tried the
// colon spelling, so every one of its 43 label layers coalesced down to `name` — the ENDONYM —
// and a Russian page rendered 中国 and Türkiye while fetching a glyph range for every script on
// screen. The localizer was running and could not help, which is the failure that looks like a
// basemap problem and is really a key-name problem.
//
// MEASURED against the live tiles (six z3/z4 tiles across Europe, Asia and Africa, identical key
// sets): name_ar, name_de, name_el, name_en, name_es, name_fr, name_it, name_nl, name_pl,
// name_pt, name_uk. Of the eleven locales we ship that covers SEVEN — ar, de, en, es, fr, it, pt
// — in their own language, with no change to the basemap the Driver chose.
//
// hi, ro, ru and zh are genuinely absent from those tiles, so they take name_en: Latin script,
// one script, readable rather than mixed CJK and Devanagari endonyms. That is the same role
// name:latin already plays for the OpenFreeMap styles, which is why it sits in the same position
// rather than being a special case.
//
// Order matters and is not arbitrary: the colon spelling first so the OpenFreeMap styles behave
// exactly as before (their first entry still wins and nothing about them changes), then the
// underscore, then the two Latin fallbacks, then the local name.
const next = ['coalesce',
['get', 'name:' + code], ['get', 'name_' + code],
['get', 'name:latin'], ['get', 'name_en'],
['get', 'name']]
map.setLayoutProperty(layer.id, 'text-field', next)
n++
}