Clusters not showing at some levels in Leaflet and useSupercluster

Viewed 17

In the Leaflet map, I´m rendering 80,000 points (markers) Works fine, but at some zoom levels, the map not shows any marker or cluster. If I zoom, appears the clusters. But I want to show clusters in all the map at all the map zoom levels.

Live demo: https://gifyu.com/image/Sw5Fn

Source code:

import React, { useEffect, useState, useCallback } from 'react';
import useSupercluster from "use-supercluster";

import { divIcon } from 'leaflet';
import { Marker, useMap } from 'react-leaflet';
import { iconMarker } from './MarkerIcon';
import "./ShowMarkersCluster.css";

const icons = {};

const fetchIcon = (count, size) => {
    if (!icons[count]) {
        let classMarker = "";
        if (count < 10) {
            classMarker = "green-marker"
        } else if (count < 40) {
            classMarker = "warning-marker";
        } else if (count > 40) {
            classMarker = "danger-marker"
        }

        icons[count] = divIcon({
            html: `<div class='cluster-marker ${classMarker}' style="width: ${size}px; height: ${size}px;">
        ${count}
      </div>`,
        });
    }
    return icons[count];
};

const ShowMarkersCluster = ({ onClickMarker, data }) => {
    const maxZoom = 21;
    const [bounds, setBounds] = useState(null);
    const [zoom, setZoom] = useState(12);
    const map = useMap();

    function updateMap() {
        console.log(map)
        const b = map.getBounds();
        setBounds([
            b.getSouthWest().lng,
            b.getSouthWest().lat,
            b.getNorthEast().lng,
            b.getNorthEast().lat
        ]);
        setZoom(map.getZoom());
    }


    const onMove = useCallback(() => {
        updateMap();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [map]);

    useEffect(() => {
        updateMap();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [map]);


    useEffect(() => {
        map.on("moveend", onMove);
        return () => {
            map.off("moveend", onMove);
        };
    }, [map, onMove]);


    const points = data.map((data, id) => ({
        type: "Feature",
        properties: { cluster: false, crimeId: id, category: data.Delito },
        geometry: {
            type: "Point",
            coordinates: [
                parseFloat(data.longitud),
                parseFloat(data.latitud),
            ],
        },
    }));

    const { clusters, supercluster } = useSupercluster({
        points: points,
        bounds: bounds,
        zoom: zoom,
        options: { radius: 100, maxZoom: 20 },
    });


    return (
        <>
            {clusters.map((cluster) => {
                const [longitude, latitude] = cluster.geometry.coordinates;
                const { cluster: isCluster, point_count: pointCount } = cluster.properties;

                if (isCluster) {
                    return (
                        <Marker
                            key={`cluster-${cluster.id}`}
                            position={[latitude, longitude]}

                            icon={fetchIcon(
                                pointCount,
                                10 + (pointCount / points.length) * 40
                            )}
                            eventHandlers={{
                                click: () => {
                                    const expansionZoom = Math.min(
                                        supercluster.getClusterExpansionZoom(cluster.id),
                                        maxZoom
                                    );
                                    map.setView([latitude, longitude], expansionZoom, {
                                        animate: true,
                                    });
                                },
                            }}
                        />
                    );
                }
                // Only one marker
                return (
                    <Marker
                        key={`marker-${cluster.properties.crimeId}`}
                        position={[latitude, longitude]}
                        icon={iconMarker}
                        eventHandlers={{
                            click: (coords) => {
                                onClickMarker(coords.latlng);
                            },
                        }}
                    />
                );
            })}
        </>
    );
}

export default ShowMarkersCluster;

I´m using use-supercluster to make the clusters and react-leaflet to render the map

0 Answers
Related