Visualize your hiking trip using Leaflet map
Tags: leaflet, gpx, python, javascript
Published: 2021-01-15 16:18:47


# GPX track to Leaflet map

Many mobile map apps and fitness trackers can record your hike or running trip so you later can see your track on a map. Many of the apps will also let you export the track into the GPX ([GPS exchange format](https://en.wikipedia.org/wiki/GPS_Exchange_Format)) format so you can import the tracks into other apps or make your app that visualize or manipulates the data.

In this short article I will show how to use a Python script to generate a html page that shows a map using Leaflet with a polyline representing a track read from a GPX file.

The Python script uses the [gpxpy -- GPX file parser](https://pypi.org/project/gpxpy/) package to read all the points recorded in the GPX data and convert it into JavaScript in a html page and visualize the track in a [Leaflet](https://leafletjs.com/) map.

You find the entire Python script below the screenshots or you can clone it from this [GitHub repo](https://github.com/CoderAllan/gpx-to-leaflet).

![Gpx-To-Leaflet](https://dev-to-uploads.s3.amazonaws.com/i/9vjrejh4hvlfmtejbwct.gif)


```python
import gpxpy
import os

def main(gpxFilename, htmlFilename) -> None:
    track: list = load_track(gpxFilename)
    if(track != None and len(track) > 0):
        generate_html(track, htmlFilename)
        print("Done generating html page: ", htmlFilename)

def load_track(filename: str) -> list:
    trackPoints: list = []
    if(os.path.exists(filename) == False):
        print(f"File not found: {filename}")
        return
    gpx_file = open(filename)
    try:
        gpx = gpxpy.parse(gpx_file)
        for track in gpx.tracks:
            for segment in track.segments:
                for point in segment.points:
                    trackPoints.append(
                        [float(point.latitude), float(point.longitude)])
    except Exception as error:
        print(f"\nParsing file '{filename}' failed. Error: {error}")
    gpx_file.close()
    return(trackPoints)

def generate_html(track: list, file_out: str) -> None:
    """Generates a new html file with points"""
    template = """
    <html><head>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
  <style type="text/css">
  #mapId {
    position: absolute;
    top: 0px;
    width: 1000px;
    left: 0px; 
    height: 1000px;
    border: 1px solid #000;
  }  
</style>
</head>
<body>
  <div id="mapId"></div>
  <script>
    var myMap = L.map('mapId').setView([55.641, 12.47], 13);
    L.tileLayer(
      'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
          '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
          'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        id: 'mapbox/streets-v11',
        tileSize: 512,
        zoomOffset: -1
      }).addTo(myMap);
    var track = [];
    L.polyline(track, {color: 'blue'}).addTo(myMap);;
  </script>
</body></html>    
    """

    track_points = ",".join([f"[{g_track_point[0]}, {g_track_point[1]}, 0.1]" for g_track_point in track])
    track_points = f"var track=[{track_points}];"
    template = template.replace("var track = [];", track_points)
    f = open(file_out, "w")
    f.write(template)
    f.close()

if __name__ == '__main__':
    main("myTrack.gpx", "myTrack.html")

```

Have a look at some of the other good articles here on [Dev about Leaflet](https://dev.to/search?q=leaflet)