Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Single marker fails to get rendered if it is not in or close to a cluster

In my react-leaflet map application, I am fetching the marker positions from a JSON file and want to cluster the markers which are located nearby. Using the react-leaflet-markercluster library, the clustered markers render successfully as required. However, if there is a single marker which is either not part of a cluster or close to a cluster, it does not render on the map. This is reproducible when passing the markers as an array to markers prop as well as when defining the Markers component directly in MarkerClusterGroup (as shown in example).

In the code snippet below, the first 6 markers are rendered as a cluster since they are located close. However, the last marker (position={[42.2793, -71.4162]}) is not displayed at all since it in not part of any of the clusters. What is the best way to fix this?

"leaflet": "^1.5.1", "leaflet.markercluster": "^1.4.1", "react-leaflet": "1.9.1", "react-leaflet-markercluster": "^1.1.8"

Single marker outside of a MarkerClusterGroup works. However, a single marker inside the MarkerClusterGroup does not get displayed.

The required styles for Leaflet and react-leaflet-markercluster are imported in the project. I've added the following to the index.html page within the head section (as suggested here https://www.npmjs.com/package/react-leaflet-markercluster#getting-started):

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
    integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
    crossorigin=""/>
<!--Make sure you put this AFTER Leaflet's CSS-->
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
    integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
    crossorigin=""></script>
<link rel="stylesheet" href="https://unpkg.com/react-leaflet-markercluster/dist/styles.min.css" />
  render() {
    const mapCenter = [this.center.lat, this.center.lng];
    return (
      <LeafletMap 
        center={mapCenter} 
        zoom={this.center.zoom}
        maxZoom={10}
        minZoom={2.5}
        maxBounds={[[-85,-180],[85,180]]}
        maxBoundsViscosity={0.1}
        bounceAtZoomLimits={true}     
        easeLinearity={0.35} 
        >
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
        />

        <MarkerClusterGroup
              showCoverageOnHover={false}
              spiderfyDistanceMultiplier={2}
              animate={true}
              zoomToBoundsOnClick={true}
              spiderfyOnMaxZoom={false}
              maxClusterRadius={60}
            >
            <Marker position={[50.0647, 19.9450]} />
            <Marker position={[48.9226, 24.7111]} />
            <Marker position={[48.7164, 21.2611]} />
            <Marker position={[51.5, -0.09]} />
            <Marker position={[51.5, -0.09]} />
            <Marker position={[51.5, -0.09]} />
            <Marker position={[42.2793, -71.4162]} />
         </MarkerClusterGroup>
      </LeafletMap>
    );
  }

like image 604
oifun Avatar asked Nov 18 '25 03:11

oifun


1 Answers

I have been using Leaflet along with Leaflet cluster for a few months now and I ran into the same issue.

If you look at your minZoom, it is 2.5 and if you have a look at the leaflet.markercluster source code particularly at the line:

https://github.com/Leaflet/Leaflet.markercluster/blob/master/src/MarkerCluster.js#L275

You will notice that either this._group._map.getMinZoom() or zoomLevel isn't rounded or floored - using Math.round or Math.floor to be exact. ( although there are some sections of the code where one or both of them are )

In the bigger picture, when this function runs recursively - it is going to get to a point where it has to match: https://github.com/Leaflet/Leaflet.markercluster/blob/master/src/MarkerCluster.js#L382

Since the value isn't floored or rounded, it is going to try to match (0.5 === 0) and this conditional will fall through. As a result, some markers are never going to be added to the map and rendered.

I got this fixed by setting the minZoom of the map to be an Integer -3. So you should go with an Integer as well - which, in your case, will be minZoom={3} or minZoom={2}

I hope this answered your question and helped.

like image 129
Alex000001 Avatar answered Nov 21 '25 09:11

Alex000001



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!