Leaflet -> Gpx route

A last one for this year. I’ve got leaflet running to show a gpx route. Now there is a small thing I need to verify. The data is now stored in a text field in a table. This can be a gpx file in a url, but you can’t upload them. This means I need to write a google drive api or some other to save the files there, or store all trackpoints in a table. I now went the easy way.

The method used here can also calculate time, total distance and so on. You can pass that back to Wix. I haven’t done that yet.

Step 1: make a table. This table contains ‘gpx_code’, and ‘gpx_data’. The first is a primary key, the second contains the gpx file content one on one.

Step 2: make a backend function to collect the data

import wixData from 'wix-data';

export function getGpx(arrTrailCode) {
	return wixData.query("trail_gpx")
		.eq("gpx_code", arrTrailCode[0])
		.find()
		.then((resultGpx) => {
			const oGpx = resultGpx.items;
			const arrGpx = [];
			
			for (const iGpx in oGpx) {
				arrGpx.push({
					"_id": iGpx,
					"gpx_data": oGpx[iGpx].gpx_data,
					"gpx_code": oGpx[iGpx].gpx_code
				});
			}
			
			return arrGpx;
		});
}

Here I query the ‘trail_gpx’ table for the record passed. Now I only pass one value to the function so I just coded position ‘0’ of strTrailCode. I make a array of the result just because I’m used to that.

Step 3: Place an html element on a page. I’m doing it on my dynamic trail page. You need to add code to that element

<!DOCTYPE html>
<html style="height: 100%; width: 100%">
    <head>
        <link rel="stylesheet" 
              href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
              integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
              crossorigin=""/>
        <script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"
                integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
                crossorigin="">
        </script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-gpx/1.3.1/gpx.min.js"
              crossorigin="">            
        </script>
        <style>
            body {
                background-color: transparent;
                width: 100%;
                height: 100%;
                overflow: hidden;
                margin: 0;
            }
            #vttRoute {
                width: 100%;
                height: 100%;
            }
        </style>
    </head>
    <body>
        <div id="vttRoute"></div>
        <script type="text/javascript">
            // When data received
            window.onmessage = (event) => { 
                if (event.data) { 
                     // initialize map
                    let mapOverview = L.map('vttRoute', {
                        center: [52.113301, 5.796346],
                        zoom: 13
                    });

                    // Add tilelayer and define layout of map
                    L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
                        maxZoom: 15,
                        attribution: 'Venture the Trails - Trail Overview'
                    }).addTo(mapOverview);

                    // Create route
                    const oGpx = event.data;
                    const gpx = oGpx[0]["gpx_data"];
                    new L.GPX(gpx, {async: true}).on('loaded', function(e) {
                        mapOverview.fitBounds(e.target.getBounds());
                    }).addTo(mapOverview);
                } 
            };
        </script>
    </body>
</html>

Again this code inserts leaflet script and a plugin for GPX. Then there is some layout code. A map is initiated with a tile layer as desired. The script catches the postmessage from Wix. That data is linked to make the GPX route and then the map is zoomed to fit the route.

Step 4: Call the backend function and link the data. Now, since my data is multi lingual I add this to my ‘onReady’ of the dataset. You could make a new dataset on the page, but in future I need to do some more with the query so I did it this way. Also my base dataset contains a column ‘has_gpx’ :slight_smile:

import {getGpx} from 'backend/vttTrails';
import wixLocation from 'wix-location';
import {local} from 'wix-storage';

$w.onReady(function () {
	// Link lingual fields
	$w("#datasetTrails").onReady(function () {
		const curTrail = $w("#datasetTrails").getCurrentItem();
		
		...
		
		// Initiate map
		if (curTrail.has_gpx) {
			setTimeout(function(){
				const strTrailCode = wixLocation.path;
				getGpx(strTrailCode).then((oGpx) => {
					$w("#htmlRoute").postMessage(oGpx);
					$w("#htmlRoute").show();
					$w("#htmlRoute").expand();
				});
			}, 1000);
		}

	});
});

So, the map is here initiated. When my ‘has_gpx’ is true, after one second (don’t know why I always need it with leaflet) I fill a constant with the current ‘trail_code’ from the url. Then that is passed to my backend function. The data return is passed to the html element and that element is made visible and expanded.

It should make something like this.

I need to change the tile overlay I think. I’m not entirely happy with the design of this one. Options still to include which are possible by default:

  • add start-end point markers
  • add onroute markers (checkpoint, water station, what ever you like)

For the information. This route is 70km. The gpx file was 500kb. It contains about 4275 trackpoints (lat, lon, ele, time).

Tip: if you use leaflet, go for Esri.WorldTopoMap. This is much better then the one above

1 Like

Amazing work man!

Hello, I’m French ! I little speak enghlish… :frowning:
I would like make a new website for my company “drome à cheval” on Wix but I’don’t to insert wix code et I don’t understand how…
We have a lot of .gpx and markers.
Can you help me please ?

Hello Marie. I can help you I think. If you send me a message via this form HERE I can contact you. I looked at your site and the maps you have there are indeed what you can do with leaflet too.