Search code examples
javascriptjqueryleafletgeojsonleaflet.markercluster

Style individual features based on their geojson properties + Leaflet.Markercluster


I've been stuck for days trying to get this to work. I have a function to display geojson points based on their properties (i.e. "Type"). The geojson file is loaded with jQuery. However, I cannot manage to cluster them and at the same time preserve their custom icons.

I'm able to cluster in general by making some adjustments and leaving out the function geojsonType(). That's not what I'm after, though. I'm caught in a vicious circle.

Thanks to this post I can display the points based on their properties.

// create function for pointToLayer when loading geojson
 function geojsonType(feature, latlng) {
            switch (feature.properties["Type"]) {
                case "bar":
                    var barIcon = new L.icon({
                        iconUrl: 'images/pub.png', //assign PNG
                        iconSize: [42, 50], // size of the icon
                        iconAnchor: [22, 22], // point of the icon which will correspond to marker's location
                        popupAnchor: [-3, -26] // point from which the popup should open relative to the iconAnchor    
                    });
                    return L.marker(latlng, { icon: barIcon });

                case "recordclothingstore":
                    var venueIcon = new L.icon({
                        iconUrl: 'images/venue.png', //assign PNG
                        iconSize: [42, 50], // size of the icon
                        iconAnchor: [22, 22], // point of the icon which will correspond to marker's location
                        popupAnchor: [-3, -26] // point from which the popup should open relative to the iconAnchor    
                    });
                    return L.marker(latlng, { icon: storeIcon });

                case "venueandbar":
                    var venueandbarIcon = new L.icon({
                        iconUrl: 'images/pub.png', //assign PNG
                        iconSize: [42, 50], // size of the icon
                        iconAnchor: [22, 22], // point of the icon which will correspond to marker's location
                        popupAnchor: [-3, -26] // point from which the popup should open relative to the iconAnchor    
                    });
                    return L.marker(latlng, { icon: venueandbarIcon });
            }
        };
        // get geojson
        var url = "points.geojson";
        $.getJSON(url, function (data) {
            pointData.addData(data);
        });
        // load geojson
        var pointData = L.geoJson(null, {
            pointToLayer: geojsonType,
            onEachFeature: function (feature, layer) {
                layer.bindPopup("<a href='" + feature.properties.Website + "'>" + feature.properties.Name + "</a>" + "<br>" + feature.properties.Address + "<br>" + feature.properties.Descriptio);
            }
        });

However, the following bit of code when added to the bottom has no effect. There are no errors in the console either.

    var clusters = L.markerClusterGroup({
        spiderfyOnMaxZoom: true,
        showCoverageOnHover: false,
        zoomToBoundsOnClick: true
    });
    clusters.addLayer(pointData);
    map.addLayer(clusters);

Solution

  • I was able to order all the code above to make it work. The variable and icon names may have changed, but it's the same bits of code, basically. I'm not sure where to put the pop-up, though. Edit I found a spot for the bindPopup line. it can go here, for example:

    return L.marker(latlng, { icon: pubandvenueIcon }).bindPopup("<a href='" + feature.properties.Website + "'>" + feature.properties.Name + "</a>" + "<br>" + feature.properties.Address + "<br>" + feature.properties.Description);
    
    $.getJSON("points.geojson", function (data) {
        var venueIcon = L.icon({
            iconUrl: 'images/venue.png',
            iconSize: [60, 50]
        });
        var metallocations = L.geoJson(data, {
            pointToLayer: function geojsonType(feature, latlng) {
                switch (feature.properties["Type"]) {
                    case "pub":
                        var pubIcon = new L.icon({
                            iconUrl: 'images/pub.png', //assign PNG
                            iconSize: [42, 50], // size of the icon
                            iconAnchor: [22, 22], // point of the icon which will correspond to marker's location
                            popupAnchor: [-3, -26] // point from which the popup should open relative to the iconAnchor    
                        });
    
                        return L.marker(latlng, { icon: pubIcon });
    
                    case "pubandvenue":
                        var pubandvenueIcon = new L.icon({
                            iconUrl: 'images/search-icon.png', //assign PNG
                            iconSize: [42, 50], // size of the icon
                            iconAnchor: [22, 22], // point of the icon which will correspond to marker's location
                            popupAnchor: [-3, -26] // point from which the popup should open relative to the iconAnchor    
                        });
                        return L.marker(latlng, { icon: pubandvenueIcon });
                }
            }
        });
        map.fitBounds(metallocations.getBounds());
        var clusters = L.markerClusterGroup({
            spiderfyOnMaxZoom: true,
            showCoverageOnHover: false,
            zoomToBoundsOnClick: true
        });
        clusters.addLayer(metallocations);
        map.addLayer(clusters);
    });