Liste aller places als CSV mit Land

Hallo,

ich versuche gerade mit einer Overpass-Abfrage eine Liste von Städten als CSV auszugeben. Zu den Städten hätte ich gerne das jeweilige Länderkürzel ausgegeben (ISO3166-1-Tag des umschließenden Länderpolygons).

Kann mir jemand mit Overpass-Kenntnissen helfen, die Abfrage anzupassen?

Viele Grüße
dktue

Leider habe ich keine Lösung, eher noch mehr Fragen:

  1. Da die OSM-Relationen (am Beispiel Rixheim) keinen Ländercode enthalten, ist Deine Aufgabenstellung m.M.n nicht direkt lösbar.
  2. Nominatim hätte place=country, aber das sehe ich in OSM nicht. Warum? Deine Overpass-Query habe ich um die Spalte place:country ergänzt, die bleibt immer leer … Warum?
  3. Ein Umweg könnte die Overpass-Ergänzung wikipedia sein, aus der Spalte könnte man die ersten zwei Zeichen extrahieren. Z. B. für Rixheim kommt der Wert in der Overpass-Abfrage nicht, obwohl er bei OSM vorhanden ist. Warum?

Meine Idee ist, dass man für jede place-Koordinate mittels einer Spatial-Query in Overpass das dazugehörige Länderpolygon abfragt und dort das ISO3166-1-Tag heranzieht. Allerdings reichen meine Overpass-Fähigkeiten dazu nicht aus.

Nominatim ermittelt das aus der Lage. Das ist kein Tag.

place:country gibt es nicht, es gibt nur place.

Weil nur Nodes zurückgegeben werden (die Relationen besitzen kein place und darauf wird ja gefiltert), in dem Fall dieser Node: ‪Rixheim‬ (‪26691914‬) | OpenStreetMap. Und dort gibt es kein wikipedia.

Wie wär es damit:

Das Entscheidende ist das “is_in”.
Die Ergebnisse sind über 2 Zeilen verteilt, und man erhält teilweise auch die Einwohnerzahl des Staates.

place	name	population	ISO3166-1
town	Allschwil	20249	
	Schweiz/Suisse/Svizzera/Svizra		CH
town	Pfastatt	10237	
	France	67852556	FR
town	Kingersheim	13178	
	France	67852556	FR
[out:csv(
  "place:country",
  "wikipedia", 
  "place", "name", "population")][timeout:90];
(
  nwr["place"="city"]({{bbox}});
  nwr["place"="town"]({{bbox}});
)->.all;
area[admin_level=2]["ISO3166-1"]({{bbox}});
foreach ->.country
{
  nwr.all(area.country);
  convert info ::=::,"place:country"=country.u(t["ISO3166-1"]);
  out;
}

Die beiden nwr-Selektionen kommen in eine Union, damit auch Ergebnisse aus beiden ankommen. Nach .all um das Ergebnis in der ersten Zeile im forech nutzen zu können.

Die Suche nach area beschafft möglichst genau die Ländergrenzen, und das foreach iteriert dann darüber. Da es von mehreren Staaten mehrere Landesgrenzen gibt (z.B. Frankreich komplett vs. Hexagon), möglichst mit ISO3166-1 so beschränkt, dass jeweils nur ein Land iteriert wird. Dann per räumlicher Abfrage jeweils auf das Land beschränkt.

2 Likes

Wow, das funktioniert! Danke!