Gestern schrieb ich in einem Artikel, wie Adressen aus Koordinaten mittels des Dienstes Nominatim, unter Zuhilfenahme von OpenStreetMap-Daten, ermittelt werden können. Mithilfe der freien Bibliothek Leafleat, kann dies nun in eine kleine Webapplikation gegossen werden.
Ziel ist es eine Applikation zu bauen, welche eine Karte darstellt und bei einem Klick auf diese Karte den Geocoding-Dienst anfragt. Sobald die Antwort vom Dienst eingetroffen ist, soll in einem Pop-up die Adresse dargestellt werden. Nachdem ein Grundgerüst in Form einer HTML-Datei erstellt wurde, werden dort die benötigten Bibliotheken (Leaflet und jQuery) eingebunden. Anschließend kann die Karte erzeugt werden. Damit diese im Vollbild dargestellt wird, findet sich eine entsprechende CSS-Definition in der Datei:
<style type="text/css"> body { padding: 0; margin: 0; } html, body, #map { height: 100%; } </style>
Anschließend kann der TileLayer angelegt werden und der Map zugewiesen werden:
// Options var centerLatitude=53.49577; var centerLongitude=13.30873; var zoomLevel=15; // Define layer var openStreetMapLayer = new L.TileLayer( 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: '<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>'}); // Define map var map = L.map('map', { center: new L.LatLng(centerLatitude, centerLongitude), zoom: zoomLevel, layers: [openStreetMapLayer] });
Für die Karte muss im nächsten Schritt ein Click-Event definiert werden, welches den AJAX-Request gegen den Geocoding-Dienst auslöst und den Marker erstellt. Der jeweilige Marker wird in eine separate Ebene gepackt und beim nächsten Klick wieder gelöscht und anschließend ein neuer Marker erstellt:
// Marker managment var markerLayer; map.on('click', function(e){ // Console debug var coord = e.latlng; var lat = coord.lat; var lng = coord.lng; console.log("You clicked the map at latitude: " + lat + " and longitude: " + lng); // Marker managment if(markerLayer != undefined) { map.removeLayer(markerLayer); } markerLayer = new L.Marker(e.latlng); map.addLayer(markerLayer); // Call geocode api var request = $.ajax({ method: "GET", url: "https://nominatim.openstreetmap.org/reverse?lat=" + lat + "&lon=" + lng + "&format=json" }); request.done(function( json ) { console.log(json); markerLayer.bindPopup(json.display_name).openPopup(); }); });
Am Stück sieht die Applikation wie folgt aus:
<!DOCTYPE html> <html> <head> <title>Leaflet address encoder</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/> <style type="text/css"> body { padding: 0; margin: 0; } html, body, #map { height: 100%; } </style> <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" crossorigin=""></script> <script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script> </head> <body> <div id="map"></div> <script> // Options var centerLatitude=53.49577; var centerLongitude=13.30873; var zoomLevel=15; // Define layer var openStreetMapLayer = new L.TileLayer( 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: '<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>'}); // Define map var map = L.map('map', { center: new L.LatLng(centerLatitude, centerLongitude), zoom: zoomLevel, layers: [openStreetMapLayer] }); // Marker managment var markerLayer; map.on('click', function(e){ // Console debug var coord = e.latlng; var lat = coord.lat; var lng = coord.lng; console.log("You clicked the map at latitude: " + lat + " and longitude: " + lng); // Marker managment if(markerLayer != undefined) { map.removeLayer(markerLayer); } markerLayer = new L.Marker(e.latlng); map.addLayer(markerLayer); // Call geocode api var request = $.ajax({ method: "GET", url: "https://nominatim.openstreetmap.org/reverse?lat=" + lat + "&lon=" + lng + "&format=json" }); request.done(function( json ) { console.log(json); markerLayer.bindPopup(json.display_name).openPopup(); }); }); </script> </body> </html>
Alternativ kann der Quelltext heruntergeladen bzw. ausprobiert werden.