Skip to content

Missing admin_level=2 boundaries for some countries (US, France) — no country_code returned #53

Closed

Description

@altmarksch

Missing admin_level=2 boundaries for some countries (US, France) — no country_code returned

Repo: https://github.com/dedicatedcode/paikka/issues/new


Summary

After a successful self-hosted import, reverse geocoding returns an empty
country_code for places in some countries because the admin_level=2
(country) entry is absent from the returned hierarchy. Other countries in the
same import, from the same continental extract, resolve correctly.

Environment

  • Paikka 1.1.7 (dedicatedcode/paikka:latest), Docker
  • Import completed 2026-08-05, gridLevel: 12, ~100 GB datastore
  • Source: 9 Geofabrik continental extracts — europe, north-america, asia,
    south-america, australia-oceania, central-america, plus
    africa/south-africa, africa/mozambique, africa/swaziland
  • Each filtered with the bundled prepare script, then a single
    import --memory 14g --threads 6 run over all nine files

Reproduction

curl 'http://localhost:8080/api/v1/reverse?lat=45.5152&lon=-122.6784&limit=1'   # Portland, US
curl 'http://localhost:8080/api/v1/reverse?lat=48.8700&lon=2.3000&limit=1'      # Paris, FR
curl 'http://localhost:8080/api/v1/reverse?lat=49.2827&lon=-123.1207&limit=1'   # Vancouver, CA

Actual results

Portland, United States — hierarchy begins at level 4, no country entry:

level  4  Oregon                       cc=[]
level  6  Multnomah County             cc=[]
level  8  Portland                     cc=[]
level 10  Downtown                     cc=[]

Paris, France — hierarchy begins at level 3, no country entry:

level  3  France métropolitaine        cc=[]
level  4  Île-de-France                cc=[]
level  6  Paris                        cc=[]
level  8  Paris                        cc=[]
level 10  Quartier des Champs-Élysées  cc=[]

Vancouver, Canada — correct, level 2 present:

level  2  Canada                       cc=[CA]
level  4  British Columbia             cc=[]
level  6  Metro Vancouver RD           cc=[]
level  8  Vancouver                    cc=[]

Mexico (MX) and the United Kingdom (GB) also resolve correctly.

Note that Canada, Mexico and the United States all come from the same
north-america extract
, so this is not a case of a country being absent from
the source data.

Expected

hierarchy should include an admin_level=2 entry with a populated
country_code for all countries present in the imported extracts.

Impact

In a dataset of 3,390 places spanning six continents, 2,448 (72%) have an empty
country_code
— almost entirely US and French locations. Downstream consumers
such as Reitti store this field per place, so it stays blank there too.

Suspected cause

Both /usr/bin/prepare and /usr/bin/prepare-boundaries invoke:

osmium tags-filter "$INPUT_FILE" ... r/boundary=administrative -o "$OUTPUT_FILE"

without the -r / --add-referenced flag. Matching relations are retained, but
the member ways (and their nodes) that define the boundary geometry are not,
unless they happen to match another filter expression. Simple boundaries may
survive incidentally; large multipolygon relations such as the United States
(relation 148838) and France cannot be reassembled.

Adding -r would retain referenced members, at the cost of a larger
intermediate file.

Additional observation

The GeoJSON payload does contain a human-readable country name — e.g.
"country": "New Zealand / Aotearoa" — even where country_code is empty. If
the ISO code cannot always be derived, exposing that string consistently would
still let consumers fall back to something meaningful.

Related feature request

Publishing prepared exports for common region sets would help a lot of
self-hosters. The README notes that prepared data is designed to be portable to
lightweight machines, but building it currently requires a machine most people
don't have — this planet-scale import needed ~20 hours and 24 GB of RAM, and
took three attempts to get the heap and swap configuration right.

Activity

  1. dgraf-gh commented on Aug 5, 2026

    @dgraf-gh
    Contributor

    Hi @altmarksch,

    Thank you for the detailed report. I will check that out.

    Did you try them against geo.dedicatedcode.com? Just out of curiosity, could be related how the country pbf exports are handled. I normally only import the planet.pbf file.

    I tested it against https://geo.dedicatedcode.com/api/v1/reverse?lat=45.5152&lon=-122.6784&limit=1

    As you wrote:

    My theory is that during the import (maybe of the multi polygon nature) the admin_level 2 relation is not successfully matched against the poi. Or the other way around, we try to find all containing relations for a poi to connect them together.

    Having prepared exports somewhere hosted would be nice but I have no place right now. I already used up my cloudflare storage for the upcoming spatial coverage feature for reitti. Then there is the need to run multiple exports at once somewhere. Right now I do the planet (roughly once per month) on my home server and upload it. This takes around 12h plus 2h downloading and uploading the files.

  2. added a commit that references this issue on Aug 5, 2026
  3. added a commit that references this issue on Aug 5, 2026
  4. dgraf-gh commented on Aug 5, 2026

    @dgraf-gh
    Contributor

    Hi @altmarksch,

    I believe I fixed the issue. At least I could reproduce this with the monaco.pbf export. What happened during the monaco import was the following:

    • paikka imported https://www.openstreetmap.org/relation/90352
      • this is the shared border between france an monaco
      • note the admin_level = 2 but no country_code
      • paikka imported that as a boundary and created a polygon out of it
      • when a poi is imported, paikka checks if there is a surrounding polygon for it to build up the hierarchy
      • and it finds the 90352 instead of the monaco boundary
      • now that one is written into the hierarchy
      • later when the import creates the actual poi data for the database, it filters that out again

    I changed the code to strip out the boundaries. If you want to test that alongside with me, you can switch to the develop docker tag. I am currently started a new planet import, as soon as this is done and looks good, I will create a new version.

  5. dgraf-gh commented on Aug 6, 2026

    @dgraf-gh
    Contributor

    This did not help in resolving that issue. In parallel I fixed #55 maybe that could have been another reason why it did not find the hierarchy. Unfortunately I was to fast with my planet import so this did not made it in the build.

    I will verify if that helped, else I need to look further

  6. altmarksch commented on Aug 6, 2026

    @altmarksch
    Author
  7. dgraf-gh commented on Aug 9, 2026

    @dgraf-gh
    Contributor

    So, the import with the fixed boundaries finished but did not help with the resolution of the admin level 2.

    On my way to find the smallest region possible to reproduce this, these are the results by manually checking the latest import.

    URL Country Works
    https://geo.dedicatedcode.com/api/v1/reverse?lat=45.5152&lon=-122.6784 USA ❌
    https://geo.dedicatedcode.com/api/v1/reverse?lat=48.8700&lon=2.300 France ❌
    URL Country Works
    https://geo.dedicatedcode.com/api/v1/reverse?lat=50.85&lon=5.14 Belgium (52411) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=46.6299&lon=3.7614 France ❌
    https://geo.dedicatedcode.com/api/v1/reverse?lat=13.59&lon=1.41 Niger (192786) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=8.317&lon=-81.486 Panama (287668) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=64.130&lon=-21.813 Island (299133) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=53.08&lon=-7.56 Ireland (62273) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=47.23&lon=8.26 Suisse (51701) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=51.571&lon=10.898 Germany (51477) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=39.14&lon=22.21 Greece (192307) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=19.46&lon=-98.99 Mexico (114686) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=-43.595&lon=172.590 New Zealand ❌
    https://geo.dedicatedcode.com/api/v1/reverse?lat=-37.54&lon=175.47 New Zealand ❌
    https://geo.dedicatedcode.com/api/v1/reverse?lat=-46.22&lon=168.38 New Zealand ❌
    https://geo.dedicatedcode.com/api/v1/reverse?lat=-45.58&lon=170.27 New Zealand ❌
    https://geo.dedicatedcode.com/api/v1/reverse?lat=-37.02&lon=145.50 Australia (80500) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=37.580&lon=140.120 Japan (382313) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=33.953&lon=113.379 China (270056) ✔️
    https://geo.dedicatedcode.com/api/v1/reverse?lat=42.858&lon=23.395 Bulgaria (186382) ✔️

    So, from the first look:

    • if a country is missing, it seems like it is missing from all the pois
    • atm I need to check what the difference between working and non working countries are

    New Zealand:

  8. dgraf-gh commented on Aug 9, 2026

    @dgraf-gh
    Contributor

    So, the current working theory of the failure is that if affects every country which crosses the anitmeridian (180°E/W)
    The HierarchyCache breaks when calculating the boundaries of that.

  9. dgraf-gh commented on Aug 11, 2026

    @dgraf-gh
    Contributor

    Hi @altmarksch,

    that was the actual reason and is now fixed. I will issue a new version today.

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

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