0

I would like to create a simple Leaflet app that zooms to the user location, and also to a location defined within the geocode search bar. Secondly, the app should show the shortest route between the two locations, like the way Google Map functions. I have managed to fulfill the first objective and partially the second. However, even though I am following examples as in the Leaflet Routing Machine app, the shortest route between the two locations (user and geocoded search) is not being rendered on the map. I know that to simply render a route using the routing.machine plugin is:

L.Routing.control({
            waypoints: [
                L.latLng(lat, lon), // User's location
                L.latLng(geocodedLat, geocodedLon) // Geocoded location
            ]
        }).addTo(map);

This initially did not work, and asking ChatGPT for solutions to the discrepancy added other if statements that in the end, weren't helpful. Here is my code:

<!DOCTYPE html>
<html>

<head>
    <title>Geolocation</title>
    <!-- Mobile view -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <!-- Mobile view -->

    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />

    <!-- Leaflet search -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" />
    
    <!-- Leaflet routing machine css -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet-routing-machine@latest/dist/leaflet-routing-machine.css" />

    <!-- Leaflet routing -->
    <link rel="stylesheet" href="./LeafletControlRouteToAddress-master/dist/v1/LeafletControlRoutingtoaddress.css" />

    <!-- Leaflet routing machine -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet-routing-machine/3.0.3/leaflet-routing-machine.css" />
    <!-- Leaflet routing machine -->

    <!-- Leaflet routing -->
    
    <!-- Leaflet routing machine js -->
    <!-- <script src="https://unpkg.com/leaflet-routing-machine@latest/dist/leaflet-routing-machine.js"></script>
    <script src="D:\gachuhi\vs_code\geolocation\routing\Leaflet.LocationShare-master\Leaflet.LocationShare.js"></script> -->

    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script src="https://unpkg.com/leaflet-routing-machine@latest/dist/leaflet-routing-machine.js"></script>
    <script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
    <script src="./LeafletControlRouteToAddress-master/dist/v1/LeafletControlRoutingtoaddress.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-routing-machine/3.0.3/leaflet-routing-machine.js"></script>
    <style>
        body {
            margin: 0;
            padding: 0;
        }
    </style>

</head>

<body>
    <div id="map" style="width:100%; height: 100vh"></div>

    <script>
    
    var map = L.map('map').setView([-1.297221, 36.829702], 11);
    mapLink = "<a href='http://openstreetmap.org'>OpenStreetMap</a>";
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: 'Leaflet &copy; ' + mapLink + ', contribution', maxZoom: 18 }).addTo(map);

    L.Control.geocoder().addTo(map);

    map.locate({ setView: true, maxZoom: 16 });

    var lat, lon; // Variables to store user location
    var geocodedLat, geocodedLon; // Variables to store geocoded location

    function onLocationFound(e) {
        lat = e.latlng.lat;
        lon = e.latlng.lng;

        var radius = e.accuracy;
        L.marker(e.latlng).addTo(map)
        .bindPopup("You are within " + radius + " meters from this point").openPopup();
        L.circle(e.latlng, radius).addTo(map);

        // Create a routing control after obtaining both locations
        if (geocodedLat !== undefined && geocodedLon !== undefined) {
            createRoutingControl();
        }
    }

    map.on('locationfound', onLocationFound);
    
    function onLocationError(e) {
        alert(e.message);
    }

    map.on('locationerror', onLocationError);

    map.on('geocoded', function(e) {
        geocodedLat = e.latlng.lat;
        geocodedLon = e.latlng.lng;

        // Create a routing control after obtaining both locations
        if (lat !== undefined && lon !== undefined) {
            createRoutingControl();
        }
    });
    
    function createRoutingControl() {
        L.Routing.control({
            waypoints: [
                L.latLng(lat, lon), // User's location
                L.latLng(geocodedLat, geocodedLon) // Geocoded location
            ]
        }).addTo(map);
    }

    </script>


</body>

</html>

How can I display the shortest route layer on my map?

0

1 Answer 1

0
  • To catch geocoder event when location is found you can use markgeocode geocoder control event.
  • To prevent default geocoder action you can use defaultMarkGeocode: false option.
  • To zoom on route found by router you can use fitSelectedRoutes: true router control option.

Relevant part of the code could then look something like this:

var lat, lon;
var geocodedLat, geocodedLon;

var geocoderControl = L.Control.geocoder({
  defaultMarkGeocode: false
}).addTo(map);

geocoderControl.on('markgeocode', function(e) {
  geocodedLat = e.geocode.center.lat;
  geocodedLon = e.geocode.center.lng;

  if (lat !== undefined && lon !== undefined) {
    createRoutingControl();
  }
});

map.locate({ setView: true, maxZoom: 16 });

function onLocationFound(e) {
  lat = e.latlng.lat;
  lon = e.latlng.lng;

  var radius = e.accuracy;
  L.marker(e.latlng).addTo(map)
  .bindPopup("You are within " + radius + " meters from this point").openPopup();
  L.circle(e.latlng, radius).addTo(map);

  if (geocodedLat !== undefined && geocodedLon !== undefined) {
    createRoutingControl();
  }
}

map.on('locationfound', onLocationFound);

function onLocationError(e) {
  alert(e.message);
}

map.on('locationerror', onLocationError);

function createRoutingControl() {
  L.Routing.control({
    waypoints: [
      L.latLng(lat, lon), // User's location
      L.latLng(geocodedLat, geocodedLon) // Geocoded location
    ],
    fitSelectedRoutes: true
  }).addTo(map);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.