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.
    – Dror Bogin
    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.
    – TomazicM
    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 ?
    – Hervé
    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.
    – TomazicM
    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?
    – TomazicM
    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
    – Hervé
    Feb 16, 2021 at 9:56
  • Sorry, I made a mistake implementing your code, it works exactly as I want, Thanks a lot, solved.
    – Hervé
    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.
    – TomazicM
    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'
    – Hervé
    Feb 16, 2021 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.