Benutzer-Werkzeuge

Webseiten-Werkzeuge


osmium

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
osmium [2026/04/02 10:17]
admin [Buslinien extrahieren]
osmium [2026/04/05 13:50] (aktuell)
jango [Linux]
Zeile 1: Zeile 1:
-Osmium ist ein CLI-Tool für die Arbeit mit OSM-Daten und basiert auf der C-Bibliothek libosmium. Es kann mit mehreren OSM-Datenformaten arbeiten, vor allem:+Osmium ist ein CLI-Tool für die Arbeit mit [[OpenStreetMap|OSM]]-Daten und basiert auf der C-Bibliothek libosmium. Es kann mit mehreren OSM-Datenformaten arbeiten, vor allem:
  
   * .osm.pbf → binäres [[PBF]]-Format   * .osm.pbf → binäres [[PBF]]-Format
Zeile 20: Zeile 20:
   n/public_transport=platform \   n/public_transport=platform \
   r/route=bus \   r/route=bus \
 +  -R \
   -o bus-relevant.osm.pbf -O   -o bus-relevant.osm.pbf -O
 </code> </code>
Zeile 30: Zeile 31:
 import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
 from collections import defaultdict from collections import defaultdict
 +
 +
 +def fail(msg, code=1):
 +    print(msg, file=sys.stderr)
 +    sys.exit(code)
 +
  
 if len(sys.argv) != 3: if len(sys.argv) != 3:
-    print("Aufruf: python3 osm_bus_stops_to_geojson.py input.osm.pbf output.geojson"+    fail("Aufruf: python3 osm_bus_stops_to_geojson.py input.osm.pbf output.geojson")
-    sys.exit(1)+
  
 input_pbf = sys.argv[1] input_pbf = sys.argv[1]
 output_geojson = sys.argv[2] output_geojson = sys.argv[2]
  
-# OSM XML aus osmium cat streamen +try: 
-proc = subprocess.Popen+    proc = subprocess.run
-    ["osmium", "cat", input_pbf, "-f", "osm"], +        ["osmium", "cat", input_pbf, "-f", "osm"]
-    stdout=subprocess.PIPE+        capture_output=True, 
-    stderr=subprocess.PIPE+        text=True, 
-    text=True+        check=False
-)+    
 +except FileNotFoundError: 
 +    fail("Fehler: 'osmium' wurde nicht gefunden."
 + 
 +if proc.returncode != 0: 
 +    fail(f"Fehler bei 'osmium cat':\n{proc.stderr}"
 + 
 +if not proc.stdout.strip(): 
 +    fail("Fehler: 'osmium cat' hat keine Ausgabe geliefert."
 + 
 +try: 
 +    root ET.fromstring(proc.stdout) 
 +except ET.ParseError as e: 
 +    fail(f"XML Parse Error: {e}"
 + 
 +# Haltestellen-Nodes sammeln 
 +stops = {} 
 +for node in root.findall("node"): 
 +    node_id = node.get("id"
 +    lat = node.get("lat"
 +    lon = node.get("lon"
 +    if node_id is None or lat is None or lon is None: 
 +        continue 
 + 
 +    tags = {tag.get("k"): tag.get("v") for tag in node.findall("tag")} 
 +    is_bus_stop = tags.get("highway") == "bus_stop" 
 +    is_platform = tags.get("public_transport") == "platform" 
 + 
 +    if is_bus_stop or is_platform: 
 +        stops[node_id] = { 
 +            "id": node_id, 
 +            "lat": float(lat), 
 +            "lon": float(lon), 
 +            "tags": tags, 
 +        } 
 + 
 +# Routenrelationen -> Haltestellen mappen 
 +routes_by_stop = defaultdict(list) 
 + 
 +for rel in root.findall("relation"): 
 +    rel_tags {tag.get("k"): tag.get("v") for tag in rel.findall("tag")} 
 + 
 +    if rel_tags.get("route") != "bus": 
 +        continue 
 + 
 +    route_info = { 
 +        "relation_id": rel.get("id"), 
 +        "ref": rel_tags.get("ref"), 
 +        "name": rel_tags.get("name"), 
 +        "from": rel_tags.get("from"), 
 +        "to": rel_tags.get("to"), 
 +        "operator": rel_tags.get("operator"), 
 +        "network": rel_tags.get("network")
 +    
 + 
 +    for member in rel.findall("member"): 
 +        if member.get("type") !"node": 
 +            continue 
 + 
 +        ref = member.get("ref"
 +        role = member.get("role""") 
 + 
 +        if ref in stops: 
 +            entry = dict(route_info) 
 +            entry["member_role"] = role 
 +            routes_by_stop[ref].append(entry) 
 + 
 +features = [] 
 + 
 +for stop_id, stop in stops.items(): 
 +    routes = routes_by_stop.get(stop_id, []) 
 + 
 +    # doppelte Routen vermeiden 
 +    seen = set() 
 +    unique_routes = [] 
 +    for r in routes: 
 +        key = ( 
 +            r.get("relation_id"), 
 +            r.get("ref"), 
 +            r.get("name"), 
 +            r.get("member_role"), 
 +        ) 
 +        if key not in seen: 
 +            seen.add(key) 
 +            unique_routes.append(r) 
 + 
 +    route_refs = sorted({r["ref"] for r in unique_routes if r.get("ref")}) 
 +    route_names = sorted({r["name"] for r in unique_routes if r.get("name")}) 
 + 
 +    properties = dict(stop["tags"]) 
 +    properties["osm_id"] = stop["id"
 +    properties["osm_type"] = "node" 
 +    properties["route_refs"] = route_refs 
 +    properties["route_names"] = route_names 
 +    properties["routes"] = unique_routes 
 + 
 +    features.append({ 
 +        "type": "Feature", 
 +        "geometry":
 +            "type": "Point", 
 +            "coordinates": [stop["lon"], stop["lat"]], 
 +        }, 
 +        "properties": properties, 
 +    }) 
 + 
 +geojson = { 
 +    "type": "FeatureCollection", 
 +    "features": features, 
 +
 + 
 +try: 
 +    with open(output_geojson, "w", encoding="utf-8") as f: 
 +        json.dump(geojson, f, ensure_ascii=False, indent=2) 
 +except OSError as e: 
 +    fail(f"Fehler beim Schreiben von '{output_geojson}': {e}"
 + 
 +print(f"GeoJSON geschrieben: {output_geojson}"
 +print(f"Haltestellen: {len(features)}"
 +print(f"Haltestellen mit Routeninfo: {sum(1 for f in features if f['properties']['routes'])}")
 </code> </code>
  
Zeile 53: Zeile 177:
  
 Die geojson hat dann so eine struktur Die geojson hat dann so eine struktur
-<code json>{ +<code json> 
-  "name": "Hervicusgasse", +
-  "public_transport": "platform", +  "type": "Feature", 
-  "bus_lines": ["16A", "63A"]+  "geometry": 
-  "bus_route_names": [ +    "type": "Point", 
-    "Bus 16AAlaudagasse => Südwestfriedhof2. und 8. Tor", +    "coordinates": [16.3738, 48.2082] 
-    "Bus 63AGesundheitszentrum Süd => Am Rosenhügel+  }, 
-  ], +  "properties":
-  "bus_routes": [ +    "name": "Karlsplatz", 
-    +    "highway": "bus_stop", 
-      "route_id": 123456+    "osm_id": "123456789", 
-      "line_ref": "16A", +    "route_refs"["13A", "59A"]
-      "route_name": "Bus 16A...", +    "route_names"
-      "role": "platform" +      "13A: Alser Straße - Hauptbahnhof", 
-    +      "59A: Bhf. Meidling - Oper" 
-  ]+    ], 
 +    "routes": [ 
 +      
 +        "relation_id": "111"
 +        "ref": "13A", 
 +        "name": "13AAlser Straße - Hauptbahnhof", 
 +        "from": "Alser Straße", 
 +        "to": "Hauptbahnhof", 
 +        "operator": "Wiener Linien", 
 +        "network": "Wiener Linien", 
 +        "member_role": "platform" 
 +      
 +    ] 
 +  }
 } }
 </code> </code>
Zeile 734: Zeile 871:
 =====Linux===== =====Linux=====
  
-<code>+<code bash>
 sudo apt update sudo apt update
 sudo apt install osmium-tool sudo apt install osmium-tool
  
 osmium extract --bbox 16.20,48.10,16.50,48.35 --strategy smart -o wien.osm.pbf europe-latest.osm.pbf osmium extract --bbox 16.20,48.10,16.50,48.35 --strategy smart -o wien.osm.pbf europe-latest.osm.pbf
 +
 osmium tags-filter wien.osm.pbf n/highway=bus_stop -o bus_stops.osm.pbf osmium tags-filter wien.osm.pbf n/highway=bus_stop -o bus_stops.osm.pbf
 +
 osmium sort edited.osm.pbf -o edited-sorted.osm.pbf osmium sort edited.osm.pbf -o edited-sorted.osm.pbf
 +
 osmium renumber edited-sorted.osm.pbf -o edited-renumbered.osm.pbf osmium renumber edited-sorted.osm.pbf -o edited-renumbered.osm.pbf
 +
 osmium fileinfo -e edited-renumbered.osm.pbf osmium fileinfo -e edited-renumbered.osm.pbf
  
 osmium extract -b 16.36,48.20,16.38,48.21 input.osm.pbf -o output.osm.pbf --output-header=generator="MeinTool/1.0" osmium extract -b 16.36,48.20,16.38,48.21 input.osm.pbf -o output.osm.pbf --output-header=generator="MeinTool/1.0"
 </code> </code>
 +Siehe [[https://docs.osmcode.org/osmium/latest/osmium-extract.html|osmium-extract]] 
 +<code> 
 +# bbox 
 +at - 9.54063,46.37853,17.17397,49.01266 
 +vienna - 16.20,48.10,16.50,48.35 
 +</code>
 =====Python===== =====Python=====
  
Zeile 985: Zeile 1131:
   * [[https://osmcode.org/osmium-tool/|Osmium Tool]]   * [[https://osmcode.org/osmium-tool/|Osmium Tool]]
   * [[https://github.com/osmcode/osmium-tool|Osmium Tool - Github]]   * [[https://github.com/osmcode/osmium-tool|Osmium Tool - Github]]
 +  * [[https://docs.osmcode.org/osmium|Docs]]
osmium.1775117863.txt.gz · Zuletzt geändert: 2026/04/02 10:17 von admin