DEV Community

Cover image for Leaflet onClick event
Allan Simonsen
Allan Simonsen

Posted on

Leaflet onClick event

In the previous post we added distance markers to our GPS track to see where on the route we passed the distances.
But what if we want to know exactly how far along the route a given point is?
We want to be able to click on the track and calculate how long the distance was from the starting point to the point we clicked on in the map. That is what I will show how to implement based on the code from the previous posts and it turns out that Leaflet let us do this fairly easily.

The on-click event on the polyline we use to draw the track on the map, returns the latitude and the longitude of the point you clicked. We use these coordinates to find the the index of point on our track closest to these coordinates. This index we use to sum the length of each section of the track polyline until we get to that index.
Finally we add a marker to the map with the distance in meters from start until the clicked point on the track.

So all the code for this feature is implemented in JavaScript so no changes to the Python script this time. You can see the new code below.

const polyline = L.polyline(track, {color: 'blue'}).addTo(myMap);
var highlightMarker = undefined;
polyline.on('click', function(e) {
  const closestIdx = findPointIdxOnPolyline(track, e.latlng);
  const trackLength = lengthOfTrack(track, closestIdx);
  if(highlightMarker != undefined) {
    myMap.removeLayer(highlightMarker);
  }
  highlightMarker = L.marker(track[closestIdx], {icon: L.divIcon({ html: '<span style="font-size: 20px; font-weight: bold">' + Math.round(trackLength) + 'm</span>' })}).addTo(myMap);
});

function findPointIdxOnPolyline(track, latlng) {
  let prevDiffLat = prevDiffLng = 99999;
  let closestIdx = 0;
  for(var i = 0; i < track.length; i++) {
    var diffLat =  Math.abs(track[i][0] - latlng.lat);
    var diffLng = Math.abs(track[i][1] - latlng.lng);
    if(diffLat + diffLng < prevDiffLat + prevDiffLng) {
      prevDiffLat = diffLat;
      prevDiffLng = diffLng;
      closestIdx = i;
    }
  }
  return closestIdx;
}
function lengthOfTrack(track, idx) {
  var length = 0;
  for(var i = 1; i < track.length && i < idx; i++) {
    let from = L.latLng(track[i-1]);
    let to = L.latLng(track[i]);
    length += from.distanceTo(to);
  }
  return length;
}
Enter fullscreen mode Exit fullscreen mode

I hope you found this useful or that it might inspire you to experiment with Leaflet yourself. If so, leave a like and consider having a look at the previous posts in this series.

For the entire code, check out the previous article and clone the repository with the code from the GitHub repository gpx-to-leaflet.

Leaflet click event

Top comments (0)