Dados GeoJSON do cluster com PruneCluster

Oct 01 2020

Estou tentando criar um cluster com categorias usando PruneCluster em torno de minhas camadas GeoJSON.

Conforme o exemplo no GitHub, eles estão criando aleatoriamente alguns marcadores e depois os adicionando ao cluster.

Eu fiz o mesmo, peguei os coords de uma camada GeoJSON, armazenei em uma variável e depois adicionei ao Prunecluster da seguinte maneira:

leafletView.BuildLeafletClusterIcon = function(cluster) {
        var e = new L.Icon.MarkerCluster();

        e.stats = cluster.stats;
        e.population = cluster.population;
        return e;
    };

    var colors = ['rgb(10, 94, 219)', 'rgb(253, 152, 1)', 'rgb(3, 180, 11)'],
        pi2 = Math.PI * 2;

    L.Icon.MarkerCluster = L.Icon.extend({
        options: {
            iconSize: new L.Point(44, 44),
            className: 'prunecluster leaflet-markercluster-icon'
        },

        createIcon: function() {
            // based on L.Icon.Canvas from shramov/leaflet-plugins (BSD licence)
            var e = document.createElement('canvas');
            this._setIconStyles(e, 'icon');
            var s = this.options.iconSize;
            e.width = s.x;
            e.height = s.y;
            this.draw(e.getContext('2d'), s.x, s.y);
            return e;
        },

        createShadow: function() {
            return null;
        },

        draw: function(canvas, width, height) {

            var lol = 0;

            var start = 0;
            for (var i = 0, l = colors.length; i < l; ++i) {

                var size = this.stats[i] / this.population;


                if (size > 0) {
                    canvas.beginPath();
                    canvas.moveTo(22, 22);
                    canvas.fillStyle = colors[i];
                    var from = start + 0.14,
                        to = start + size * pi2;

                    if (to < from) {
                        from = start;
                    }
                    canvas.arc(22, 22, 22, from, to);

                    start = start + size * pi2;
                    canvas.lineTo(22, 22);
                    canvas.fill();
                    canvas.closePath();
                }

            }

            canvas.beginPath();
            canvas.fillStyle = 'white';
            canvas.arc(22, 22, 18, 0, Math.PI * 2);
            canvas.fill();
            canvas.closePath();

            canvas.fillStyle = '#555';
            canvas.textAlign = 'center';
            canvas.textBaseline = 'middle';
            canvas.font = 'bold 12px sans-serif';

            canvas.fillText(this.population, 22, 22, 40);
        }
    });


let myLayerOptionsArbre = {

        pointToLayer: createCustomIcon,
        onEachFeature: function(feature, layer) {
            layer.bindTooltip(feature.properties.titre);
            layer.on({
                click: onMarkerClick
            });
            coordsArb.push(feature.geometry.coordinates);

        }
    }

var arb = arbres
    var arbre = new L.GeoJSON(arb, myLayerOptionsArbre)

var ap = {}

    for (var i = 0; i < coordsAP.length; i++) {

        ap = new PruneCluster.Marker(coordsAP[i][1], coordsAP[i][0]);
        console.log(typeof ap)
        console.log("hey", coordsAP[i][1])
        ap.category = AIRES_PROTEGEES;
        leafletView.RegisterMarker(ap);
    }

leafletView.ProcessView();
    mymap.addLayer(leafletView)

Agora, no meu mapa, tenho os clusters em torno de novos marcadores e as camadas GeoJSON. Quando li o documento, descobri que Prunecluster não oferece suporte a GeoJSON. Agora, se eu trabalhar apenas com marcadores, como posso anexá-los às propriedades dos recursos geojson, porque estou construindo pop-ups personalizados com a função onMarkerClickchamada quando um recurso geojson é clicado.

Portanto, se você tiver uma ideia sobre como conseguir isso, eu ficaria satisfeito.

Respostas

TomazicM Oct 02 2020 at 01:59

Se você deseja exibir marcadores com PruneClusterplug - in, não pode combinar isso com a exibição dos mesmos marcadores por meio da camada GeoJSON.

Se seus marcadores vêm de dados GeoJSON, você pode usar Folhetos L.geoJSONpara iterar através de recursos / pontos, mas os marcadores devem ser criados apenas com instâncias de PruneCluster.Markerobjeto.

Uma vez que os marcadores criados com o PruneClusterplugin não são marcadores de folheto padrão, você não pode atribuir pop-ups ou manipuladores de eventos a esses marcadores usando métodos de folheto padrão. Há uma solução para isso na forma de PrepareLeafletMarker(leafletMarker, data)método de substituição (ver documentos emhttps://github.com/SINTEF-9012/PruneCluster) O primeiro parâmetro leafletMarkeré o marcador de folheto padrão ao qual você pode aplicar todos os métodos de marcador padrão para criar dicas de ferramentas, pop-ups, manipuladores de eventos etc. O segundo parâmetro é data, que contém dados da datapropriedade do marcador , fornecidos no momento da criação do marcador, por exemplo:

var marker = new PruneCluster.Marker(latLng.lat, latLng.lng);
marker.data.properties = feature.properties;
leafletView.RegisterMarker(marker);

Para o marcador do exemplo acima, data.propertiesconteria todas as propriedades do recurso.

Abaixo está um exemplo simples de criação de PruneClustermarcadores da fonte GeoJSON geojsonData. O pop-up é atribuído ao marcador da propriedade do recurso namee, ao clicar no marcador, todas as propriedades do recurso são exibidas no console.

var map = L.map("map", {
  attributionControl: false,
  zoomControl: false
}).setView(new L.LatLng(41.89, 12.49), 15);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  detectRetina: true,
  maxNativeZoom: 17
}).addTo(map);

var leafletView = new PruneClusterForLeaflet();
leafletView.Cluster.Size = 160;

leafletView.PrepareLeafletMarker = function(leafletMarker, data) {
  leafletMarker.bindPopup(data.properties.name);
  leafletMarker.on('click', function(evt){
    console.log(data);
  });
};

L.geoJSON(geojsonData, {
  pointToLayer: function(feature, latLng) {
    var marker = new PruneCluster.Marker(latLng.lat, latLng.lng);
    marker.data.properties = feature.properties;
    leafletView.RegisterMarker(marker);
  }
});

map.addLayer(leafletView);