Zum Inhalt springen

Streckennetz erstellen mit OpenStreetMap

Aus awm
Version vom 11. Februar 2025, 07:00 Uhr von Flr (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „<pre> [out:json]; // Wir möchten sämtliche Elemente (z.B. Nodes, Ways oder Relations) innerhalb einer bestimmten „Area“ abrufen. Die Area // kann theoretisch über beliebige Schlüssel referenziert werden – diese Möglichkeit stellt insbesondere während der // Entwicklung oder des Debuggings eine enorme Erleichterung dar. Im Produktivbetrieb empfiehlt es sich jedoch, zuerst // die hinter einer Area stehende Relation anhand ihrer OSM-internen ID…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
[out:json];
 
// Wir möchten sämtliche Elemente (z.B. Nodes, Ways oder Relations) innerhalb einer bestimmten „Area“ abrufen. Die Area
// kann theoretisch über beliebige Schlüssel referenziert werden – diese Möglichkeit stellt insbesondere während der
// Entwicklung oder des Debuggings eine enorme Erleichterung dar. Im Produktivbetrieb empfiehlt es sich jedoch, zuerst
// die hinter einer Area stehende Relation anhand ihrer OSM-internen ID zu ermitteln und diese Relation durch einen
// Aufruf von `map_to_area` in eine Area umzuwandeln, womit fehlerhafte Referenzierungen zuverlässig verhindert werden.
//
// https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL#By_element_id
//
// Wichtig: Unabhängig davon, ob die Area anhand von Schlüsseln referenziert oder mit `map_to_area` aus einer Relation
// erzeugt wird, muss dem (Result-)Set ein Name vergeben werden (hier: `searchArea`), damit im Union-Block die zu
// durchsuchende Area nicht verloren geht bzw. überschrieben wird.
//
// https://help.openstreetmap.org/questions/48794/overpass-api-union-doesnt-work
 
rel(id: 75155, 75177);
map_to_area -> .searchArea;
 
// Für das Erzeugen des Streckennetzes sind nur bestimmte Straßenarten relevant. Manche Klassifizierungen werden aus
// Gründen der Einfachheit und Entwicklerergonomie über reguläre Ausdrücke selektiert, damit z.B. bei `motorway`
// automatisch auch `motorway_link` oder `motorway_junction` berücksichtigt werden.
//
// https://wiki.openstreetmap.org/wiki/DE:Key:highway
 
// Das Ergebnis der Abfrage unterteilen wir in zwei (Result-)Sets:
//
//   * `right_side_streets` für Straßen, welche nur rechtsseitig gesammelt werden sollen
//   * `both_side_streets` für kleinere Neben- und Wohnstraßen, welche beidseitig gesammelt werden können
//
// https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL#Sets
 
(
  // Autobahnen und Anschlussrampen
  way(area.searchArea)["highway" ~ "^motorway"];
 
  // Autostraßen und Anschlussrampen
  way(area.searchArea)["highway" ~ "^trunk"];
 
  // Bundes- und Landesstraßen
  way(area.searchArea)["highway" ~ "^primary"];
  way(area.searchArea)["highway" ~ "^secondary"];
 
  // Sonstige Hauptstraßen
  way(area.searchArea)["highway" ~ "^tertiary"];
)->.right_side_streets;
 
(
  // Gemeindestraßen, Straßen in Wohngebieten und Zufahrtsstraßen
  way(area.searchArea)["highway" = "unclassified"];
  way(area.searchArea)["highway" = "residential"];
  way(area.searchArea)["highway" = "living_street"];
  way(area.searchArea)["highway" = "service"];
 
  // Auch Fußgängerzonen, aber Umrisse explizit ausschließen
  way(area.searchArea)["highway" = "pedestrian"]["area" != "yes"];
)->.both_side_streets;
 
// Nicht alle Ways innerhalb der `searchArea` sind gleichermaßen nützlich und interessant für uns. Die kleinen Straßen
// auf Parkplätzen bei Einkaufszentren oder vor Baumärkten müssen ignoriert werden, da diese unser Streckennetz nur
// unnötig aufblähen und mit einem LKW ohnehin nur schwer befahren werden können.
 
way(area.searchArea)["amenity" = "parking"];
map_to_area -> .searchAreaParkingLots;
way(area.searchAreaParkingLots)["highway"]->.streets_to_ignore;
 
(.right_side_streets; - .streets_to_ignore;)->.right_side_streets;
(.both_side_streets; - .streets_to_ignore;)->.both_side_streets;
 
// Die ermittelten Ways haben wir in zwei (Result-)Sets unterteilt, damit wir diese nun um Metadaten anreichern können.
// Den `convert`-Ausdrück können wir leider nicht verwenden; dieser verändert die Datenstruktur soweit, dass einerseits
// die Node-IDs verloren gehen und die Koordinaten als GeoJSON zurückgeliefert werden.
//
// Aus diesem Grund erzeugen wir stattdessen ein eigenes Element und aggregieren schlicht die IDs, damit diese vom
// Streckennetzgenerator wieder ausgelesen werden können.
 
make infeo_road_network_meta
  ::id = 0,
  both_side_street_way_ids = both_side_streets.set(id()),
  right_side_street_way_ids = right_side_streets.set(id());
 
out;
 
.both_side_streets out geom;
.right_side_streets out geom;