mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 05:56:53 +00:00
6a5f067663
Zooming into England showed nothing below "England" itself, so boroughs marked as visited had no polygon to light up. It stopped working in 3.1.0, when the runtime Natural Earth fetch was replaced by the bundled geoBoundaries assets: Natural Earth carried 232 GB regions including the London boroughs, and geoBoundaries calls the four constituent countries ADM1. The builder asks every country for ADM1, so GB shipped as four features. GB now ships at ADM2 — 216 counties and unitary authorities, which is the granularity every other country gets from its ADM1 and the granularity that was there before. That is a deliberate one-country list: ADM2 everywhere would multiply the bundle for no gain, since ADM1 already is the level people think in for most countries. Two things had to be said to data that already exists. Regions marked before 3.1.0 hold the old Natural Earth codes, and are reconciled by name within the country, the way the 3.1.1 step already does for everywhere else; a row that still cannot be matched is left alone rather than destroyed. And place_regions is full of GB-ENG rows that were correct under the old bundle — nothing re-derives a row that is already cached, so without clearing them every English place would keep reporting "England" forever. The bundle guard that would have caught this in 3.1.0 is now in place: four features for a whole country is not a region layer. Closes #1974
82 lines
4.0 KiB
TypeScript
82 lines
4.0 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import zlib from 'zlib';
|
|
|
|
// Data-integrity guard for the shipped Atlas region bundle. geoBoundaries fills
|
|
// shapeISO with the bare country code for some countries (every Spanish region got
|
|
// "ESP", every Chinese "CHN", also CL/OM), which made marking one region light up the
|
|
// whole country (#1217). build-atlas-geo.mjs now synthesizes a unique per-region code
|
|
// for those; this asserts the shipped bundle actually carries distinct codes.
|
|
// Countries with user-assigned ISO codes (Kosovo = XK/XKX) are absent from the
|
|
// upstream ISO list the builder's A3_TO_A2 map was sourced from, which shipped
|
|
// Kosovo with ISO_A2=null — unresolvable by the client, so it had no hover/click
|
|
// handlers and never appeared in search (#1609). Guard that the country bundle
|
|
// carries the alpha-2 code the client keys on.
|
|
describe('Atlas admin0 country bundle (#1609)', () => {
|
|
const bundlePath = path.join(__dirname, '..', '..', '..', 'assets', 'atlas', 'admin0.geojson.gz');
|
|
const features = JSON.parse(zlib.gunzipSync(fs.readFileSync(bundlePath)).toString()).features as {
|
|
properties: { ISO_A2: string | null; ADM0_A3: string; NAME?: string };
|
|
}[];
|
|
|
|
it('ATLAS-BUNDLE-003 — Kosovo ships with a resolvable ISO_A2', () => {
|
|
const kosovo = features.filter(f => f.properties.ADM0_A3 === 'XKX');
|
|
expect(kosovo.length, 'exactly one Kosovo feature').toBe(1);
|
|
expect(kosovo[0].properties.ISO_A2).toBe('XK');
|
|
});
|
|
});
|
|
|
|
describe('Atlas admin1 region bundle (#1217)', () => {
|
|
const bundlePath = path.join(__dirname, '..', '..', '..', 'assets', 'atlas', 'admin1.geojson.gz');
|
|
const features = JSON.parse(zlib.gunzipSync(fs.readFileSync(bundlePath)).toString()).features as {
|
|
properties: { iso_a2: string | null; iso_3166_2: string };
|
|
}[];
|
|
|
|
const regions = (a2: string) => features.filter(f => f.properties.iso_a2 === a2);
|
|
|
|
it('ATLAS-BUNDLE-001 — previously-broken countries now have distinct region codes', () => {
|
|
for (const a2 of ['ES', 'CN', 'CL', 'OM']) {
|
|
const f = regions(a2);
|
|
expect(f.length, `${a2} should ship regions`).toBeGreaterThan(1);
|
|
expect(new Set(f.map(r => r.properties.iso_3166_2)).size, `${a2} region codes must be unique`).toBe(f.length);
|
|
}
|
|
});
|
|
|
|
it('ATLAS-BUNDLE-002 — countries with real ISO codes keep them and stay unique', () => {
|
|
for (const a2 of ['DE', 'FR', 'US']) {
|
|
const f = regions(a2);
|
|
expect(f.length).toBeGreaterThan(1);
|
|
// real ISO 3166-2 form, e.g. DE-BW
|
|
expect(f.some(r => /^[A-Z]{2}-[A-Z0-9]+$/.test(r.properties.iso_3166_2))).toBe(true);
|
|
expect(new Set(f.map(r => r.properties.iso_3166_2)).size).toBe(f.length);
|
|
}
|
|
});
|
|
|
|
/*
|
|
* geoBoundaries' GBR ADM1 is the four constituent countries, so a bundle built
|
|
* from it has no polygon below "England" — a London borough marked as visited
|
|
* has nothing to light up, and every English place reports "England" (#1974).
|
|
* The builder ships GB at ADM2 for exactly that reason.
|
|
*
|
|
* This is the guard that would have caught it when it landed in 3.1.0: four
|
|
* features for a whole country is not a region layer, it is a country layer
|
|
* with extra steps.
|
|
*/
|
|
it('ATLAS-BUNDLE-004 — Great Britain ships below the constituent-country level (#1974)', () => {
|
|
const gb = regions('GB');
|
|
expect(gb.length, 'GB must ship counties and boroughs, not the four nations').toBeGreaterThan(50);
|
|
expect(new Set(gb.map(r => r.properties.iso_3166_2)).size, 'GB region codes must be unique').toBe(gb.length);
|
|
});
|
|
|
|
it('ATLAS-BUNDLE-005 — the London boroughs are in it (#1974)', () => {
|
|
const names = new Set(
|
|
(features as unknown as { properties: { iso_a2: string | null; name?: string } }[])
|
|
.filter(f => f.properties.iso_a2 === 'GB')
|
|
.map(f => (f.properties.name || '').toLowerCase()),
|
|
);
|
|
for (const borough of ['camden', 'westminster', 'hackney', 'islington']) {
|
|
expect(names.has(borough), `${borough} should be a region of its own`).toBe(true);
|
|
}
|
|
});
|
|
});
|