Skip to content

build-stats under-reports settlements reaching the country-named region #1

Description

@navjottomer

What happens

When containment cannot be resolved for a settlement, the pipeline attaches it to the country node, and that country node is then published as one of the country's own region records. The result is a division named after the country, sitting inside it:

{"type":"region","id":668,"name":"India","slug":"india","iso_3166_2":null,
 "place_type":"Q6256","latitude":"22.800000","longitude":"83.000000",
 "population":1326093247}

id 668 is the country record's own id. place_type is Q6256 (country) or, more often, Q3624078 (sovereign state) — never an admin1 type. iso_3166_2 is always null.

Scale

Measured across 2026-08-15T0426Z, every country's data/<CC>.ndjson:

  • 249 of 255 countries publish a region whose id equals the country's id
  • 57,250 settlements are attached to one — 3.4% of the dataset

Worst affected:

settlements cc region name place_type
23,193 LT Lithuania Q3624078
4,220 FR France Q3624078
3,338 RU Russia Q3624078
3,149 DE Germany Q3624078
1,010 MA Morocco Q41614
971 UA Ukraine Q3624078
966 IN India Q6256

Lithuania is effectively unusable for a picker. 23,193 of its 23,404 settlements (99%) are in the bucket; its ten real counties hold 211 between them:

23193  —        Lithuania      <-- the country posing as a region
  114  LT-VL    Vilnius County
   27  LT-KU    Kaunas County
   22  LT-SA    Siauliai County
   ...
    0  LT-AL    Alytus County

Why it is a correctness problem, not just a tidiness one

The affected settlements are real and their coordinates are fine — they are simply filed under the wrong parent. For India's 966, plotting them against state bounding boxes puts them all over the country: ~125 in Maharashtra, ~59 in Rajasthan, ~57 in Uttar Pradesh, ~31 in West Bengal, and roughly 490 in southern states. Agra, for instance, appears in the bucket at 27.1601,77.9922 while a separate Agra record sits correctly under IN-UP.

So a consumer asking "which division is this settlement in?" gets an answer that is wrong but well-formed — the failure mode LIMITATIONS.md is otherwise careful to avoid.

It also weakens a stated guarantee. README.md says no region contains the same name twice; it does not say a region may be its country, and a consumer reasonably reads type: region as meaning an administrative division.

Reproducing

python3 - <<'PY'
import json, collections
cid=None; regions={}; counts=collections.Counter()
for line in open('data/LT.ndjson', encoding='utf-8'):
    r=json.loads(line); t=r.get('type')
    if t=='country': cid=r['id']
    elif t=='region': regions[r['id']]=r
    elif t=='settlement': counts[r.get('admin1_id')]+=1
print('country id', cid, '| settlements attached to it:', counts[cid])
print('is it also published as a region?', cid in regions)
PY

Suggested directions

Not prescriptive — you know the containment code. Options that seem open:

  1. Do not emit a region whose id is the country's id. Settlements attached to it become genuinely unparented, which at least surfaces the gap instead of hiding it.
  2. Emit it, but not as type: region — a distinct type, or an unassigned: true flag, so consumers can tell a real division from a fallback.
  3. Improve the fallback itself — for the affected rows the coordinates are present and correct, so a point-in-polygon or nearest-admin1 pass would place most of them. Lithuania suggests the admin1 relation is simply not being picked up for that country at all, which may be a per-country mapping gap rather than a general algorithm problem.

Happy to help with whichever direction you prefer.

Interim handling downstream

placedb.org, which serves these releases, currently relabels the bucket as "name": "Division not recorded" with "unassigned": true, strips the country's population and centroid off it, sorts it last, and excludes it from autocomplete suggestions while keeping its settlements searchable. That is presentation only — it does not attempt to reassign anything — and it will be removed once a corrected release lands.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions