Ordre personnalisé / index z des icônes dans la couche Leaflet


8

J'ai une seule couche (points) avec un tas de marqueurs. Chaque point a un attribut qui est régulièrement mis à jour. Je comprends que Leaflet trie les couches de telle sorte que celles qui sont plus basses en latitude soient au sommet pour des raisons esthétiques, mais je voudrais les réorganiser de telle sorte que dans les zones de regroupement, celles qui ont des valeurs plus élevées dans l'attribut soient en haut. Y a-t-il un moyen de le faire sans avoir à diviser chaque marqueur / point en une couche individuelle et à forcer l'ordre de tirage de cette façon?

Réponses:


6

Jusqu'à ce que quelqu'un trouve une meilleure solution, voici ce que je ferais ...

Comme vous l'avez remarqué, le dépliant utilise la position des pixels pour définir zIndex (dans Marker.js)

pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
this._zIndex = pos.y + this.options.zIndexOffset;

Ce que je suggère est d'annuler le dépliant zIndex en utilisant setZIndexOffset ()

Dites que vous voulez définir zIndex = 100, vous feriez

var pos = map.latLngToLayerPoint(marker.getLatLng()).round();
marker.setZIndexOffset(100 - pos.y);

Il y a un petit problème: vous devez le faire chaque fois que la carte est agrandie :(

Voici un exemple JSFiddle (commentez le code dans adjustZindex () pour voir la différence)


Cela ressemble à Leaflet refait les index z à chaque fois qu'il est zoomé de toute façon (au moins en jouant avec et en vérifiant l'index z d'un marqueur sur les outils de développement de chrome). Je pense donc que c'est une option parfaitement bien, merci!
wowohweewah


2

Ce plugin fera l'affaire: 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);

Utiliser:

var aMarker = L.marker([lat, lon], {
    icon: icon,
    title: title,
    forceZIndex: <Value> // This is forceZIndex value
})

La déclaration forceZIndex garantira que ZIndex sera toujours défini à partir de aMarker.options.forceZIndex

Mettez-le quelque part à jour pour re-forcer la valeur ZIndex

aMarker.setForceZIndex(<New Value>)

Ou définissezForceZIndex (null) sur l'état zIndex automatique:

aMarker.setForceZIndex(null);

À la fin de la journée, si aucune option forceZIndex n'est déclarée, Marker fonctionnera avec un comportement normal.


1

Les seules solutions actuellement disponibles sont hacky et peuvent se briser à l'avenir, si elles décident d'utiliser autre chose que pos.you de refactoriser fortement le code.

Voici une autre solution hacky simple qui est plus facile à utiliser et ne nécessite pas de mettre à jour la valeur à chaque fois que le zoom change. Il fait zIndexOffsetrefléter le réel zIndex:

L.Marker.prototype.__setPos = L.Marker.prototype._setPos;
L.Marker.prototype._setPos = function ()
{
    L.Marker.prototype.__setPos.apply(this, arguments);
    this._zIndex = this.options.zIndexOffset;
    this._resetZIndex();
};

Ensuite, si vous souhaitez définir zIndex sur 100, utilisez simplement:

marker.setZIndexOffset(100);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.