Curate two Maltese localities misfiled under Mali - #13
Conversation
Who's On First ships duplicates of Mellieħa (101912869) and Naxxar
(101846471) inside whosonfirst-data-admin-ml. Each carries Malta's
coordinates, name and population - Mellieħa's population is 5976, exactly
the Maltese record's - but wof:country ML, wof:parent_id -1 and a
hierarchy containing nothing but Mali's country id. Between them they own
three cells over the real towns, so those coordinates reverse geocode
into Mali while forward search returns the Maltese ids, and the two can
no longer be grouped.
Curation is the last resort here, so the rationale records the four
generic rules that were tried against a world build and the measured
reason each was rejected: distance from the nearest same-country
neighbour (useless - the misfiled records sit beside each other, 1 km
apart - and unsafe, since 973 legitimate places are more than 100 km from
one); a missing admin1 parent (only 20 localities world-wide, but they
include Lilongwe, Banjul, Honiara and Tarawa); validating the country tag
against the country polygon holding the centroid (impossible - the admin
repositories ship no country records at all, 0 in Mali's 15,060 files and
0 in Malta's 395); and cross-country name-and-population duplicate
matching (narrow enough at 14 pairs world-wide, but it misses this record
because "ħ" has no Unicode decomposition to "h").
The entry needed two small, guarded additions to the overlay format:
- "absorbForeignTagged" lets an absorb id carry another country's tag,
which is the whole defect. It is opt-in per entry so it can never be
the result of a typo'd id, and the target is never exempt - a file
can still only produce labels for the country it is named for.
- "probes[].country" lets a guard probe name the country its expected
label belongs to, so the entry can assert that Mali itself is
untouched. Verification resolves the country from the database, so a
same-named place across the border cannot satisfy the guard.
Both are covered red-green. Two Mali-tagged records inside Malta's
bounding box are deliberately left out, and the entries say so: San
Giljan owns no cells, and Xghajra's population of 837 does not clear the
build's floor.
Verified strictly against a Mali+Malta build with --verify and no
--skip-unresolvable: 6 probes passed, 0 skipped, 0 failed, 3 cells
relabeled.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 261de9dc81
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The country check short-circuited on `!probe.country`, so it only ever
ran for probes that spelled a country out. An omitted "country" is
documented to mean the entry's own country, and that default was never
enforced: every probe written without one - including all six in gt.json
- could be satisfied by a same-named place across a border, which is the
exact confusion the field was added to prevent.
The comparison now runs unconditionally.
Case: no mismatch to reconcile. Entry and probe countries are validated
as /^[A-Z]{2}$/ and the files declare "GT"/"MT"; placeCountry() reads
country_id, which the builds store uppercase, and uppercases it anyway.
Both sides are normalised explicitly so the comparison stays correct if
either validator is ever relaxed.
Null: fails closed. compact_places.country_id is NOT NULL and no built
database has an empty one, so this can only mean the reverse result
carried no id - and a verification tool must never pass a probe it was
unable to check. Pinned by its own spec, because nothing else was
holding that decision in place.
The failure hint names the resolved country and, for an unqualified
probe, says probes default to the entry's country, so an author who
meant to cross a border knows to add the field rather than guessing.
Verified strictly over both curation files against a gt+ml+mt build:
12 probes passed, 0 skipped, 0 failed, 7 cells relabeled. Forcing every
resolved country to a wrong value turns all of them red - including the
six unqualified gt.json probes - which is what proves they were checked
rather than skipped.
|
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Who's On First ships duplicates of two Maltese localities inside
whosonfirst-data-admin-ml, the Mali repository:MLwof:parent_id: -1MLwof:parent_id: -1Both carry Malta's coordinates, name and population — Mellieħa's 5976 is exactly the Maltese record's — with
iso:country: MLand a hierarchy containing nothing but Mali's country id. They are misfiled records, not places in Mali.Why it matters beyond one town
Between them they own three precision-5 cells over the real towns, so those coordinates reverse geocode into Mali while forward search returns the Maltese ids. In the app that means a resident and someone selecting the same town from search receive different
city_keyvalues and cannot be grouped — the town silently splits in two.Why curation rather than a build rule
Curation is the last resort in this repo, so each generic rule was tried against a world build and measured before falling back:
MLneighbour is 1 km. Also unsafe: 973 places world-wide are >100 km from a same-country neighbour and are legitimate (Svalbard, Bonaire, French Polynesia).whosonfirst-data-admin-*ships no country records: 0 in Mali's 15,060 files, 0 in Malta's 395. Needs a new data dependency.ħhas no Unicode decomposition toh, so the names never normalise equal.That evidence lives in the entry's own
rationale, so a future contributor does not have to re-litigate it.Format additions
Two small, guarded extensions the entry needed, both covered red-green:
entries[].absorbForeignTagged— lets anabsorbid carry another country's tag, which is the defect. Opt-in per entry so it can never result from a typo'd id, andintois never exempt: a file can still only ever produce labels for the country it is named for.probes[].country— lets a guard probe name the country its expected label belongs to, so the entry can assert Mali itself is untouched. Verification resolves the country from the database, so a same-named place across the border cannot satisfy the guard.Scope
Two further Mali-tagged records inside Malta's bounding box are deliberately left out, and the entries say so: San Giljan (101752435) owns no cells so it can produce no wrong answer, and Xghajra (101846463) has a population of 837 and does not clear the build's floor. Recorded rather than omitted, so a later build that gives either of them cells has a note to act on.
Verification
Strict —
--verify, no--skip-unresolvable— against a Mali + Malta build at the world configuration:Full suite green: 227 specs, 0 failures.