Ich habe für den Datenblog des TA eine Visualisierung beliebter Jogging-Routen in Schweizer Städten erstellt. Hier eine Anleitung, wie das einfach möglich ist.
Am Anfang steht die Suche nach dem potentiellen Datenset. Die Daten der Joggingrouten, die ich verwende, stammen vom Trackingdienst RunKeeper. Der Dienst bietet eine Stichprobe ansehnlicher Grösse für eine halbwegs aussagekräftige Analyse. Mit der dortigen Suchfunktion lassen sich die von Nutzern hinterlegten Routen im Umfeld von Städten suchen und filtern.
Zwar rückt RunKeeper die Daten nicht direkt heraus, aber sie lassen sich relativ gut von der Suchseite scrapen. Sucht man nach Joggingrouten in und um die Stadt Bern, sieht man im Browser folgendes Resultat:
Jeweils sechs Routen werden in einer weiterblätterbaren Ansicht gezeigt. Der Clou daran, und praktisch für das Scraping: Die Karten, die RunKeeper anzeigt, sind keine Grafiken, sondern werden per Skript zum Ladezeitpunkt aus den tatsächlichen Geodaten erzeugt. Das heisst, wir müssen nicht einmal weitersuchen, sondern bloss die Koordidaten aus der Resultatseite herausziehen. Dort finden sich im Quelltext (neben einem Jobangebot) Daten in der Form:
var pointJson = [{"latitude":46.211764,"longitude":6.231522,"deltaDistance":0,"type":"StartPoint","deltaPause":0},{"latitude":46.21175,"longitude":6.23151,"deltaDistance":0.001809970036468833,"type":"ManualPoint","deltaPause":0}...
Um die angenehm klar ausgezeichneten Koordinatenpaare Längengrad / Breitengrad zu extrahieren, verwende ich Outwit, das ich bereits einmal in einem früheren Post vorgestellt habe. Das Tool ist deutlich einfacher zu nutzen als ein Skript und kann mit einer relativ kurz formulierten Suchanweisung wie folgender bereits die Routen aus dem Quellcode holen.
Das Resultat gibt Outwit auf Wunsch in einer CSV-Datei zurück (Beispiel Zürich). Für die anschliessende Visualisierung der Routen gibt es ein verschiedene Optionen. Ich nutze R, spezifisch das leistungsfähige Paket ggmap
, das auch Googlekarten im Gepäck hat. Deren Formatierung ist ähnlich einfach wie bei einem plot-Befehl:
detailMap <- function(bbox, thedata) { basemap <- get_map(location=bbox, source='google', maptype="terrain", color="bw") ggmap(basemap) + geom_path(aes(x=Longitude, y=Latitude, group=Route.Nr), size=0.8, color="#008000", alpha=0.3, data=thedata) } bern <- c(7.377017, 46.901330, 7.523213, 46.990161) detailMap(bern, routes_B)
Die Liste „bern“ ist eine Bounding-Box für die Karte. Das Resultat sieht ansehnlich aus.
Da ich die Daten nicht im Vorfeld auf ihre Korrekheit geprüft habe, schadet ein zweiter Blick an dieser Stelle nicht. So findet mal zum Beispiel einen mysteriös-magischen Wasserjogger auf dem Zürichsee. Retuschieren ist die einfachste Möglichkeit, das Problem zu lösen.
Wie das Ganze aussieht, wenn man ein noch grösseres Datenset zur Verfügung hat und eine Live-Visualisierung davon zeichnet, zeigt die schicke Jogging- und Bikingkarte von Strava – leider allerdings ohne nähere Informationen zur Herkunft der Daten.