Skip to content

Fill 678 missing city values, each cross-verified and sourced - #232

Merged
alexander-san merged 2 commits into
mwgg:masterfrom
thomasgobinfcmlabs:fill-missing-cities
Aug 16, 2026
Merged

alexander-san merged 2 commits into
mwgg:masterfrom
thomasgobinfcmlabs:fill-missing-cities

Conversation

@thomasgobinfcmlabs

@thomasgobinfcmlabs thomasgobinfcmlabs commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Fills the city field for 678 of the 853 entries that have an IATA code but no city.

Only previously-blank fields are touched — no existing value is modified, and no other field changes. The diff is 678 lines in airports.json.

Method

Nothing here comes from guesswork or from a model's memory. Three independent open datasets were combined to generate candidates, then every value was verified individually against a primary source:

source licence contributes
Wikidata P931 place served by transport hub CC0 primary signal
OurAirports municipality public domain corroboration
GeoNames gazetteer CC BY 4.0 confirms the name is a real settlement near the airport's coordinates
Wikipedia — per-airport verification

661 of the 678 values (97%) are backed by an English Wikipedia article, the remainder by Wikidata or an operator/government source. Every value has a verbatim supporting quote and a source URL recorded; happy to attach the full audit table if useful.

What city was taken to mean

The place an airport serves, not the municipality containing the runway. These differ often, and the existing data consistently prefers the former — so Rostock-Laage Airport gives Rostock, not Laage. Wikidata's P931 encodes exactly this, which is why it was weighted above P131 (located in the administrative territorial entity).

House style

Matched to the existing file rather than assumed:

  • ASCII, diacritics stripped — only 15 of the 26,433 already-populated values contain any non-ASCII character, and the file strips rather than expands (Bodø→Bodo, Arnavutköy→Arnavutkoy), so Svolvær→Svolvaer.
  • Common English name where one exists (Munich, Cologne).
  • Serialised with indent=4, sorted by ICAO — byte-identical to what .github/scripts/sort.py produces, so the sort workflow is a no-op on merge.

.github/scripts/valid_json.py passes.

Deliberately left blank

175 entries are not filled, rather than guessed:

  • ~136 remote Australian pastoral stations and mine sites (Delta Downs, Durham Downs, Mount Keith) that serve no settlement.
  • Airstrips documented only by directory sites that republish these same open datasets — citing those would be circular, not verification.
  • A handful where two sources disagreed and nothing authoritative settled it.

Two further entries were dropped late for citing an article about a different airport, and a small number for resting on aggregator sources. Accuracy was prioritised over coverage throughout.

Sample

ICAO IATA Airport City
AGGM MUA Munda Airport Munda
AYMN MDU Mendi Airport Mendi
NZTU TIU Timaru Airport Timaru
YBDV BVI Birdsville Airport Birdsville
RJAW IWO Iwo Jima Airport Iwo To
DAOV MUW Ghriss Airport Mascara

Changes after review

After @alexander-san's review, 41 values went back to blank. Filled drops from 719 to 678, blank rises from 134 to 175.

  • 39 pastoral stations, mine sites, a gas plant, two resorts and a landform, so the "serves no settlement" exclusion now covers the whole category instead of half of it. YMMI to Leonora stays.
  • YLZI Lizard Island, where the evidence named where the service flies from rather than the place the airport serves.
  • OIBH, where the OIBH / OI20 / IAQ identity conflict also affects name, state, lat and lon. That needs its own issue rather than a city-fill PR.

Populates the `city` field for 719 of the 853 entries that have an IATA code
but no city. Only previously-blank fields are touched; no existing value is
modified.

Method
------
Three independent open datasets were combined, then every value was verified
individually against a primary source:

  * Wikidata P931 "place served by transport hub" (CC0) - the property whose
    meaning matches this field exactly
  * OurAirports `municipality` (public domain)
  * GeoNames gazetteer (CC BY 4.0), used to confirm each candidate name is a
    real settlement near the airport's own coordinates

96% of the values are backed by an English Wikipedia article, the rest by
Wikidata or an operator/government source. Every value carries a verbatim
supporting quote and a source URL in an audit trail.

`city` is taken to mean the place an airport *serves*, not the municipality
containing the runway - the two differ often (Rostock-Laage serves Rostock,
not Laage) and this dataset consistently wants the former.

Values follow the file's existing conventions: ASCII with diacritics stripped
(Svolvaer, not Svolvær), and the common English name where one exists.

Not filled
----------
127 entries are deliberately left blank rather than guessed. Most are remote
Australian pastoral stations and mine sites that serve no settlement, plus a
few airstrips documented only by directory sites that republish these same
open datasets - citing those would be circular, not verification.
@thomasgobinfcmlabs

Copy link
Copy Markdown
Contributor Author

Hi @alexander-san, when you have time, could you take a look at this PR?
I've attached the per-entry audit table with the source URL and supporting evidence for each of the 719 filled entries. Thanks!

sources_audit.csv

@alexander-san

alexander-san commented Aug 16, 2026 •

Copy link
Copy Markdown
Collaborator

First of big thanks and this huge PR took a moment to review.

Three things I'd like changed @thomasgobinfcmlabs before merge. All of them are cases where the PR's own stated rules point somewhere other than the value that landed.

1. The pastoral-station / mine-site exclusion is applied to about half the category.

The description says ~96 remote stations and mine sites were deliberately left blank, naming Delta Downs, Durham Downs and Mount Keith. But of the 14 Australian * Downs cattle-station airports that have an IATA code and no city, seven are filled and seven are blank:

filled blank
Abingdon Downs, Alton Downs, Augustus Downs, Austral Downs, Bedford Downs, Brunette Downs, Marion Downs Barkly Downs, Delta Downs, Davenport Downs, Durham Downs, Gregory Downs, Macdonald Downs, Victoria River Downs

Station-named airports split the same way — Myroodan Station and Roy Hill Station filled, Christmas Creek Station, Mount Sanford Station, Theda Station, Vanrook Station and others blank. Mine sites too: Mount Keith (nickel mine) blank, The Monument filled as Phosphate Hill (phosphate mine), Murrin Murrin filled as Leonora.

The audit notes concede the exclusion criterion is met on many of these — "no town center" (YAUV), "no town exists at the site" (YTST, where the value is Anjo Peninsula, a landform), "industrial facility (gas plant) not a city or town" (YLLE), "Remote pastoral station with zero population" (YMUP). About 29 rows fall in this category.

Either rule is defensible; what I'd like is one rule. Since the description already commits to leaving these blank, blanking the ~29 is the smaller change and keeps the PR's stated policy true. YMMI → Leonora is the one I'd keep either way — the note reasons it through properly (Murrin Murrin is a ghost town, Leonora is the nearest real town), and if that's the preferred treatment then it should be applied to the whole category instead, which is a much bigger diff.

2. YLZI Lizard Island → Cairns rests on a misread sentence.

The audit's evidence field is "It is served from Cairns by Hinterland Aviation" — that makes Cairns the origin of the service, not the place the airport serves. Wikipedia's infobox gives location = Lizard Island, Queensland, operator Lizard Island Resort Pty Ltd, and names no city served. At 253 km it's the only real distance outlier among all 719 values. This is the same "serves no settlement" case as the resort and station strips, so blank.

3. OIBH — the identity conflict is bigger than the city field.

The audit is transparent here, citing Bahregan_Airport and noting "Bastak... is outdated data", so this was a deliberate call rather than a slip. But two things give me pause. OurAirports carries these as separate airports — OI20 "Bahregan Airport" at 29.84/50.27 with iata=IAQ, and OIBH "Bastak Airport" at 27.21/54.32 with no IATA — so "OIBH/IAQ are current for Bahregan" is contested rather than settled. And if the row really is Bahregan, then name, state, lat and lon are all wrong too, not just city. Filling only city leaves:

"OIBH": { "iata": "IAQ", "name": "Bastak Airport", "city": "Emam Hasan",
          "state": "Hormozgan", "lat": 27.2127, "lon": 54.3186 }

a row whose city is 490 km from its own coordinates and in a different province than its own state. Before this PR the row was at least self-consistently "Bastak". I'd revert it to blank here and open a separate issue to correct the whole record — that keeps this PR's "only previously-blank fields are touched" scope intact and gives the identity question the space it needs.

@thomasgobinfcmlabs thomasgobinfcmlabs changed the title Fill 719 missing city values, each cross-verified and sourced Fill 678 missing city values, each cross-verified and sourced Aug 16, 2026
@thomasgobinfcmlabs

thomasgobinfcmlabs commented Aug 16, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for going through it in that much detail. All three are done.

Counts go from 719 filled / 134 blank to 678 / 175. Every ICAO that went back to blank is listed below, so the audit table I attached earlier still lines up once you drop those 41 rows. Happy to upload a regenerated one if that's easier. It's a follow-up commit rather than a force-push, so your comments stay where you put them.

1. Stations and mine sites

Rather than work from the 29, I re-derived the category. Every Australian filled row got checked against its GeoNames feature code, then anything ambiguous against Wikipedia. The rule:

Blank if the served place is a pastoral station or homestead, a mine, a gas or industrial plant, a resort, or a landform. Keep if it's a named settlement, even a tiny one.

That gives 39 rows, ten more than your estimate.

Stations and homesteads (31): YABI, YADS, YAGD, YAMM, YANL, YARY, YAUS, YAUV, YBDF, YBLC, YBRU, YBWM, YCWY, YDRD, YGIB, YGLE, YHBY, YHDY, YIKM, YKCS, YLAH, YMNY, YMUP, YMWT, YMWX, YMYR, YMYT, YRYH, YSPV, YWDL, YWMP.

Two of those need a word of explanation. Balcanoona (YBLC) is a former pastoral station that now serves as the headquarters for Vulkathunha-Gammon Ranges National Park. Lawn Hill (YLAH) is a gazetted locality with 63 people at the 2021 census, but the airstrip sits at the Lawn Hill homestead, which Wikipedia lists as one of several homesteads inside that locality.

Mines, gas and industrial (5): YBRY (Barimunya, next to the Yandi mine), YLLE (Ballera gas plant), YOOM (Moomba, Santos' restricted-access gas facility), YTMO (Phosphate Hill), YWIT (Wittenoom).

Wittenoom is the odd one there, since it was a town rather than a mine site. It was degazetted in 2007, the 2021 census recorded nobody living there, and the airport closed back in 1993, so I've treated it as a mine site whose town is gone.

Resorts and a landform (3): YCOO (Cooinda lodge in Kakadu), YKCA (Kings Canyon resort in Watarrka National Park), YTST (Anjo Peninsula). YLZI is the same case, but it's under point 2 below since you raised it separately.

YMMI to Leonora stays, as you asked.

Two of the ten extra rows are really your point rather than mine. YKCS and YKCA were both filled as Petermann, which is the containing locality, so P131 semantics, when the description commits to P931 "place served" over P131. YKCS is the Kings Creek Station airstrip, so it sits with the stations, and it's 35 km from Petermann anyway. YKCA serves the Kings Canyon resort, so it sits with the resorts.

Your list of 14 * Downs airports with an IATA code and no city checks out exactly against master, and all 14 are blank now. Running the same sweep over Station, Homestead and Mine names gives 11 airports, also all blank now.

There are still eight Australian rows with Downs, Station or Mine in the airport name that carry a city: YCOD, YEVA, YGDN, YGRM, YKIR, YMHU, YMUC, YNUD (seven of them with an IATA code). All eight already had those values on master, so this PR doesn't touch them, and folding them in would break the "only previously-blank fields are touched" scope. Worth a separate issue if you want that category consistent across the whole file, and I'm happy to open one.

Three I kept that you might want blank too

Each is a named settlement rather than a station, mine or resort, which is the only reason it survived the rule. All three have little or no recorded population, so I'd rather flag them than quietly keep them:

  • YBEO Betoota. A ghost town inside the locality of Birdsville, surveyed in 1887, with a hotel and a racetrack and no recorded population.
  • YFRT Forrest. A former railway settlement on the Nullarbor that grew around the aerodrome. The 2021 census records "no people or a very low population".
  • YRRB Roper Bar. Wikipedia calls it a settlement on the Roper River with a store, but gives no population.

Happy to blank any or all of them.

For contrast, the small Australian ones I'm confident about: YLRA Laura (133 at the 2021 census), YGNV Greenvale (192), YBIL Billiluna (150 at 2016). Those are towns and communities rather than stations.

2. YLZI

Agreed, and good catch. The evidence names where the service flies from, not what the airport serves. Blanked.

3. OIBH

Agreed. Blanked, so the row is back to being self-consistently Bastak:

"OIBH": { "iata": "IAQ", "name": "Bastak Airport", "city": "", "state": "Hormozgan",
          "lat": 27.2127, "lon": 54.3186 }

I'll open a separate issue for the OIBH / OI20 / IAQ conflict covering name, state, lat and lon, unless you'd rather raise it yourself.

Checks

Against master after the change:

  • 678 entries differ, all of them blank-to-filled city changes
  • no non-blank city changed, no other field changed, same key set
  • sort.py output is byte-identical to the committed file, valid_json.py passes
  • the audit table lines up 1:1 with the 678 changed entries

@alexander-san
alexander-san merged commit 004e134 into mwgg:master Aug 16, 2026
1 check passed
@alexander-san

Copy link
Copy Markdown
Collaborator

I'll open a separate issue for the OIBH / OI20 / IAQ conflict covering name, state, lat and lon

Would be much appreciated @thomasgobinfcmlabs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants