Streckennetz erstellen mit OpenStreetMap
Erscheinungsbild
[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;