TransWikia.com

Cluster GeoJSON data with PruneCluster

Geographic Information Systems Asked on January 15, 2021

I’m trying to create a cluster with categories using PruneCluster around my GeoJSON layers.

As the example in GitHub They are creating randomly some markers then adding them to the cluster.

I did the same, I got the coords from a GeoJSON layer, stored it in a variable then added it to Prunecluster as follows :

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)

Now on my map I have the clusters around new markers and the GeoJSON layers. When I read the doc, I found that Prunecluster does not support GeoJSON.
Now if I just work with markers, How can I attach them to the properties of the geojson features, because I’m building custom popups with the function onMarkerClick called when a geojson feature is clicked.

So if you have an idea about how to achieve that I would be pleased.

One Answer

If you want to display markers with PruneCluster plugin, you cannot combine that with displaying the same markers through GeoJSON layer.

If your markers are coming from GeoJSON data, you can use Leaflets L.geoJSON for iterating through features/points, but markers must be created only with instances of PruneCluster.Marker object.

Since markers created with PruneCluster plugin are not standard Leaflet markers, you cannot assign popups or event handlers to those markers using standard Leaflet methods. There is solution for this in the form of overriding PrepareLeafletMarker(leafletMarker, data) method (see docs at https://github.com/SINTEF-9012/PruneCluster). First parameter leafletMarker is standard Leaflet marker to which you can apply all standard marker methods for creating tooltips, popups, event handlers etc. Second parameter is data, which contains data from marker's data property, supplied at the time of marker creation, for example:

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

For marker from the above example, data.properties would contain all the feature's properties.

Below is simple example of creating PruneCluster markers from GeoJSON source geojsonData. Popup is assigned to marker from feature's property name, and upon marker click all the feature's properties are displayed in the 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);

Correct answer by TomazicM on January 15, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP