Explorer Tile Video

Seit einiger Zeit nutze ich die Explorer Tiles, um systematisch mehr von der Umgebung zu erkunden. Mit meinen heruntergeladenen Daten von Strava kann ich nun weitere Dinge erzeugen. Komplett Strava nachbauen möchte ich gar nicht, das ist viel zu viel Aufwand. Aber ein Ding, was so nicht angeboten wird, ist ein Video mit der Erkundung der Kacheln. Wie in einem Echtzeit-Strategiespiel (RTS), bei dem die Karte zuerst unentdeckt und schwarz oder dunkel ist, möchte ich zeigen, wie ich so langsam die Umgebung erkundet habe.

Dazu brauche ich erst einmal die zeitliche Abfolge der Erkundung. Die habe ich bereits, das ist ein Data Frame mit Zeit und Kachel X und Y. Daraus kann ich nun ein Video bauen. Ein Bestandteil ist das Herunterladen der Kacheln von der Open Street Map, damit ich daraus Bilder für ein Video bauen kann, dafür habe ich auch schon ein bisschen Code. Zuletzt muss ich die Einzelbilder für das Video zusammensetzen. Und da braucht es einen Plan, wie ich das am sinnvollsten mache.

Kacheln herunterladen

Die Kacheln kann man über diverse APIs herunterladen. Sie sind über Zoom-Level, X und Y spezifiziert. Nehmen wir Zoom-Level 14, also das, mit dem die Explorer Tiles definiert sind, dann hat man mit Kachel (8509, 5503) folgende PNG-Bilddatei mit 256×256 Pixeln:

Das war jetzt erstaunlich einfach.

Bild zusammensetzen

Als nächstes muss ich ein Bild aus den Kacheln zusammensetzen. Dabei muss ich einen Mittelpunkt, ein Bildformat und noch eine Liste mit zu diesem Zeitpunkt schon erkundeten Kacheln übergeben. Die Funktion kann dann ein großes Bild daraus aufbauen und die unerkundeten Kacheln ausblenden.

Da ich zu diesem Zeitpunkt schon alles in Integer-Kachelindizes umgerechnet habe, muss ich mir auch keine Sorgen bezüglich Web-Mercator-Projektion machen. Ich kann einfach nur noch in diesen Kacheln arbeiten. Das macht es schon einfacher.

Ich musste etwas rechnen, aber dann ging das eigentlich ganz brauchbar. Ein FullHD Bild, das um jene Kacheln zentriert ist, und bei dem nur diese Kachel aufgedeckt ist, sieht so aus:

Das ganze unterstützt auch schon Mittelpunkte, die nicht exakt eine Kachel sind. So kann ich das gleich sanft verschieben:

Trajektorie

Der schwerste Teil ist eine ansprechende Trajektorie zu finden, mit der durch die Karte abgefahren werden soll. Einfach immer nur zu den Mittelpunkten springen wird ruckelig werden. Mit konstanter Geschwindigkeit linear dazwischen fahren ist einfach, bringt aber immer Knicke rein und wirkt dadurch unrund. Die Punkte in 2D mit kubischen Splines verbinden wird eine runde Trajektorie ermöglichen.

Ein Problem ist noch, wie mit großen Sprüngen umgegangen werden soll. Da ich nicht alle Kacheln dazwischen herunterladen möchte, kann ich keine langen Kamerafahrten machen. Außerdem wird einem davon auch nur schlecht, wenn ich zum Beispiel von Utrecht nach Bonn springe. Ich werde dann einfach aus- und wieder einblenden.

Für die Kamerafahrt baue ich mir noch ein kleines System für Animationen. Und zwar muss ich für die Erzeugung der Bilder den Mittelpunkt, die bis dahin erkundeten Kacheln und dann noch die allgemeine Helligkeit haben. Diese Daten kann ich mit Generatoren erzeugen. Jeder Generator erzeugt, bis sein Abschnitt fertig ist.

Für die Animation habe ich dann scipy.interpolate.splprep genutzt, um an alle Punkte eine B-Spline zu legen. Mit scipy.interpolate.splev kann ich die Kurve anschließend an vielen Zeitpunkten auswerten und so eine sanfte Kamerafahrt erzeugen.

Das Erzeugen der Bilder dauert ewig, weil ich immer wieder aus allen Kacheln das Bild zusammensetze. So schafft das Programm zwischen 1 und 4 Bilder pro Sekunde. Teilweise wird es verzögert, weil erst die Kacheln heruntergeladen werden müssen, wenn sie noch nicht im Zwischenspeicher liegen.

Ergebnis

Nachdem das dann viele Stunden gerechnet hat, und 36 GB Einzelbilder erzeugt hat, konnte ich mit ffmpeg daraus ein Video rendern. Das fertige Video sieht so aus:

Verbesserungsmöglichkeiten

Aktuell gibt es noch kein langsames »Anfahren« der Kamerabewegung. Man könnte hier die Geschwindigkeit, mit der der Kurvenparameter abgefahren wird, noch sanft erhöhen und am Ende verzögern. Dadurch würde sich das ganze noch etwas sanfter anschauen lassen.

Das jeweilige Datum könnte noch mit eingefügt werden, so bekäme man eine Idee, wann welche Tour unternommen worden ist.

Die Performance könnte man noch deutlich verbessern. So wird immer ein neues Bild angelegt und die Kacheln reinkopiert. Da man das Bild hier nur zur Seite bewegt, könnte man das bestehende Bild verschieben und nur die Ränder neu setzen. Oder man erzeugt pro Phase ein Bild, das alles enthält, und erzeugt die Kamerafahrt durch das Nehmen von Ausschnitten aus diesem großen Bild. Man müsste nur beim Aufdecken der Kacheln einzelne Kacheln neu setzen. Dann wird auch noch beim Abblenden jedes Mal ein neues Bild erzeugt, obwohl es nur 25 Helligkeitsstufen des gleichen Bildes ist.

Wenn in einer Phase nur eine einzelne Kachel aufgedeckt wird, klappt es anscheinend nicht so gut, dann ist die Kachel schon beim Aufblenden aufgedeckt.

Ich gehe aber davon aus, dass ich nur einmal dieses Video erzeuge, mich daran erfreue und den Code nicht so schnell wieder anpacken werde.