mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
fix(voice): treat a Zone as retired only in Nepal
Every name ending in "Zone" was kept without a level and refused as a retired administrative identity. That is right for Nepal, which replaced its zones in 2015, but zones are current units elsewhere: Ethiopia's "Gamo Zone" was refused. The selector now keeps the verified level unless display_name places the zone in Nepal or names no country, and the client no longer reads "Zone" as a retired level when the source verified one.
This commit is contained in:
1 parent
682427ef1d
commit
451be8e3b7
4 files changed
+73
-2
No files matched your search
@@ -274,11 +274,27 @@ function selectedAdminIdentity(kind, row) {
|
|||||||
);
|
);
|
||||||
if (contradictory) return null;
|
if (contradictory) return null;
|
||||||
const adminArea = authoritativeAdminArea.slice(0, 160);
|
const adminArea = authoritativeAdminArea.slice(0, 160);
|
||||||
if (nameLevel === 'retired') return { adminArea };
|
if (nameLevel === 'retired') {
|
||||||
|
// Nepal replaced its zones in 2015, but zones are current units elsewhere
|
||||||
|
// (Ethiopia). Without a country the name stays retired.
|
||||||
|
if (!zoneIsCurrentIn(row)) return { adminArea };
|
||||||
|
return { adminArea, adminLevel };
|
||||||
|
}
|
||||||
if (nameLevel && nameLevel !== adminLevel) return null;
|
if (nameLevel && nameLevel !== adminLevel) return null;
|
||||||
return { adminArea, adminLevel };
|
return { adminArea, adminLevel };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether the row names a country (last display_name part) other than Nepal. */
|
||||||
|
function zoneIsCurrentIn(row) {
|
||||||
|
const country = String(row?.display_name || '')
|
||||||
|
.split(',')
|
||||||
|
.slice(1)
|
||||||
|
.pop()
|
||||||
|
?.trim()
|
||||||
|
.toLocaleLowerCase();
|
||||||
|
return Boolean(country) && country !== 'nepal';
|
||||||
|
}
|
||||||
|
|
||||||
/** Whether supplied administrative evidence contradicts the accepted identity. */
|
/** Whether supplied administrative evidence contradicts the accepted identity. */
|
||||||
function adminLevelFits(kind, row) {
|
function adminLevelFits(kind, row) {
|
||||||
const evidence = ADMIN_EVIDENCE[kind];
|
const evidence = ADMIN_EVIDENCE[kind];
|
||||||
|
|||||||
@@ -853,6 +853,34 @@ test('admin identity comes only from unambiguous evidence on the selected row',
|
|||||||
assert.equal('adminLevel' in retiredPrefix, false);
|
assert.equal('adminLevel' in retiredPrefix, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('a Zone is retired only in Nepal, where zones were replaced', () => {
|
||||||
|
const current = selectOutlineResult(
|
||||||
|
[
|
||||||
|
boundary({
|
||||||
|
name: 'Gamo Zone',
|
||||||
|
addresstype: 'county',
|
||||||
|
display_name: 'Gamo Zone, South Ethiopia Regional State, Ethiopia',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{ kind: 'admin', query: 'Gamo Zone' },
|
||||||
|
).outline;
|
||||||
|
assert.equal(current.adminArea, 'Gamo Zone');
|
||||||
|
assert.equal(current.adminLevel, 'admin2');
|
||||||
|
|
||||||
|
const retired = selectOutlineResult(
|
||||||
|
[
|
||||||
|
boundary({
|
||||||
|
name: 'Bagmati Zone',
|
||||||
|
addresstype: 'state',
|
||||||
|
display_name: 'Bagmati Zone, Nepal',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
{ kind: 'admin', query: 'Bagmati Zone' },
|
||||||
|
).outline;
|
||||||
|
assert.equal(retired.adminArea, 'Bagmati Zone');
|
||||||
|
assert.equal('adminLevel' in retired, false);
|
||||||
|
});
|
||||||
|
|
||||||
test('admin identity validates the full name before display truncation', () => {
|
test('admin identity validates the full name before display truncation', () => {
|
||||||
const longValidName = `Province of ${'Example '.repeat(24)}`.trim();
|
const longValidName = `Province of ${'Example '.repeat(24)}`.trim();
|
||||||
const valid = selectOutlineResult(
|
const valid = selectOutlineResult(
|
||||||
|
|||||||
@@ -270,6 +270,12 @@ export function createVoiceAreas({
|
|||||||
const sourceAdmin = administrativeIdentity(sourceIdentity);
|
const sourceAdmin = administrativeIdentity(sourceIdentity);
|
||||||
const primaryAdmin = administrativeIdentity(primaryLabel);
|
const primaryAdmin = administrativeIdentity(primaryLabel);
|
||||||
const requestedAdmin = administrativeIdentity(requestedLabel);
|
const requestedAdmin = administrativeIdentity(requestedLabel);
|
||||||
|
// The server leaves a Zone without a level only where zones were retired
|
||||||
|
// (Nepal). A verified level means a current zone, so "Zone" claims no level.
|
||||||
|
if (sourceLevel && sourceAdmin.level === 'retired') {
|
||||||
|
for (const admin of [sourceAdmin, primaryAdmin, requestedAdmin])
|
||||||
|
if (admin.level === 'retired') admin.level = null;
|
||||||
|
}
|
||||||
const sourceClaimsAdministrative = Boolean(
|
const sourceClaimsAdministrative = Boolean(
|
||||||
administrativeRequest ||
|
administrativeRequest ||
|
||||||
administrativeLabel ||
|
administrativeLabel ||
|
||||||
|
|||||||
@@ -30,12 +30,13 @@ function fakeLadder({
|
|||||||
calls = [],
|
calls = [],
|
||||||
delay = null,
|
delay = null,
|
||||||
label = 'Bagmati Province',
|
label = 'Bagmati Province',
|
||||||
|
match = /bagmati/i,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
return {
|
return {
|
||||||
calls,
|
calls,
|
||||||
async resolveAnnotationTarget(request) {
|
async resolveAnnotationTarget(request) {
|
||||||
calls.push(request);
|
calls.push(request);
|
||||||
if (!/bagmati/i.test(request.target)) return null;
|
if (!match.test(request.target)) return null;
|
||||||
return {
|
return {
|
||||||
lat: 27.7,
|
lat: 27.7,
|
||||||
lon: 85.3,
|
lon: 85.3,
|
||||||
@@ -391,6 +392,26 @@ test('a verified province accepts a bare query with a separate level', async ()
|
|||||||
assert.equal(retired.areas.store.size, 0);
|
assert.equal(retired.areas.store.size, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('a current Zone the source verified is not refused as retired', async () => {
|
||||||
|
const gamo = makeAreas({
|
||||||
|
annotationResolver: fakeLadder({
|
||||||
|
label: 'Gamo Zone',
|
||||||
|
match: /gamo/i,
|
||||||
|
outline: {
|
||||||
|
ring: BAGMATI_POLYGONS[0][0],
|
||||||
|
polygons: BAGMATI_POLYGONS,
|
||||||
|
adminArea: 'Gamo Zone',
|
||||||
|
adminLevel: 'admin2',
|
||||||
|
synthesized: false,
|
||||||
|
outlineSource: 'nominatim',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const result = await gamo.areas.resolveAreaAction({ query: 'Gamo Zone' });
|
||||||
|
assert.equal(result.ok, true, result.error);
|
||||||
|
assert.equal(gamo.areas.store.size, 1);
|
||||||
|
});
|
||||||
|
|
||||||
test('a place no outline source can trace is refused, not guessed', async () => {
|
test('a place no outline source can trace is refused, not guessed', async () => {
|
||||||
const miss = makeAreas({
|
const miss = makeAreas({
|
||||||
annotationResolver: fakeLadder({ outline: null }),
|
annotationResolver: fakeLadder({ outline: null }),
|
||||||
|
|||||||
Reference in new issue
Block a user