Adding distance markers to your Leaflet map
Tags: leaflet, gpx, javascript, python
Published: 2021-01-26 13:16:38

In my previous posts in this series I used a Python script to generate a html page with JavaScript to generate a map using the Leaflet JavaScript library to visualize your hiking track and calculated the distance and the duration of the hike.

In this article I will show how to add distance markers to the leaflet map so you can see where you passed 1 kilometer, 2 kilometer and so on for the whole track.

To do this we introduce a new class DistanceMarker in our script that holds the latitude, longitude and a label for the marker. We then extend our existing Track class to have a property of this new DistanceMarker class.

```python
class DistanceMarker:
    def __init__(self, latitude, longitude, label):
        self.latitude = latitude
        self.longitude = longitude
        self.label = label

    def toJsString(self):
        return f"""
            L.marker([{self.latitude},{self.longitude}], {{
              icon: L.divIcon({{ html: '<span style="font-size: 20px; font-weight: bold">{self.label}</span>' }})
            }}).addTo(myMap);"""
```

As you can see we also added a method to the class for converting the distance marker object into the JavaScript code we need to add a Leaflet marker to the map.

The algorithm we use to figure out when to create a new marker and add it to our Track object is by simply looking at the current track distance which we update for each new point we read from the gpx track file. The trick to knowing when to add a new marker is to convert the distance to an integer and then when the integer changes we know we have passed another kilometer on our track.

This is the implementation of the algorithm we added to the load_track method:
```python
prevDistance = 0

...

if(int(current_track.distance) > prevDistance):
	prevDistance = int(current_track.distance)
	newDistanceMarker = DistanceMarker(point.latitude, point.longitude, f"{int(prevDistance)}km")
	current_track.distanceMarkers.append(newDistanceMarker)
```

We also need a small change to the code generating the html so we can convert the list of DistanceMarker objects in our internal Track object to JavaScript. This is done by this method we have added to the Track class:

```
    def distanceMarkersToJsStr(self):
        return "\n".join(map(lambda marker: marker.toJsString(), self.distanceMarkers))
```

This method will produce the following new staements in the JavaScript in our html file when the script has been executed:

```javascript
L.marker([55.6563244,12.4798398], {
  icon: L.divIcon({ html: '<span style="font-size: 20px; font-weight: bold">1km</span>' })
}).addTo(myMap);

L.marker([55.6510156,12.488698], {
  icon: L.divIcon({ html: '<span style="font-size: 20px; font-weight: bold">2km</span>' })
}).addTo(myMap);

L.marker([55.643674,12.4973899], {
  icon: L.divIcon({ html: '<span style="font-size: 20px; font-weight: bold">3km</span>' })
}).addTo(myMap);

L.marker([55.6368974,12.5051689], {
  icon: L.divIcon({ html: '<span style="font-size: 20px; font-weight: bold">4km</span>' })
}).addTo(myMap);
...
...
```

For the entire code, check out the previous posts and clone the repository with the code from the [GitHub repository gpx-to-leaflet](https://github.com/CoderAllan/gpx-to-leaflet).

When running the code now, you get this result:
![Distance markers to yours Leaflet map](https://dev-to-uploads.s3.amazonaws.com/i/unm17gzfr66jqov9gk2q.gif)