Leaflet und GeoJSON-Daten

Keine Kommentare

Heute zeige ich euch, wie man mittels der JavaScript-Bibliothek Leaflet GeoJSON-Daten auf einer Karte in eigenen Anwendungen darstellen kann. Wie man dies mittels des Google Maps JavaScript API macht, habe ich in diesem Beitrag erklärt. Wir werden den gleichen Use Case nun mit Leaflet umsetzen.

Leaflet

Grundsätzlich gestaltet sich die Nutzung von Leaflet sehr einfach. Im Gegensatz etwa zum Google Maps JavaScript API kann Leaflet unter anderem auch das Kartenmaterial von Open Street Map einbinden, so dass wir ohne API-Key arbeiten können.

Unser minimales Beispiel sieht so aus, dass wir ein DIV-Element definieren, auf dem Leaflet dann die OSM-Karte darstellt. Im Header-Bereich binden wir Stylesheets und das Script für Leaflet ein:

<head>
  <title>Leaflet and GeoJSON</title>
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css"
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
crossorigin=""></script>
</head>

Unser Body besteht im Wesentlichen aus dem DIV für die Map und einer JavaScript-Funktion:

<body>
<h1>Leaflet and GeoJSON</h1>
<div id="map" style="width: 600px; height: 400px;"></div>
<script>
  window.onload = function() {
    // set up the map
    var map = new L.Map('map');
    var osm = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      minZoom: 0,
      maxZoom: 20,
      attribution: 'Map data &copy; <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'
    });
 
    // define view
    map.setView(new L.LatLng(49.451993, 11.073397), 5);
    map.addLayer(osm);
</script>
</body>

Wir erzeugen ein Objekt map, das die Map und eins, das den OSM-Karten-Layer (osm) repräsentiert. Durch den Aufruf map.setView(…) legen wir den Mittelpunkt der Karte und den initialen Zoom-Faktor fest. Beim Zoom-Faktor gilt: je größer, desto „tiefer“ zoomt man in die Karte.

Das Ergebnis kann dann so aussehen:

Leaflet Map

Im Folgenden werden wir nun sukzessive die Funktion window.onload erweitern, um weitere Funktionalität zu ergänzen.

GeoJSON

Wir stellen eine GeoJSON-Datei ccbranches.geojson mit den Niederlassungen der codecentric AG dar, die auch bereits in meinem GeoJSON-Tutorial als Beispiel für einen MultLineString diente.

Die Integration von GeoJSON-Daten in Leaflet kann über eins der Plugins erfolgen, die GeoJSON-Dateien verarbeiten können. Um mir aber eine weitere Abhängigkeit zu sparen, führe ich selber einen entsprechenden AJAX-Request aus (mehr machen die Plugins auch nicht) und füge die Antwort als als GeoJSON-Layer ein:

window.onload = function() {
  ...
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'ccbranches.geojson');
  xhr.setRequestHeader('Content-Type', 'application/json');
  xhr.onload = function() {
    if (xhr.status === 200) {
      L.geoJSON(JSON.parse(xhr.responseText)).addTo(map);
    }
  };
  xhr.send();
}

Standardmäßig werden GeoJSON-Punkte als blaue Marker gerendert, Linien ebenso:

Leaft GeoJSON

Darstellung der GeoJSON-Daten anpassen

Das geht noch besser, indem wir Styling-Informationen ergänzen. Ein eigenes Icon für die Marker und die Farbe der Linie passen wir an, indem wir der Function L.geoJSON(…) weitere Parameter übergeben:

window.onload = function() {
   ...
 
   // CC Icon
   var ccIcon = L.icon({
      iconUrl: 'cc-logo-black.png',
      iconSize: [35, 35],
      iconAnchor: [17, 17],
      popupAnchor: [0, -28]
   });  
 
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'ccbranches.geojson');
  xhr.setRequestHeader('Content-Type', 'application/json');
  xhr.onload = function() {
    if (xhr.status === 200) {
    	L.geoJSON(JSON.parse(xhr.responseText), {
	   // Marker Icon
	   pointToLayer: function (feature, latlng) {
	      return L.marker(latlng, {icon: ccIcon});
	   },
	   // Style
	   style: function(feature) {
	      return {color: '#808080', width:2};
	   }
	}).addTo(map);
    }
  };
  xhr.send();
}

Die Karte sieht nun so aus:

Leaflet GeoJSON Styles

Schnell mal ein Popup

Beim Klick auf einen Marker sollen nun noch bestimmte Properties des jeweiligen GeoJSON-Features (in unserem Fall Name der Niederlassung und Adresse) angezeigt werden. Dazu verwenden wir das Standard-Popup von Leaflet, das für viele Anwendungsfälle bereits ausreichen sollte, da es frei definierbare HTML-Snippets beinhalten kann. Dazu müssen wir nur eine weitere Funktion als Parameter übergeben:

L.geoJSON(JSON.parse(xhr.responseText), {
	// Marker Icon
	pointToLayer: function (feature, latlng) {
   	return L.marker(latlng, {icon: ccIcon});
	},
	// Style
	style: function(feature) {
		return {color: '#808080', width:2};
	},
	// Popup
	onEachFeature: function (feature, layer) {
		layer.bindPopup("<b>" + feature.properties.name + '</b><br />'
			+ feature.properties.address);
	}
}).addTo(map);

Bei einem Klick auf einen Marker sehen wir dann ein Popup:

Leaflet GeoJSON Popup

Zusammenfassung

Wir haben gesehen, wie man Leaflet zur Darstellung von Karten nutzen kann. Eigene Geo-Daten im GeoJSON-Format sind extrem einfach einzubinden, wobei die Darstellung noch anpassbar ist. Interaktionen mit den Geometrien haben wir am Beispiel eines einfachen Popups demonstriert.

Die vollständigen Code-Beispiele gibt es in meinem GitHub-Repository ttrelle/geojson-examples.

Einfach dieses Repository klonen und den Inhalt des Ordners docroot als statischen Content in einen Web-Server werfen. Noch einfacher geht es mit dem beiliegenden docker-compose.yml:

$ docker-compose up

Und schon ist das vollständige Beispiel abrufbar unter

http://localhost:8080/leaflet.html
Tobias Trelle

Diplom-Mathematiker Tobias Trelle ist Senior IT Consultant bei der codecentric AG, Solingen. Er ist seit knapp 20 Jahren im IT-Business unterwegs und interessiert sich für Software-Architekturen und skalierbare Lösungen. Tobias hält Vorträge auf Konferenzen und Usergruppen und ist Autor des Buchs „MongoDB: Ein praktischer Einstieg“.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.