1

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.

7
  • I used your suggestion and it worked. I thought I accepted the answer but forgot. My apologies. Commented Sep 30, 2020 at 16:00
  • What you don't like in the way you have done it already, through onEachFeature option of GeoJSON layer creation?
    – TomazicM
    Commented Sep 30, 2020 at 16:20
  • Yes I'm getting the coords from onEachFeature and the clusters are being created but not arround the geojson layers. New markers are created with ap = new PruneCluster.Marker(coordsAP[i][1], coordsAP[i][0]);, added to map then clustered. Geojson layers overlap the clusters and it's a mess. Commented Sep 30, 2020 at 16:23
  • So simply don't add GeoJSON layer to the map.
    – TomazicM
    Commented Sep 30, 2020 at 16:27
  • I know but how am I supposed to get the properties(fields) of each geojson. The markers have only the coords Commented Sep 30, 2020 at 16:29

1 Answer 1

1

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);
1
  • Thank you so much, It worked for me. Commented Oct 2, 2020 at 15:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.