Karte für Blogeinträge

Hier im Blog habe ich habe viele Artikel zu verkehrspolitischen Themen. Damit ich die schnell wiederfinden kann, habe ich Schlagworte vergeben, wie zum Beispiel »Bonn-Zentrum«. Damit kann man dann eine Liste aller Artikel bekommen. Auf meinem Rechner habe ich in Viking allerdings auch noch eine Kartenebene, auf der ich die Dinge eintrage:

Nachts, als ich zwischendurch aufgewacht bin, war da eine Idee: Auf meinem Blog will ich auch eine Karte haben, auf der die Artikel verlinkt sind. Das ist noch viel praktischer, und die Leser*innen haben auch noch etwas davon.

So eine interaktive Karte ist dank Open Street Map und Leaflet gar nicht mehr schwer. Das Tutorial hat sogar auch schon direkt einen Marker drin:

var map = L.map('map').setView([51.505, -0.09], 13);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

L.marker([51.5, -0.09]).addTo(map)
    .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
    .openPopup();

Das ist alles super einfach, ich muss jetzt nur noch die ganzen Marker einfügen. Dazu muss ich die natürlich erstmal irgendwo innerhalb meines Blogs erfassen. Dafür gibt es letztlich zwei Möglichkeiten: Ich kann die in die Metadaten meiner Artikel schreiben, oder ich habe eine zentrale Liste.

Ich füge den YAML-Metadaten eines Artikels dann noch dieses Elemente hinzu, das die URL im Format eines Open Street Map Links enthält:

latlon: 51.3998/3.5180

Und ich schreibe ein Python-Skript, das diese Dinge alle extrahiert. Das erzeugt dann eine JSON-Datei:

[
  {
    "category": "Verkehr",
    "date": "2021-11-07",
    "lat": 50.413325,
    "lon": 7.577921,
    "path": "bendorf-radweg-mit-treppe",
    "previewimage": "IMG_20210901_124018.jpg",
    "title": "Radweg mit Treppe in Bendorf"
  }
]

Und dann kann ich noch ein bisschen JavaScript schreiben, das daraus dann Marker erzeugt. Von JavaScript habe ich wirklich sehr wenig Ahnung, daher ist das einfach nur so mit Gewalt.

var set_markers = function(data) {
    for (var i in data) {
        var elem = data[i];
        L.marker([elem.lat, elem.lon]).addTo(map)
            .bindPopup(`<a href="/posts/${elem.path}/">${elem.title}</a><br />${elem.date}<br />${elem.category}`);
    }
};

fetch('data.json')
.then(res => res.json())
.then(set_markers)

Aber es funktioniert. Auf der Karte ist jetzt ein Marker:

Und wenn man den anklickt, so geht auch das Pop-Up auf:

Der Link zum Blogeintrag funktioniert auch. Alles wunderbar! Jetzt müssen nur noch die ganzen Blogeinträge nachgetragen werden.

Das fertige Ergebnis kann unter Pages → Karte angeschaut werden. Viel Spaß damit!