Custom ordering/z-index of icons in Leaflet layer
Until somebody finds a better solution, here what I would do ...
As you noticed, leaflet is using pixel position to set zIndex (in Marker.js)
pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
this._zIndex = pos.y + this.options.zIndexOffset;
What I suggest is to undo leaflet zIndex using setZIndexOffset()
Say you want to set zIndex = 100, you would do
var pos = map.latLngToLayerPoint(marker.getLatLng()).round();
marker.setZIndexOffset(100 - pos.y);
There is a bit of a glitch: you have to do it every time the map is zoomed :(
Here is a JSFiddle example (comment the code in adjustZindex() to see the difference)
The current version of leaflet (as of early 2017) has a zIndexOffset property with default = 0 that can be set to atler the z-index of a marker. http://leafletjs.com/reference.html#marker-zindexoffset Works fine with zooming and everthing.
This plugin will do the trick: leaflet.forceZIndex.js
// Force zIndex of Leaflet
(function(global){
var MarkerMixin = {
_updateZIndex: function (offset) {
this._icon.style.zIndex = this.options.forceZIndex ? (this.options.forceZIndex + (this.options.zIndexOffset || 0)) : (this._zIndex + offset);
},
setForceZIndex: function(forceZIndex) {
this.options.forceZIndex = forceZIndex ? forceZIndex : null;
}
};
if (global) global.include(MarkerMixin);
})(L.Marker);
To use:
var aMarker = L.marker([lat, lon], {
icon: icon,
title: title,
forceZIndex: <Value> // This is forceZIndex value
})
forceZIndex declaration will assure that ZIndex will be always set from aMarker.options.forceZIndex
Update it somewhere to re-force ZIndex value
aMarker.setForceZIndex(<New Value>)
Or setForceZIndex(null) to automatical zIndex state:
aMarker.setForceZIndex(null);
By the end of the day, if no forceZIndex option declared, Marker will work with normal behaviour.