Agrupar datos de GeoJSON con PruneCluster

Oct 01 2020

Estoy tratando de crear un clúster con categorías usando PruneCluster alrededor de mis capas GeoJSON.

Como en el ejemplo de GitHub, están creando aleatoriamente algunos marcadores y luego los agregan al clúster.

Hice lo mismo, obtuve las coordenadas de una capa GeoJSON, las almacené en una variable y luego las agregué a Prunecluster de la siguiente manera:

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)

Ahora en mi mapa tengo los grupos alrededor de nuevos marcadores y las capas GeoJSON. Cuando leí el documento, descubrí que Prunecluster no es compatible con GeoJSON. Ahora, si solo trabajo con marcadores, ¿cómo puedo adjuntarlos a las propiedades de las entidades geojson, porque estoy creando ventanas emergentes personalizadas con la función onMarkerClickllamada cuando se hace clic en una entidad geojson?

Entonces, si tiene una idea sobre cómo lograrlo, me complacerá.

Respuestas

TomazicM Oct 02 2020 at 01:59

Si desea mostrar marcadores con el PruneClustercomplemento, no puede combinar eso con mostrar los mismos marcadores a través de la capa GeoJSON.

Si sus marcadores provienen de datos de GeoJSON, puede usar Folletos L.geoJSONpara iterar a través de características / puntos, pero los marcadores deben crearse solo con instancias de PruneCluster.Markerobjeto.

Dado que los marcadores creados con el PruneClustercomplemento no son marcadores de folletos estándar, no puede asignar ventanas emergentes o controladores de eventos a esos marcadores utilizando métodos de folletos estándar. Hay una solución para esto en forma de PrepareLeafletMarker(leafletMarker, data)método de anulación (consulte los documentos enhttps://github.com/SINTEF-9012/PruneCluster). El primer parámetro leafletMarkeres un marcador de folleto estándar al que puede aplicar todos los métodos de marcador estándar para crear información sobre herramientas, ventanas emergentes, controladores de eventos, etc. El segundo parámetro es data, que contiene datos de la datapropiedad del marcador , suministrados en el momento de la creación del marcador, por ejemplo:

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

Para el marcador del ejemplo anterior, data.propertiescontendría todas las propiedades de la función.

A continuación se muestra un ejemplo simple de creación de PruneClustermarcadores a partir de la fuente GeoJSON geojsonData. La ventana emergente se asigna al marcador de la propiedad de la función namey, al hacer clic en el marcador, todas las propiedades de la función se muestran en la consola.

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);