Raruto/leaflet-elevation

How to sort `L.gpxGroup` tracks in alphabetical order?

haldo98 opened this issue ยท 10 comments

I use Gpx group to show multiple gpx tracks on a map.

everything is working fine but the list of tracks is not in alphabetical order but in some other order I don't know...

i have...

var routes = L.gpxGroup(tracks, {
  elevation: true,
  legend: true,
  legend_options: {
    position: "topright",
    collapsed: true,
  },
  elevation_options: opts.elevation,
  distanceMarkers: true,
});

routes.addTo(map);

and my list or gox track are in

let tracks = [.........

what can I do to have the tracks in alphabetical order?

Hi @haldo98,

did you search among the closed issues? eg: I found this

๐Ÿ‘‹ Raruto

Hi @haldo98,

did you search among the closed issues? eg: I found this

๐Ÿ‘‹ Raruto

yes... but it doesn't work.

@haldo98

var routes = L.gpxGroup(tracks, {
  elevation: true,
  legend: true,
  legend_options: {
    position: "topright",
    collapsed: true,
    sortLayers: true, // <-- whether to sort the layers (alphabetically by their name)
  },
  elevation_options: opts.elevation,
  distanceMarkers: true,
});

For more info:

๐Ÿ‘‹ Raruto

I already tried that... but it doesn't work either....

If you're looking for help show a complete example, otherwise it's just ellipsis.. and words..

For more info:

I showed you two options (which I also tested with the public example), but you just say it doesn't work..

๐Ÿคท Raruto

You're right....

here my test page...

https://www.tadini.it/temp/svizzera_estate.html

sortLayers: true, is present but refreshing the page the order is not alphabetical and always different

the order is not alphabetical and always different

They are probably sorted by their leaflet_id, because the layers control also considers the svg/html as part of the name:

this._legend.addBaseLayer(route, '<svg id="legend_' + route._leaflet_id + '" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">' + '<line x1="0" x2="50" y1="5" y2="5" stroke="' + route.options.originalStyle.color + '" fill="transparent" stroke-width="5" /></svg>' + ' ' + route.options.name);

You should also try with the sortFunction:

sortFuction(a, b) { return a.layer.options.name - b.layer.options.name },
// sortLayers: true, // <-- I don't know if it should be set to true

Otherwise, be creative and move the html the way you like it when it's all done (I think you could also do it without invoking any leaflet code):

// source: https://stackoverflow.com/a/59493914
function sortLabels() {
    var controlLayers = {}
    routes._legend._layers.forEach(x => controlLayers[x.layer.options.name] = x.layer);
    names = Object.keys(controlLayers).sort()
    //remove and add sorted layernames
    names.forEach(x => routes._legend.removeLayer(controlLayers[x]))
    names.forEach(x => routes._legend.addBaseLayer(controlLayers[x], '<svg id="legend_' + controlLayers[x]._leaflet_id + '" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">' + '<line x1="0" x2="50" y1="5" y2="5" stroke="' + controlLayers[x].options.originalStyle.color + '" fill="transparent" stroke-width="5" /></svg>' + ' ' + controlLayers[x].options.name))
}

๐Ÿ‘‹ Raruto

unfortunately none of the above works.....

I will continue searching for a solution....