0

I am trying to determine what the parent administrative area of any given area. The idea is that the closest parent is the administrative area with the highest/deepest admin_level that is shared as a parent by all points of the area boundary. Her the pseudo-algorithm I would like to be able to reproduce with the OSM API.

For a given area: For n in all nodes of its boundaries:

  • parents are the administrative area the node n lies in

potential_parent = intersect(list of parents)

unique_parent = parent in potential_parent where admin_level == min(admin_level)

Unfortunately I wasn't able to define the intersection of the different sets of parents for each node composing the boundary of the area of interest

Hehre is the solution I came up with:

rel(426391772) -> .obj;
.obj>;
is_in;
area._[boundary=administrative] -> .parents;
foreach .parents -> .shared(
  (.shared; - (.shared; - ._;););
);
out tags;

The for loop was my attempt to create the intersection set. But it doesn't return anything, while the .parents set is not empty. I suspect the difference is not working as I thing it would.

The rest of the request to filter the good area is as follow and seems to work:

area.shared[boundary=administrative](if:t["admin_level"] == max(t["admin_level"]));

If you have a better approach to this problem, I am happy to hear it.

Here is an example of my request with the turbo-overpass.

1

1 Answer 1

1

You could use the following approach, which assumes to have at least one node with tags inside your relation. It restricts the output to adminsitrative boundaries.

rel(1681994) -> .r;
.r map_to_area;
(node[~"."~"."](area); - (.r;way(r);node(w);););
is_in;
area._[boundary=administrative];
area._(if:number(t["admin_level"]) < number (r.set(t["admin_level"])));
area._(if:number(t["admin_level"]) == max(number(t["admin_level"])));
rel(pivot);
out;

NOTICE: This sort of query is very expensive. Don't use it in any app unless you're happy to hammer your own Overpass API instance!

In general, I highly recommend to do this sort of query with a GIS database, like Postgresql with Postgis instead.

7
  • I'm not sure what you are doing here, especially line 3 and 6. Can you explicit it? I will probably use it for a fairly big amount of data. Do you recommend to go for a cheaper top down approach, but requiring more numerous queries or tu use postgresql/postgis (that requires to download the dataset before doing queries right?)? Thank you for your answer.
    – Hobo Sheep
    Mar 5, 2019 at 11:28
  • 1
    Row 3: find node inside relation area, excluding the nodes of the relation itself. Row 4: determine areas for nodes of previous step. Row 5: Filter for boundary=administrative Row 6: Find all areas where admin_level is lower than the one in row 1.
    – mmd
    Mar 5, 2019 at 12:12
  • What exactly is your use case, and how many queries do you want to run? You could easily precalculate this data once in Postgis.
    – mmd
    Mar 5, 2019 at 12:13
  • Thank you for the details. I would like to build a database containing hierarchical relationships between administrative areas (e.g. city, children districts, children neighbourhoods...). It is sometimes contained in relation, but sometimes this relation is not given, therefore I would like to be able to extract it from the geographic information. This for entire countries. While this data can be found of official portals I really would like to use osm data to be able to do that for multiple countries and more easily add other osm data.
    – Hobo Sheep
    Mar 5, 2019 at 17:46
  • 1
    There are OSM projects out there doing just that: wambachers-osm.website/boundaries
    – mmd
    Mar 5, 2019 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.