Ordenamiento personalizado / índice z de iconos en la capa de folleto

8

Tengo una sola capa (puntos) con un montón de marcadores. Cada punto tiene un atributo que se actualiza regularmente. Entiendo por Leaflet que las capas se clasifican de manera que los que tienen menos latitud están en la parte superior por razones estéticas, pero me gustaría reordenarlos de manera que en las áreas de agrupamiento, aquellos con valores más altos en el atributo estén en la parte superior. ¿Hay alguna manera de hacer esto sin tener que dividir cada marcador / punto en una capa individual y forzar el orden de dibujo de esa manera?

wowohweewah
fuente

Respuestas:

6

Hasta que alguien encuentre una mejor solución, aquí lo que haría ...

Como notó, el folleto está utilizando la posición de píxeles para establecer zIndex (en Marker.js)

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

Lo que sugiero es deshacer el prospecto zIndex usando setZIndexOffset ()

Digamos que desea establecer zIndex = 100, lo haría

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

Hay un pequeño problema: debe hacerlo cada vez que se acerca el mapa :(

Aquí hay un ejemplo de JSFiddle (comente el código en ajustarZindex () para ver la diferencia)

YaFred
fuente
Parece que Leaflet rehace los índices z cada vez que se hace zoom de todos modos (al menos jugando con él y verificando el índice z de un marcador en las herramientas de desarrollo de Chrome). Así que creo que esta es una excelente opción, ¡gracias!
wowohweewah
2

Este complemento hará el truco: 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);

Usar:

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

La declaración forceZIndex asegurará que ZIndex siempre se establecerá desde aMarker.options.forceZIndex

Actualízalo en algún lugar para volver a forzar el valor de ZIndex

aMarker.setForceZIndex(<New Value>)

O establezca ForceZIndex (nulo) en el estado automático de zIndex:

aMarker.setForceZIndex(null);

Al final del día, si no se declara la opción forceZIndex, Marker funcionará con un comportamiento normal.

Up209d
fuente
1

Las únicas soluciones disponibles actualmente son hacky y pueden romperse en el futuro, si deciden usar algo más pos.yo refactorizar el código en gran medida.

Aquí hay otra solución hacky simple que es más fácil de usar y no requiere actualizar el valor cada vez que cambia el zoom. Hace que el zIndexOffsetreflejo sea real 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();
};

Luego, si desea establecer zIndex en 100, simplemente use:

marker.setZIndexOffset(100);
Sebastian Nowak
fuente