1

I use Leaflet to display tracks described in XML file on OpenStreetMap background. Some of my XML files contains several tracks, example Multi tracks. Is it possible to display each track with a different color ?

This is the HTML code I use to display the map : getUrlParameter('map') gives the XML file URL; getUrlParameter('Lon') & 'Lon' gives a marker coordinates. Each track color should either be specified in the XML for each track or choosen automatically sequentially among a limited number of colors i.e. black, grey, blue, lighe blue, red then again black ...

<!DOCTYPE html> <html> <head> <title>Open Street Map</title> <meta charset="utf-8" > <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" > <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script> <link rel="stylesheet" href="src/Leaflet.GraphicScale.min.css" > <link rel="stylesheet" href="src/stylesheet.css" > </head> <body> <div id="map"></div> <script src="https://api.mapbox.com/mapbox.js/plugins/leaflet-omnivore/v0.2.0/leaflet-omnivore.min.js"></script> <script src="src/Leaflet.GraphicScale.min.js"></script> <script> function getUrlParameter(name) { name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]'); var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'); var results = regex.exec(location.search); return (results === null)? '' : decodeURIComponent(results[1].replace(/\+/g, ' ')); }; </script> <script> var blauwIcon = L.icon({ iconUrl: 'Point.png', iconSize: [27, 32], // size of the icon iconAnchor: [13, 32], // point of the icon which will correspond to marker's location popupAnchor: [0, -30] // point from which the popup should open relative to the iconAnchor }); var Lon = getUrlParameter('Lon') var Lat = getUrlParameter('Lat') var starts = new L.LayerGroup(); L.marker([Lat,Lon], {icon: blauwIcon}).bindPopup(Lat+'<br>'+Lon).addTo(starts); var customLayer = L.geoJson(null, { style: function(feature) { return { color: '#f00' }; } }); var zomer = new L.LayerGroup(); var runLayer = omnivore.gpx("../"+getUrlParameter('map')) .on('ready', function() { map.fitBounds(runLayer.getBounds()); }) .addTo(zomer); var osmLink = '<a href="https://openstreetmap.org">OpenStreetMap</a>' ; var osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', osmAttrib = '&copy; ' + osmLink + ' Contributors' ; var mbAttr = 'Map data &copy; <a href="https://openstreetmap.org">OpenStreetMap</a> contributors, ' + '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' + 'Imagery © <a href="https://mapbox.com">Mapbox</a>', mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=TOKEN; var osmMap = L.tileLayer(osmUrl, {attribution: osmAttrib}), satellite = L.tileLayer(mbUrl, {id: 'mapbox.satellite', attribution: mbAttr}); var Stamen_Terrain = L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.{ext}', { attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>', subdomains: 'abcd', ext: 'png' }); var standard = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', { attribution: 'Map data: &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)', maxZoom: 18 }); var map = L.map('map', { layers: [osmMap, starts, zomer], }) .setView([49.21, 4.2], 8); var baseLayers = { "OpenStreetMap": osmMap, "OpenTopoMap": standard, "3D map" : Stamen_Terrain, "satellite": satellite, }; var overlays = { "Startpunten zomer": starts, "zomerwandelingen" : zomer }; L.control.layers(baseLayers).addTo(map); var graphicScale = L.control.graphicScale({ position: 'bottomright', fill: 'hollow', }).addTo(map); </script> </body> </html> 
7
  • 3
    Did you try anything yet? what you are asking is how to style layers in leaflet. you can see this leaflet tutorial on how to do basic styling. Commented Feb 15, 2021 at 9:14
  • 2
    GIS SE site is intended for focused questions. You have posted general question, which has answer Yes, but which is of course of no use to you. If you have a coding question, your question should include relevant code of what you have tried so far, otherwise it's most likely to be closed as not compliant with the site policy. Commented Feb 15, 2021 at 9:20
  • I don't have any idea about how I could solve this question so I didn't try anything. All I know is that I have one XML file containing gpx, trk, trkseg and of course trkpt tags. I display the whole with one color thanks to a JS script containing among others "omnivore.gpx("../"+getUrlParameter('map')" map being the XML file. There are several trk and trkseg to which I could add attributes. How can I display the diffenr trk (or trkseg) sections using a different color ? Commented Feb 15, 2021 at 10:17
  • 1
    You have some existing code where you display your tracks. Then edit your question and add relevant part of this code to the question and mark with comment where you would like to have tracks with different colors and how would you decide which color to use for a specific track. Commented Feb 15, 2021 at 10:44
  • Now you added the code but didn't answer the question about the colors, so again: How would you decide which color goes to each separate track section? Commented Feb 15, 2021 at 13:54

1 Answer 1

3

If you look at the docs of leaflet-omnivore plugin, you'll se you can style layer with the help of so called custom GeoJSON layer, where you can apply styles to your GPX features/tracks.

Since your GPX XML has no property to be used as the basis for color assignment, solution below assigns colors from a array of predefined colors. Each feature is at the beginning given an id (sequence number actually), which is then used to pick a color from the array of colors.

Code could then look something like this:

var colors = [ '#ff0000', '#ff8000', '#ffff00', '#bfff00', '#00ff80', '#00ffff', '#0080ff', '#bf00ff', '#ff00bf', '#ff00ff' ]; var n = 0; var customLayer = L.geoJson(null, { style: function(feature) { if (!feature.properties.id) { feature.properties.id = n++; } var iColor = feature.properties.id % colors.length; return { color: colors[iColor] }; } }); var runLayer = omnivore.gpx('data/LastYear.xml', null, customLayer) .on('ready', function() { map.fitBounds(runLayer.getBounds()); }) .addTo(map); 

With the above code your tracks would look like this:

enter image description here

4
  • Thanks a lot for your code but the tracks are still in all same color #3388FF Example : rudyv.be/OSM/MapC.html?map=VTT/Itineraires/LastYear.xml Commented Feb 16, 2021 at 9:56
  • Sorry, I made a mistake implementing your code, it works exactly as I want, Thanks a lot, solved. Commented Feb 16, 2021 at 10:00
  • If answer helped you resolve your problem, it's customary on GIS SE site to mark it as accepted, to let other users with similar problems know that problem was successfully resolved. Commented Feb 16, 2021 at 10:22
  • Yes of course, I didn't find how to, it's done now, thanks again, I just changed your color list to '#3388ff', '#800000', '#9a6324', '#808000', '#469990', '#000075', '#000000', '#e6194b', '#f58231', '#ffe119', '#bfef45', '#3cb44b', '#42d4f4', '#4363d8', '#911eb4', '#f032e6', '#a9a9a9', '#fabed4', '#ffd8b1', '#fffac8', '#aaffc3', '#dcbeff', '#ffffff' Commented Feb 16, 2021 at 11:29

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.