Search code examples
overpass-api

Query all places and their streets


I want to build a registry of places (city, town, village) and their street names (limited to germany). My first attempt was to get all places and then query for the streets like this:

[out:json];
area[name="Bremen"];
node[place~"city|town|village"](area);
out;

But this will not work because names are not unique. E.g. there is a town and also a village named Bremen (and even some in USA) and you can't mix that up if you want proper results. Next I tried this:

[out:json];

// Find all nodes representing cities
area[name="Bremen"]->.a;
node(area.germany)[place~"city|town|village"];

// For each city node, find the streets within a certain radius
foreach {
    // Query for streets within a radius of 5000 meters from each city node
    way(around:5000)[highway][name];
    /*added by auto repair*/
    (._;>;);
    /*end of auto repair*/
    out;
}

But this just gives me streets in the radius even if they do not belong to the city. Should I go with the first attempt and post-process the data (e.g. cluster the nodes for cities with ambiguous names geographically)? Is there a better way or query to archive it?


Solution

  • I was able to get the streets by post code with this overpass query. Important is the filter by ISO3166, which makes the postal code filter unique.

    [out:csv(name;false)];
    area[postal_code="57290"]->.zip;
    area["ISO3166-1"="DE"][boundary=administrative]->.state;
    way(area.zip)(area.state)[highway][name];
    out;