Kategorien
Allgemein

Heatmap Segmente

… für den BRouter. Oder: wie bekomme ich eigene Informationen mit in das BRouter Kartenmaterial?

Zu nutze gemacht habe ich mir den „alten“ Weg um Segment-Dateien zu erstellen, wie vorhin hier schon beschrieben. Auch wenn es etwas langsamer geht, ich finde den mehrschrittigen Weg übersichtlicher. Und man kann eben, an geeigneter Stelle, einfach einen weiteren Schritt mit dazwischen hängen.

Oder konkreter: nachdem die Kartendaten initial konvertiert wurden (OsmCutter) und der NodeFilter gelaufen ist, nehme ich die ways.dat und reichere sie um einen Pseudo-Schlüssel für die Heatmap an.

Den Schlüssel gilt es erst in profiles/lookups.dat zu registrieren. Also unter der Rubrik „context:way“ eine weitere Zeile dazu. Die längliche Zahl, die da mit in der Zeile steht, ist übrigens einfach egal 🙂 … so sah das dann bei mir aus:

heatmap:stefan;0000000001 yes

… damit kann man einen Weg mit „heatmap:stefan=yes“ taggen.

Dann also ein bissl Java-Code schreiben, der

  1. die gefilterten Node-Tiles ausliest, sich pro Node aus der MongoDB die Information zieht, ob ich bei dem Node schon einmal war
  2. die ways.dat liest und Weg für Weg überprüft, ob ich an allen Nodes, die den Weg bestimmen, schon einmal war — und ggf. dann den Pseudo-Schlüssel ergänzt

Eine erste Version davon habe ich als Gist hochgeladen. Die Datei einfach mit nach brouter-map-creator/src/main/java/btools/mapcreator packen und dann durchkompilieren.

Das Skript will übersichtliche acht Parameter, und kann dann z.B. so aufgerufen werden:

java -jar brouter-server-1.6.1-jar-with-dependencies.jar -Ddeletetmpfiles=true -DuseDenseMaps=true btools.mapcreator.HeatmapEnricher ../../../profiles2/lookups.dat 172.17.0.2 heatmaps points stefan ftiles ways.dat ways-enriched.dat

… und wenn man danach die weiteren Schritte zum Erstellen der Segment-Dateien (wie üblich) vollführt, den Server startet und testet: sieht man erstmal gar nix.

Der BRouter-Server gibt einem in der Antwort nämlich nur diejenigen Tags zurück, die ausgewertet wurden. Und ohne Bezug im Profil kommen die Neuen halt auch nicht mit zurück.

… der zunächst einfachste Weg führt über einen dummyUsage-Eintrag in einem benutzerdefinierten Profil, also so:

assign dummyUsage = heatmap:stefan=

… und wenn man dann eine Route ermitteln lässt, dann sieht das etwa so aus:

… der erste Routingschritt betrifft ein Straßenstück, das ich noch nie befahren habe. Der zweite Eintrag dann hingegen schon. Unter WayTags wird der Pseudo-Schlüssel mit aufgeführt. Yay 🙂

So, nächster Schritt ist dann natürlich noch ein Profil dahingehend zu modifizieren, dass es die Information geeignet mit berücksichtigt. Konkret ist die Idee, bei kleineren Straßen und Wegen einen kleinen Bonus zu vergeben, wenn das Heatmap-Tag noch nicht gesetzt ist …

Kategorien
Allgemein

Heatmaps im Eigenbau

Heute mal wieder ein Blick hinter die Kulissen: auch in der Vergangenheit hatte ich hier und hier schon darüber geschrieben, wie man Strava und Komoot verbinden kann um die Strava Heatmap bei der Routenplanung berücksichtigen zu können.

Für zahlende Strava-Kunden gibt es außerdem neben der „global heatmap“ noch eine personalisierte Variante, die also darstellt, wo man selbst schon alles gewesen ist (und dementsprechend, wo noch Strecken darauf warten entdeckt zu werden).

Nun ist es aber so, dass ich seit einer Weile um die großen, zentralisierten sozialen Medien (Twitter, Facebook) einen Bogen mache und letztlich nur noch Mastodon (bzw. konkret die wue.social Instanz von Ralf) nutze. In dieses Bild passt natürlich auch nicht der Routen-Upload auf Strava und Komoot — und so kam es letztlich zu diesem Blog als „sharing Alternative“ zu Komoot (und z.B. auch der Kilometerstatistik etc.).

Jetzt fand ich die personalisierte Heatmap von Strava aber schon toll — also habe ich mir meine dezentrale Variante selbst gebaut. So sieht das Ergebnis aus:

In leichtem rot die Strecken, auf denen ich bisher nur einmal war … wenn ich an der Stelle schon ein paar mal war, dann sattes dunkelblau.

Technisch gesehen sind das selbst gerenderte overlay tiles, die man auf beliebige OpenStreetMap Karten (und theoretisch auch Google) legen kann.

Ich hatte mich dann erstmal nach bestehenden OpenSource-Lösungen umgesehen, … und feststellen müssen, dass das eher eine Nische ist. Nach einer Weile bin ich auf das Projekt „gheat“ gestoßen, … letzte Version vom April 2008. Und das setzt auf einen ebenso alten Python Web-Server (Aspen), von dem ich zuvor noch nie gehört hatte. Dort verlinkt ist auch ein Fork, der das ganze als Python CGI Script umgesetzt hatte (wobei der Code ebenso ziemlich alt ist).

Der Fork setzt auf eine MongoDB als Backend, die 2009 erst rausgekommen ist. Das muss definitiv ein early adopter gewesen sein 🙂

So oder so, der Plan stand dann relativ fest. Den alten Python Code zum Laufen bekommen, einen fastcgi-wrapper drumrum und einen modernen nginx davor. Das ganze in Docker verpacken und eben eine MongoDB daneben. Gesagt, getan. Stellt sich raus, dass das original gheat relative fette Kleckse zeichnet (für jeden einzelnen Punkt des GPX Tracks) — also im Format eher so breit wie eine Siedlung statt einer Straße.

Hat eine Weile gedauert zu verstehen, wie das gheat intern arbeitet, … aber eigentlich ist der Ansatz cool: nämlich zweischrittig. Für jeden Punkt des gpx wird erstmal eine (halbtransparente) „dot.png“ (das Teil der Programmquellen ist) auf eine transparente Leinwand projeziert. Das führt dazu, dass dieses Zwischenbild um so dunkler wird, je mehr Punkte gezeichnet werden bzw. um so dunkler/opaker das dot.png ist.
Im zweiten Schritt wird der Alphakanal dieses „Bildes“ wieder ausgelesen und die eigentliche Heatmap unter Berücksichtigung des gewählten Farbverlaufs generiert.

Letztlich ein interessanter Ansatz — heißt nur, dass ich zum Lösen der Klecksproblematik nicht den Code anfassen muss, sondern meine (nicht vorhandenen) Gimp Skills auspacken muss.

Naja, hat dann schon irgendwie funktioniert 🙂

… und die Belohnung ist die oben gezeigte Heatmap. Die ausreichend flott für on-the-fly Generierung ist und seither mit auf dem Webserver lebt. Den aufgefrischten und modifizierten Code findet ihr (ebenso denzentral) hier auf meiner Gitlab Instanz.

Kategorien
Allgemein

Heatmap’ed Komoot 😍

Das mit der Strava Heatmap in Komoot hat mir jetzt doch noch keine Ruhe gelassen …

Also insbesondere, dass man mit der reinen Heatmap-Karte nicht so richtig erkennen kann, welcher Ort das ist. Eben weil sämtliche Beschriftungen fehlen.

Eine Lösung dafür war schnell gefunden: den Tile-Request des Browsers (bzw. von Komoot) auf einen lokalen, kleinen Web-Server verbiegen, der

  • den Request entgegen nimmt
  • das Tile vom Open Street Map Server abruft
  • das Overlay Tile vom Strava Global Heatmap Server abruft
  • die beiden Bilder kombiniert
  • für Caching-Zwecke das Ergebnis lokal vorhält
  • und last but not least an den Browser (bzw. eben Komoot) zur Anzeige ausliefert

Habe als Waffee mal node.js gewählt, Web-Server mit express.js und zum Kombinieren der Tiles habe ich „@mapbox/blend“ entdeckt. Funktioniert auf anhieb, … Source auf Github. (beachte, dass ein Strava Summit Account erforderlich ist)

So sieht das Ergebnis dann aus (weiter raus gezoomed):

Auf diesem Zoom-Level sieht eine Stadt wie Würzburg natürlich nach einem unübersichtlichen Knäuel aus. Aber man bekommt trotzdem einen guten Überblick. Und wenn man in Komoot die „m“-Taste drückt (= gewählte Route ausblenden) kann man auch gut kontrollieren, ob diese auf einem Heatmap-positiven Pfad liegt.

Die Farbtöne des Heatmap-Overlays sind auch ausreichend unterschiedlich von den OSM-Farben, sodasss man z.B. das Heatmap-Rot nicht mit dem „primary road“-Rot von OSM verwechseln kann.

Auf höherem Zoom-Level sieht das dann so aus:

Das Auge kann da schon relativ gut abschätzen, was wohl Waldwege sind oder was z.B. Landstraßen…