mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
fix(atlas): correct Guangdong Province name in region bundle
This commit is contained in:
Binary file not shown.
@@ -180,7 +180,11 @@ function normalizeAdm1(geo, a3, countryName) {
|
||||
return code
|
||||
}
|
||||
return geo.features.map(f => {
|
||||
const name = f.properties?.shapeName || ''
|
||||
let name = f.properties?.shapeName || ''
|
||||
// geoBoundaries erroneously names Guangdong Province as "Guangzhou Province" (Guangzhou is the capital city).
|
||||
if (a3 === 'CHN' && name === 'Guangzhou Province') {
|
||||
name = 'Guangdong Province'
|
||||
}
|
||||
const geometry = quantizeGeometry(f.geometry, ADM1_DECIMALS)
|
||||
if (!geometry) return null
|
||||
// shapeISO is a real ISO 3166-2 code for most features, but geoBoundaries sometimes
|
||||
|
||||
@@ -4374,6 +4374,47 @@ function runMigrations(db: Database.Database): void {
|
||||
`);
|
||||
db.exec('CREATE INDEX IF NOT EXISTS idx_roadtrip_day_tracks_place ON roadtrip_day_tracks(place_id)');
|
||||
},
|
||||
/**
|
||||
* Rename the misnamed Guangdong Province (shipped as "Guangzhou Province").
|
||||
*
|
||||
* geoBoundaries labelled the whole province with the name of its capital, so
|
||||
* every row a user collected under it carries the wrong code. All three
|
||||
* tables that key on a region are moved over: the two per-user ones with an
|
||||
* UPDATE OR IGNORE plus a DELETE, because a user who already holds the
|
||||
* correct region would otherwise hit the unique index and keep a duplicate,
|
||||
* and place_regions with a plain UPDATE, because place_id is its primary key
|
||||
* and nothing there can collide.
|
||||
*
|
||||
* Appended LAST: the array is index-addressed against schema_version.
|
||||
*/
|
||||
() => {
|
||||
db.prepare(
|
||||
`UPDATE OR IGNORE visited_regions
|
||||
SET region_code = 'CN-GUANGDONGPROVINCE', region_name = 'Guangdong Province'
|
||||
WHERE UPPER(country_code) = 'CN' AND (region_code = 'CN-GUANGZHOUPROVINCE' OR region_name = 'Guangzhou Province')`,
|
||||
).run();
|
||||
db.prepare(
|
||||
`DELETE FROM visited_regions
|
||||
WHERE UPPER(country_code) = 'CN' AND (region_code = 'CN-GUANGZHOUPROVINCE' OR region_name = 'Guangzhou Province')`,
|
||||
).run();
|
||||
db.prepare(
|
||||
`UPDATE OR IGNORE place_regions
|
||||
SET region_code = 'CN-GUANGDONGPROVINCE', region_name = 'Guangdong Province'
|
||||
WHERE UPPER(country_code) = 'CN' AND (region_code = 'CN-GUANGZHOUPROVINCE' OR region_name = 'Guangzhou Province')`,
|
||||
).run();
|
||||
// hidden_regions is the other direction: it remembers which derived region
|
||||
// a user switched off. Left behind, the tombstone stops matching and the
|
||||
// region a user deliberately hid comes back.
|
||||
db.prepare(
|
||||
`UPDATE OR IGNORE hidden_regions
|
||||
SET region_code = 'CN-GUANGDONGPROVINCE'
|
||||
WHERE UPPER(country_code) = 'CN' AND region_code = 'CN-GUANGZHOUPROVINCE'`,
|
||||
).run();
|
||||
db.prepare(
|
||||
`DELETE FROM hidden_regions
|
||||
WHERE UPPER(country_code) = 'CN' AND region_code = 'CN-GUANGZHOUPROVINCE'`,
|
||||
).run();
|
||||
},
|
||||
];
|
||||
|
||||
if (currentVersion < migrations.length) {
|
||||
|
||||
@@ -135,6 +135,8 @@ const ALLOWED_DESTRUCTIVE: Record<string, string> = {
|
||||
'Atlas enclave fix: DELETE ... WHERE place_id IN (places inside specific enclave boxes) — invalidate stale region cache; re-resolved on next request.',
|
||||
'DELETE FROM visited_regions':
|
||||
'Atlas geoBoundaries swap (#1119): DELETE ... WHERE id = ? — after UPDATE OR IGNORE re-codes a manually-marked region to its current code, drop only the single leftover row whose UNIQUE(user_id, region_code) collision caused the update to be skipped (a duplicate of a region the user already has).',
|
||||
'DELETE FROM hidden_regions':
|
||||
'Guangdong rename (#2284): DELETE ... WHERE region_code = the retired CN-GUANGZHOUPROVINCE, run right after an UPDATE OR IGNORE re-codes the tombstone. Only a row the update had to skip survives to here, and it can only be skipped because UNIQUE(user_id, region_code) already holds the same tombstone under the correct code, so the user keeps the region hidden either way.',
|
||||
'DELETE FROM reservation_day_positions':
|
||||
'DELETE ... WHERE the row joins a reservation and a day sitting on different trips. The table has no trip_id and its two foreign keys only require the ids to exist, so a pair that never belonged together was storable; the writer scopes to the trip now and this clears what earlier builds allowed. Bounded by the join — a row whose reservation and day agree on their trip is untouched.',
|
||||
};
|
||||
|
||||
@@ -78,4 +78,14 @@ describe('Atlas admin1 region bundle (#1217)', () => {
|
||||
expect(names.has(borough), `${borough} should be a region of its own`).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it('ATLAS-BUNDLE-006 — China ships Guangdong Province, not Guangzhou Province', () => {
|
||||
const cn = (features as unknown as { properties: { iso_a2: string | null; name?: string; iso_3166_2: string } }[])
|
||||
.filter(f => f.properties.iso_a2 === 'CN');
|
||||
const names = cn.map(f => f.properties.name);
|
||||
expect(names).toContain('Guangdong Province');
|
||||
expect(names).not.toContain('Guangzhou Province');
|
||||
expect(cn.some(f => f.properties.iso_3166_2 === 'CN-GUANGDONGPROVINCE')).toBe(true);
|
||||
expect(cn.some(f => f.properties.iso_3166_2 === 'CN-GUANGZHOUPROVINCE')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user