Ordenação personalizada / z-index de ícones na camada Leaflet


8

Eu tenho uma única camada (pontos) com um monte de marcadores. Cada ponto tem um atributo que é atualizado regularmente. Entendo, por Leaflet, que as camadas são classificadas de maneira que aquelas com menor latitude estejam no topo por razões estéticas, mas gostaria de reordená-las para que, nas áreas de agrupamento, aquelas com valores mais altos no atributo estejam no topo. Existe alguma maneira de fazer isso sem ter que dividir cada marcador / ponto em uma camada individual e forçar a ordem de desenho dessa maneira?

Respostas:


6

Até que alguém encontre uma solução melhor, aqui o que eu faria ...

Como você notou, o folheto está usando a posição do pixel para definir zIndex (em Marker.js)

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

O que eu sugiro é desfazer o folheto zIndex usando setZIndexOffset ()

Digamos que você queira definir zIndex = 100, você faria

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

Há uma falha: você precisa fazer isso toda vez que o mapa é ampliado :(

Aqui está um exemplo do JSFiddle (comente o código em AdjustZindex () para ver a diferença)


Parece que o Leaflet refaz índices z toda vez que aumenta o zoom (pelo menos brinca com ele e verifica o índice z de um marcador nas ferramentas de desenvolvimento do chrome). Então eu acho que essa é uma opção perfeitamente bem, obrigado!
Wowohweewah


2

Este plugin fará o truque: 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
})

A declaração forceZIndex garantirá que ZIndex seja sempre definido em aMarker.options.forceZIndex

Atualize-o em algum lugar para reforçar o valor do ZIndex

aMarker.setForceZIndex(<New Value>)

Ou setForceZIndex (null) para o estado zIndex automático:

aMarker.setForceZIndex(null);

No final do dia, se nenhuma opção forceZIndex for declarada, o Marker funcionará com comportamento normal.


1

As únicas soluções atualmente disponíveis são hacky e podem quebrar no futuro, se decidirem usar algo mais que pos.you refatorar fortemente o código.

Aqui está outra solução hacky simples que é mais fácil de usar e não requer atualização do valor toda vez que o zoom muda. Faz zIndexOffsetrefletir o 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();
};

Então, se você deseja definir zIndex como 100, basta usar:

marker.setZIndexOffset(100);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.