Reputation: 259
I have created a leaflet map to display some geoJSON data in separate vertical layers.
It works fine, except that the layer control will list the options out of order, i.e. "layer 0, layer 2, layer 1" as opposed to "layer 0, layer 1, layer 2". The data is loaded through AJAX calls, and so the layers are added to the control in the order which the calls complete, i.e. basically random.
According to the documentation for the layer control [ https://leafletjs.com/reference-1.3.0.html#control-layers ], if sortLayers is set to true, the default is to sort the layers by name, but that seems to not be happening.
So, I have tried passing in a sort function explicitly, but the doc does not give an example of what one should look like.
When my code looks like this:
var layerControlOptions = {
hideSingleBase : true,
autoZIndex : true,
sortLayers: true}
var layerControl = L.control.layers(null, null, layerControlOptions).addTo(map);
The control looks like this:
layer control with sortLayers: true and no sortFunction being defined
My best guess at writing my own sorting function:
var layerControlOptions = {
hideSingleBase : true,
autoZIndex : true,
sortLayers: true,
sortFunction: function(layerA, layerB, nameA, nameB){return
[nameA,nameB].sort();}}
var layerControl = L.control.layers(null, null,
layerControlOptions).addTo(map);
With this, the layer names appear in the same order as when no function is given. Not sure if I am writing it incorrectly, or it is simply equivalent to the default, which is returning the wrong order for some reason.
Seems like the same issue here: Leaflet Layer Control: Ordering
which has no accepted answer and makes no mention of the layer control options. I did try the solution which is proposed here, but it did not fix the problem either.
Any help on this would be greatly appreciated, thank you.
Upvotes: 2
Views: 4361
Reputation: 1206
You can add the layers as you normally would and then sort them with a function that removes labels and re-add them as sorted.
function sortLabels() {
var controlLayers = {}
layerControl._layers.forEach(function(x) {
if (x.overlay) {
controlLayers[x.name] = x.layer
}
});
names = Object.keys(controlLayers).sort()
//remove and add sorted layernames
names.forEach(x => layerControl.removeLayer(controlLayers[x]))
names.forEach(x => layerControl.addOverlay(controlLayers[x], x))
}
var baseMaps = { "OpenStreetMap": tile_layer_osm, "ESRI World Imagery" : esri_satelite };
var overlayMaps = {nameC: layerC, nameA: layerA, nameB: layerB}
var layerControl = L.control.layers(baseMaps, overlayMaps, null, {collapsed: false}).addTo(map);
sortLabels()
Upvotes: 0
Reputation: 2371
You may look at this solution to order layers in the controls (it does not order layers). I've mainly borrowed code from Leaflet specs code;
If you have not problem to sort things in the control but you have issue related to loading JSON/GeoJSON (hence layer too) in a particular order, you may want to combine fetch
with Promise.all
but it's not anymore about Leaflet but about JavaScript knowledge (look at this page to try to grasp fetch
+ Promise.all
)
Upvotes: 1