2. Tutorial: Where am I? Geolocation on a leaflet Map

Geolocation in a web browser uses access to a GPS in a mobile device to locate the device, or it can fall back on wifi or other signals used by the device, but the latter are often not accurate.

The browser requires the user to allow the use of geoloaction, and also prevents third party scripts from running, to improve the security.

Geolocation provides JavaScript with the lattitude and longitude of the location, and we can then use that to display a marker on a map.

This frame shows a live view of the map we are creating:

The HTML code

The head of the HTML document includes the links to access the leaflet.js and  leaflet.css files which we have downloaded from leafletjs.com and then uploaded to our own server.

Then in the body a div gives an id to the map and defines the space for it on the web page.

The map and its details is then created by our own script: where-am-I-leaf-map.js which is linked at the end of the HTML document so that it doesn't run before the map div has been created.

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" type="text/css" href="leaflet.css" />
    <script type='text/javascript' src='jquery.min.js'></script>
    <script type='text/javascript' src='leaflet.js'></script>
</head>
<body>
    <h2>Geolocation on a Leaflet Map</h2>
<p>Click the button to display your coordinates. Note that not all devices can access your location</p>
<p>You will need to allow the device to access your location</p>
<p><button onclick="whereAmI()">Where am I</button></p>
<div id="demo"></div>
<div id="map" style="width: 800px; height: 440px; border: 1px solid #AAA;"></div>
    <script type='text/javascript' src='where-am-I-leaf-map.js'></script>
</body>
</html>
 

The JavaScript code

The code starts by initialising the map but without any tile layer so that nothing is displayed.

 
map = L.map('map', {
    center: [0, 0],
    minZoom: 2,
    zoom: 12
})
/*
When the button on the HTML page is clicked it calls the function whereAmI().
This checks if !navigator.geolocation is available, and if successful returns the lattitude and longitude coordinates. These coordinates are then passed to the function makeMyMap(latitude, longitude);
*/
 
function whereAmI() {
    var myresult = document.getElementById("demo");
    if (!navigator.geolocation) {
        myresult.innerHTML = "<p>Geolocation is not supported by your browser</p>";
        return;
    }
 
    function success(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        myresult.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>';
        makeMyMap(latitude, longitude);
    }
 
    function error() {
        myresult.innerHTML = "Unable to retrieve your location";
    }
    myresult.innerHTML = "<p>Locating…</p>";
    navigator.geolocation.getCurrentPosition(success, error);
}
/*
The function accepts these values as mylat, mylong and now pans the map to this location. It then adds the tile layer, so that the map becomes visible at this location.
*/
function makeMyMap(mylat, mylong) {
    map.panTo(new L.LatLng(mylat, mylong), 12);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 17,
        attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
    }).addTo(map);
/*
Next, we add a marker at the same location with a popup to display the You are here! message.
*/
    L.marker([mylat, mylong]).addTo(map)
        .bindPopup("<b>You are here!</b>").openPopup();
/*
We can also add a circle round this location:
*/
    L.circle([mylat, mylong], 500, {
        color: 'red',
        fillColor: '#f2d5df',
        fillOpacity: 0.2
    }).addTo(map).bindPopup("");
    var popup = L.popup();
/*
Sometimes we may want to identify the coordinates of a different location on the map, and the line map.on('click', onMapClick) enables this. The function onMapClick(e) allows us to make something happen when the map is clicked. In this example it displays the coordinates of the click.
*/
    function onMapClick(e) {
        popup
            .setLatLng(e.latlng)
            .setContent("You clicked the map at " + e.latlng.toString())
            .openOn(map);
    }
    map.on('click', onMapClick);
 
/*
In this tutorial we haven't used our code to add markers from an array.
*/
    for (var i = 0; i < markers.length; ++i) {
        L.marker([markers[i].lat, markers[i].lng], {
            icon: new L.DivIcon({
                className: 'my-div-icon',
                html: '<span class="my-map-label">' + markers[i].name + '</span>'
            })
        }).addTo(map);
 
        L.marker([markers[i].lat, markers[i].lng]).addTo(map)
            .bindPopup(markers[i].name);
 
 
 
    }
}