BBQ-Map: Eine Grill-Landkarte
Der Sommer war viel zu kurz, aber trotzdem gab es in den vergangenen Wochen noch einige gemütliche Grillabende. Was aber, wenn Sonntag ist und kein Grillgut zur Hand? Oder noch schlimmer, kein Grill? Dann gibt es immer noch öffentliche Grillplätze und neuerdings auch Grillgutautomaten. Ich habe so einen Grillgutautomaten in der Nähe auch schon ausprobiert und habe begeistert getwittert:
Überhaupt: Grillfleischautomaten, wie geil ist das denn?
— Matthias Gutjahr (@mattsches) 17. Juli 2014
In der darauf folgenden Diskussion kam die Idee auf, eine Karte mit Grillgutautomaten zu erstellen. Natürlich kenne ich nicht alle dieser Automaten, und ob man die Daten dieses oder ähnlicher Verzeichnisse einfach so verwenden, ist fraglich (man könnte in der Tat mal dort anfragen). Aber glücklicherweise ist auch die OpenStreetMap-Community auf die Idee gekommen, diese Daten zu sammeln.
Karten und Daten
Neben den Grillgutautomaten wollte ich auch gleich noch (öffentliche) Grillplätze anzeigen. Damit war der Name der Karte klar: BBQ-Map. Es existieren mittlerweile zahlreiche Möglichkeiten, Karten zu erstellen und mit eigenen oder öffentlichen Daten aufzuwerten. Je nach Komplexität der Anforderung und Datenlage bieten sich unterschiedliche Ansätze an.
Wer einen eigenen Server hat, kann dort mittels Open Source-Tools die Karten-Webseite, die zu visualisierenden Daten und sogar die selbst generierten Kartenkacheln zur Darstellung hosten. Einfacher geht es mit öffentlichen Kartendiensten, die oft sogar kostenlos sind und vielfältige Bearbeitungsmöglichkeiten anbieten.
Für die BBQ-Map greife ich auf die Daten des OpenStreetMap-Projekts zurück. Gehostet wird die Karte beim französischen Projekt uMap.
Vorteile:
- Die Daten können von der Community ständig aktualisiert werden.
- Die Daten sind öffentlich und unterliegen der freizügigen Open Database License (ODbL).
Zum Einsatz kamen folgende Tools:
- uMap als gehostete Instanz bei umap.openstreetmap.fr.
- Overpass Turbo zum Generieren und Testen der Daten-Abfrage.
- Overpass API als eigentliche Datenquelle und zum Nachschlagen in der Dokumentation.
Anmeldung bei uMap
Die Registrierung bei uMap ist kostenlos und erfolgt per OAuth, d.h. über einen Account bei OpenStreetMap, GitHub, Twitter oder Bitbucket, der schon vorhanden sein muss. Ist dies nicht der Fall, muss man sich wohl bei einem dieser Dienste registrieren. Nach dem Einloggen finden sich unter "Meine Karten" die Maps, die ich bereits auf uMap erstellt habe. Nach dem Klick auf "Erstelle eine Karte" wir eine neue Karte generiert, die auf vielfältige Weise angepasst werden kann. Beispielsweise stehen verschiedene Kartendarstellungen ("Kacheln") zur Verfügung, es können Marker, Linien oder Flächen eingezeichnet, Menüs angepasst oder der Kartenausschnitt begrenzt werden.
Außerdem lassen sich eigene Datensätze hochladen und auf der Karte visualisieren. Eine oder mehrere Datenebenen können über das Menü links angelegt werden und anschließend mit Daten befüllt werden. Im Fall der BBQ-Map habe ich die Daten nicht selbst vorliegen, sondern werde die Grillplätze dynamisch aus den OpenStreetMap-Daten abfragen. Dies geschieht über das Overpass API als zentrale Schnittstelle zu den OSM-Daten.
Grillplätze finden mit dem Overpass API
Vergleichsweise schwierig ist das Zusammenbauen der Query für das Overpass API. Ungemein hilfreich beim Austüfteln der Abfrage-Bestandteile ist der Overpass Turbo, eine webbasierte Oberfläche, die Abfrage-Ergebnisse des Overpass API direkt auf einer OpenStreetMap anzeigt. Bedienungshinweise und nützliche Beispiele werden im OSM-Wiki gesammelt.
Für die BBQ-Map suche ich nach allen Nodes, Ways und Relations mit dem Key-Value-Paar "amenity=bbq"
. Vermutlich würde es sogar reichen, nur nach Nodes zu suchen, aber sicher ist sicher. Außerdem gibt es noch Nodes (und möglicherweise Ways und Relations) mit dem Key "food:bbq". Das trage ich wie folgt in den Query-Editor ein, der zugehörige Wizard kann dabei helfen, eine initiale Query zu erzeugen.
This has been generated by the overpass-turbo wizard.
-->
<osm-script output="json" timeout="25">
<!-- gather results -->
<union>
<query type="node">
<has-kv k="amenity" v="bbq"/>
<bbox-query {{bbox}}/>
</query>
<query type="way">
<has-kv k="amenity" v="bbq"/>
<bbox-query {{bbox}}/>
</query>
<query type="relation">
<has-kv k="amenity" v="bbq"/>
<bbox-query {{bbox}}/>
</query>
<query type="node">
<has-kv k="food:bbq" v="yes"/>
<has-kv k="amenity" v="vending_machine"/>
<bbox-query {{bbox}}/>
</query>
<query type="way">
<has-kv k="food:bbq" v="yes"/>
<has-kv k="amenity" v="vending_machine"/>
<bbox-query {{bbox}}/>
</query>
<query type="relation">
<has-kv k="food:bbq" v="yes"/>
<has-kv k="amenity" v="vending_machine"/>
<bbox-query {{bbox}}/>
</query>
</union>
<!-- print results -->
<print mode="body"/>
<recurse type="down"/>
<print mode="skeleton" order="quadtile"/>
</osm-script>
Der Platzhalter {{bbox}}
wird in der Abfrage automatisch zu den Koordinaten des jeweils sichtbaren Kartenausschnitts, der Bounding Box, umgewandelt. Diese Bounding Box sollte wann immer möglich mit angegeben werden, weil ansonsten eine weltweite Suche durchgeführt würde. Und die kann sehr lange dauern. Der vorgegebene Timeout von 25 Sekunden verhindert dann, dass überhaupt Ergebnisse zurückgegeben werden.
Nach dem Ausführen der Abfrage werden mir jede Menge Treffer angezeigt, mit denen ich zumindest vorerst zufrieden bin. Nun kann ich die Query via Export > Abfrage > OverpassQL
exportieren, und ich wähle die kompakte Variante
. Die ist zwar nicht so leicht zu lesen, aber ich kann mir den Link direkt in die Zwischenablage kopieren.
Die Abfrage anpassen und in uMap einfügen
Allerdings ist die Abfrage in OverpassQL noch nicht optimal, denn sie enthält für jede Query noch die Bounding Box des in Overpass Turbo angezeigten Kartenausschnitts. Die Bounding Box soll später jedoch dynamisch bestimmt und eingefügt werden. Momentan sieht die Abfrage noch so aus (alles ohne Leerzeichen):
way<a href="49.81184707512046,7.823638916015625,50.257741984396894,8.7396240234375">"amenity"="bbq"</a>;
relation<a href="49.81184707512046,7.823638916015625,50.257741984396894,8.7396240234375">"amenity"="bbq"</a>;
node["food:bbq"="yes"]<a href="49.81184707512046,7.823638916015625,50.257741984396894,8.7396240234375">"amenity"="vending_machine"</a>;
way["food:bbq"="yes"]<a href="49.81184707512046,7.823638916015625,50.257741984396894,8.7396240234375">"amenity"="vending_machine"</a>;
relation["food:bbq"="yes"]<a href="49.81184707512046,7.823638916015625,50.257741984396894,8.7396240234375">"amenity"="vending_machine"</a>;);
out body;>;out skel qt;
Zunächst fliegen alle Koordinaten samt der sie umgebenden Klammern raus.
node["food:bbq"="yes"]["amenity"="vending_machine"];way["food:bbq"="yes"]["amenity"="vending_machine"];
relation["food:bbq"="yes"]["amenity"="vending_machine"];);out body;>;out skel qt;
Das ist schon viel übersichtlicher. Nun muss noch der Bounding Box-Platzhalter eingefügt werden. Die Mapping-Bibliothek Leaflet.js, die von den uMap-Karten benutzt wird, stellt eine {bbox}
-Variable zur Verfügung. Unglücklicherweise unterscheidet sich deren Koordinatenreihenfolge von derjenigen, die das Overpass API benötigt: Süd, West, Nord, Ost. Also fügen wir statt {bbox}
folgende Variablen ein:
node["food:bbq"="yes"]["amenity"="vending_machine"];way["food:bbq"="yes"]["amenity"="vending_machine"];relation["food:bbq"="yes"]["amenity"="vending_machine"];);out body;>;out skel qt;
Diesen String hänge ich an den API-URL http://www.overpass-api.de/api/interpreter?data=
an und erhalte so den fertigen Abfragestring. Diesen kann ich nun im Bearbeitungsmodus auf uMap eintragen.
Dazu wähle ich links die zu editierende Datenebene aus oder erstelle eine neue. Die Abfrage wird unter Ausgelagerte Daten > URL
eingetragen, und als Format muss osm
ausgewählt sein.
Nach dem Speichern sollten nun bereits Marker auf der Map erscheinen - vorausgesetzt, im ausgewählten Kartenausschnitt sind welche gemappt.
Daten auf mehrere Ebenen verteilen
Werden die Daten erst einmal auf der Karte angezeigt, ist das Schwierigste überstanden. Wie oben erwähnt, bietet uMap eine wachsende Zahl von Anpassungsmöglichkeiten an. So lassen sich beispielsweise Grillplätze und Grillgutautomaten auf zwei verschiedenen Ebenen anzeigen (vgl. Screenshot oben). Die Overpass-Abfrage darf dann jeweils nur die Nodes, Ways und Relations mit ["amenity"="bbq"]
bzw. ["food:bbq"="yes"]["amenity"="vending_machine"]
enthalten. Auf diese Weise lassen sich auch noch weitere Datenebenen befüllen, z.B. für Getränkemärkte, Tankstellen oder was für Grillbegeisterte sonst noch von Interesse sein könnte.
Wer nicht auf einen Dienst wie uMap angewiesen sein möchte, kann sich eine solche Karte mit JavaScript und HTML/CSS auch relativ einfach selbst bauen. Aber das ist ein Thema für einen eigenen Artikel.
Meine BBQ-Map ist unter http://umap.openstreetmap.fr/de/map/bbq-map_15455 online. Für Ideen, Ergänzungen, Kritik und Verbesserungen bin ich offen.
Kommentare
Ansicht der Kommentare: Linear | Verschachtelt
Thorsten Gowik am :
Und jetzt noch jeden Automat in Ingress einreichen als Portal und die Sache wird perfekt