leaflet.js mit dem Plugin leaflet-omnivore zeigt GPX-Daten auf dieser Seite an
Home » Equipment » Navigation
Schon 2012 hatte ich mit GPX-Daten experimentiert. Damals noch alles händisch nachträglich daheim erfasst, denn meine Digitalkameras aus dieser Zeit hatten keine GPS-Erfassung. Da mir das alles zu zeitaufwändig war, habe ich mich nicht mehr weiter damit beschäftigt.
Inzwischen ist die Erfassung der GPS-Daten bei Bildern dank der in wohl jedem Schmarrnfon integrierten Option viel einfacher. Ich nutze für das Beispiel auf dieser Seite die Daten, welche ich aus EXIF-Informationen meiner während der Tour gemachten Bilder ausgelesen habe. Daher ist der heutige Beitrag als dritter Teil meiner »GPX-HowTos« zu verstehen.
Der erste Teil »GPX-Daten: Track aus EXIF-Daten in Bildern erstellen« und der gestrige zweite Teil »GPX-Daten: Track korrigieren « beschreiben, wie man mit gpsbabel eine GPX-Datei aus den Bildern generieren und etwaige Fehler im »unechten« Track mit gpx.studio korrigieren kann.
Es fehlte nur noch der letzte Teil, nämlich wie man diesen Track dann schön in eine Website einbinden kann. Nicht als Screenshot, sondern als zoombaren Karte.
Weil ich meine Website zu 100 Prozent selbst mache, also kein CMS wie WordPress, TYPO3 oder Drupal verwende, kann ich mir alles so einbauen, wie es mir gefällt.
Oder anders gesagt: Ich muss mir immer alles selber zusammenbauen, weil ich nicht einfach ein Modul für ein CMS einbauen kann, was die Funktion anbietet. 🙄
Wie geht das einfach und möglichst DSGVO-konform? Mit leaflet.js, einer sehr benutzerfreundlichen JavaScript-Bibliothek. Interaktive Karten können damit nahtlos in Websites eingebunden werden.
Dank vieler Plugins lässt sich leaflet.js mit minimalem Aufwand erweitern, um beispielsweise Markierungen, Pop-ups oder eigene Kartenebenen hinzuzufügen.
Die Bibliothek zeichnet sich dabei durch minimalem Ressourcenverbrauch aus, obwohl komplexe Geodaten visualisiert werden.
Der »Allesfresser« leaflet-omnivore.js ist ein sehr nützliches Plugin für leaflet.js, welches darauf ausgelegt ist, eine Vielzahl von unterschiedlichen Geodaten-Formaten in eine per leaflet.js eingebundene Karte zu laden.
Anstatt für jedes Format einen eigenen Parser schreiben zu müssen, bietet das Plugin eine einheitliche Schnittstelle, um folgende Formate direkt in eine Karte zu integrieren:
Das Plugin ist clever, denn es erkennt die Daten automatisch und wandelt sie in ein Layer-Objekt um. Dieses Layer-Objekt kann direkt auf einer Karte anzeigen werden.
Da mit GPX-Daten schon vorliegen, kann ich diese einfach mit dem »Allesfresser« auf eine Karte einbinden.
Nach so viel Text erst einmal ein Bild. So sieht leaflet.js mit den von mir gestern erstellten GPX-Daten aus:
Es ist ein Screenshot, daher nicht interaktiv. Es wurde auch nichts weiter an den GPX-Daten verändert, daher werden alle Marker gesetzt. Die Marker sind die Positionen, an denen die dazugehörigen Bilder gemacht wurden.
Kann man das noch aufhübschen? Ja, aber erst einmal wie die Karte eingebunden wird, mit dem dazugehörigen HTML- und JavaScript-Code. Danach wird die Darstellung noch deutlich aufgehübscht, versprochen. 😉
Ich nutze für meine Website W3.CSS, ein kostenloses, quelloffenes CSS-Framework. Es wurde von w3schools.com entwickelt. Mit W3.CSS können moderne, reaktionsfähige (responsive) Websites erstellt werden.
Daher finden sich im Beispielcode Klassenbezeichnungen wie »w3-row« oder »w3-margin-top«. Wer kundig in HTML und CSS ist, kann es sich für seine Zwecke anpassen. Wer ein leflet.js-Plugin für sein CMS verwendet, hat vielleicht über die darüber verfügbaren Optionen Möglichkeiten der Individualisierung.
Meine Lösung, wie ich die Karte auf dieser Seite einbinde, zunächst der HTML-Code:
<div id="mapid"
class="w3-row w3-margin-top"
style="position:relative;
padding-bottom:80%;
height:0;">
<div style="position:absolute;
top:0;
left:0;
width:100%;
height:100%;">
</div>
</div>Damit das <div> eine Höhe von 80 % der Breite hat, musste ich ein wenig Tricksen.
Der Trick funktioniert so: Das äußere <div> hat height:0 – es hat also von sich aus keine Höhe. padding-bottom in Prozent bezieht sich in CSS aber immer auf die Breite des Elements, nicht auf die Höhe. Mit padding-bottom:80% erzwingt man also eine Höhe, die immer 80% der aktuellen Breite beträgt – und das responsive, ganz ohne JavaScript.
Das innere <div> mit position:absolute füllt dann diesen durch das Padding erzeugten Raum vollständig aus (top:0; left:0; width:100%; height:100%). leflet.js bekommt so ein Element mit echter Pixelgröße, in das es die Karte rendern kann.
Ohne diesen Trick müsste ich der Karte eine feste Höhe in Pixeln geben, die sich dann aber nicht mit der Seitenbreite mitskaliert. Das Verhältnis von 10:8 erklärt auch die Größe des Screenshots: 652x522 px. Ich wollte kein Quadrat haben, daher das Verhältnis von 10:8.
Der dazugehörigige JavaScript-Block mit meinen Kommentaren:
Bei den Angaben von Breitengrad, Längengrad und Zoomfaktor bei »setView« muss man ein wenig experimentieren. Dies ist immer individuell. Die Koordinaten, wie man seine Karte zentrieren will, kann man sich beispielsweise mit gpx.studio per Rechtsklick und dann einfach »Koodinaten kopieren« besorgen:
Man braucht nicht sieben Stellen hinter dem Punkt, es reichen auch schon zwei völlig aus.
Die Karte sieht leider nicht ganz so schick aus, wenn die ganzen POI von den Bildern erscheinen? Die POI befinden sich in der GPX-Datei, welche ich mit gpsbabel anhand der Bilder habe generieren lassen. Man muss jetzt die GPX-Datei nicht überarbeiten, denn die POI lassen sich beim Aufruf herausfiltern. Dazu muss der Aufruf von omnivore geändert werden.
Hier der JavaScript-Block, in dem alle POI-Informationen aus den GPX-Daten beim Laden herausgefiltert werden:
Der Unnterschied im direkten Vergleich, zunächst ein Screenshot mit den ganzen POI:
Mit dem veränderten JavaScript-Block sieht die Darstellung so aus:
Warum ich diesen Weg gewählt habe? Ich möchte die GPX-Datei nicht noch einmal bearbeiten. Vielleicht will ich ja später einmal die Daten mit den Bilddaten-Wegpunkten anderweitig verwenden? Dann müsste ich sie mir erneut generieren lassen.
Vielleicht möchte man ja eigene POI einbinden? Nur die auf der Tour angefahrenen Passknacker-Nachweispunkte oder auch schöne Bilder einbinden, welche man unterwegs aufgenommen hat?
Es ist einfach umzusetzen, wenn ein Bild eingeblendet werden soll. Dafür muss im JavaScript-Block lediglich noch ein Eintrag für den POI hinzugefügt werden:
var marker = L.marker([48.031874, 8.750276])
.addTo(mymap)
.bindPopup(`
<div style="text-align:center; width:200px;">
<img src="/images/foobar.jpg"
style="width:100%; border-radius:4px;">
<p><strong>Weilheimer Berg</strong></p>
<p class="w3-small">26. Nachweispunkt am 9. April 2026</p>
</div>
`); Ich betone dabei, dass die GPX-Datei unverändert bleibt. Der neu eingefügte POI wird per leflet.js eingefügt.
Text und Bild wurden in dem Codebeispiel definiert und erscheinen beim Anklicken des POI.
Man kann auch ein eigenes Icon verwenden, wenn einem der originale Marker nicht gefällt.
Weil ich schon eine Idee hatte, wie ich POI nutzen möchte, habe ich zwei Varianten ausprobiert. Beide Varianten stelle ich in diesem Abschnitt vor.
Man kann zum Beispiel ein eigenes Bild als Marker verwenden:
var myIcon = L.icon({
iconUrl: '/images/foobar-marker.png',
iconSize: [32, 32],
iconAnchor: [16, 32],
popupAnchor: [0, -32],
className: ''
});Oder ein Emoji als Schriftzeichen, zum Beispiel das »Hundegesicht«:
var myIcon = L.divIcon({
html: '<span style="font-size:2em;">🐶</span>',
iconSize: [32, 32],
iconAnchor: [16, 32],
popupAnchor: [0, -32],
className: ''
});Das Hundegesicht ist jetzt nicht unbedingt optimal für einen Marker, aber er erinnert (mit viel Phantasie) entfernt an die pässeknackende amerikanische Bulldogge, welche im Logo von Passknacker.com zu sehen ist.
Schicker wird es natürlich mit einer »echten« Bulldogge. 😉
Das originale Passknacker-Maskottchen wollte ich nicht verwenden, daher habe ich einen Hundekopf ohne Copyright (KI-generiert) ein wenig bearbeitet, jetzt kann er als Marker für meine Nachweise dienen:
Auf die Art kann man im Overlay beispielsweise zwischen Nachweisfotos und anderen Bildern unterscheiden.
Im Screenshot sind als Beispiel ein Passknackernachweis und ein Bild zu sehen. Das Bild wurde mit dem Kamera-Emoji gekennzeichnet:
Man könnte jetzt noch weitere POI mit anderen Markern einfügen, man kann sich hier richtig kreativ ausleben. 😊
Ich nutze fancybox damit die Bilder beim Anklicken den ganzen Bildschirm ausfüllen. Wäre doch schön, wenn das auch mit den Bildern funktioniert, welche in der eingebundenen Karte in Thumbnailgröße zu sehen sind?
Nichts leichter als das! Der Eintrag für den POI muss nur entsprechend erweitert werden:
var marker = L.marker([48.031874, 8.750276], {icon: myIconPassknacker})
.addTo(mymap)
.bindPopup(`
<div style="text-align:center; width:200px;">
<a data-fancybox
data-caption="Weilheimer Berg"
href="/images/foobar.jpg">
<img src="/images/foobar-vorschau.jpg"
style="width:100%; border-radius:4px;">
</a>
<p><strong>Weilheimer Berg</strong></p>
<p class="w3-small">26. Nachweispunkt am 9. April 2026</p>
</div>
`);Klickt man auf den Thumnail, wird das Bild – wie auch sonst überall auf meiner Seite – geöffnet, dabei vergrößert dargestellt und gleichzeitig der Hintergrund abgedunkelt.
Das ist doch schon alles, was man braucht? Vor ein paar Jahren hätte das schon gereicht. Weil Daten zum OpenStreetMap-Server beim Aufruf der Karte übertragen werden und das wegen der DSGVO von mir erst nach aktiver Zustimmung erfolgen soll, habe ich noch etwas drumherum gebaut.
Die Karte soll erst dann aufgerufen werden, wenn der Button angeklickt wird. Daher wurde der HTML-Code noch einmal etwas erweitert.
So sieht da Resultat aus, welches auf allen meinen Seiten zu finden sein wird wenn ich weiter von meinen Touren mit einem »unechten« Track berichte. Erst nach dem Klick kommt die Karte mit den Daten vom OpenStreetMap-Server:
🗺️ Karte anzeigen lassen
Durch den Aufruf werden Daten an OpenStreetMap übertragen.

Damit keine Verwirrung aufkommt: Das Höhenprofil ist ein Bild, welches ich per Export aus GPXSee generiert habe. Weil es von mir selber gehostet wird, erscheint es schon vor dem Laden der Karte.
So sieht der um die DSGVO-konforme Lösung erweiterte HTML-Block (mit W3.CSS) aus:
<div id="mapid"
class="w3-row w3-margin-top"
style="position:relative;
padding-bottom:80%;
height:0;">
<!-- Consent-Overlay -->
<div id="map-consent"
style="position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:#e8e8e8;
display:flex;
align-items:center;
justify-content:center;
cursor:pointer;
z-index:1000;"
onclick="loadMap()">
<div style="text-align:center;">
<p>
<span style="font-size:6em;">🗺️</span>
<strong>Karte anzeigen lassen</strong>
</p>
<p class="w3-small">
Durch den Aufruf werden Daten an
OpenStreetMap übertragen.
</p>
<button class="w3-button w3-dark-grey w3-round">
Karte anzeigen
</button>
</div>
</div>
</div>Fertig? Ja, fertig. Zumindest dieses HowTo wie ich die Einbindung der OSM-Karte mit den GPX-Daten hier in meinem Blog gelöst habe. 😉
Das Einbinden von GPX-Daten ist relativ einfach möglich. Wenn man die Daten schon hat, kann man mittels leaflet.js den (»unechten«😉 Track einbinden und sogar mit eigenen POI versehen.
Was für mich jetzt noch als ToDo für ein nächstes HowTo zu erledigen ist: Wie kann ich mir die Passknacker-POI als Blöcke für den JavaScript-Code möglichst einfach generieren lassen? Die KI wird mir dabei bestimmt helfen. 😉
Bis zu zehn POI händisch zu schreiben nimmt ein wenig Zeit in Anspruch. 31 Nachweise wie bei der Tour vom 9. April schon etwas mehr. Da die Waypoint-Informationen mit gpsbabel ausgelesen werden konnten, drängt sich ein Scipt dafür aber regelrecht auf. Ich müsste dann nur noch 31 mal den Namen Eintragen, den Namen vom Bild und den Dateinamen habe ich ja schon. Kommt Zeit, kommt Script. 😎
Deine E-Mailadresse wird nicht veröffentlicht.
Autor:
Teilen:
Weitere Artikel des Autors:





Das könnte Sie auch interessieren:
Diese Website wurde erstellt mit: Bluefish, Kate, Geany und Gimp. Neben HTML kommt Markdown zum Einsatz und das alles unter CachyOS als Betriebssystem. 😊
Bildnachweis: Kate Editor Logo von Tyson Tan, lizenziert unter CC BY-SA 4.0.
Das Generieren dieser Seite dauerte genau 0.04658 Sekunden.
Kommentare
Dieser Beitrag hat noch keine Kommentare erhalten.