Search code examples
leafletreact-leafletreact-leaflet-v3

React leaflet Canvas


I am trying to draw about 50K points with the leaflet Marker method and it's impossible du the time rendering and ram needed. The new method I saw is to use Leaflet-canvas to draw point on-screen ' not in the DOM. How can I perform this in React leaflet 3.X. I tried https://www.npmjs.com/package/react-leaflet-canvas-markers But it doesn't support the V3 of the leaflet.

Any suggestion?


Solution

  • install and import the library npm i leaflet-canvas-marker

    Create a custom component and use a useEffect that will mimic the behavior of vanilla leaflet example

    import { useEffect } from "react";
    import { useMap } from "react-leaflet";
    import "leaflet-canvas-marker";
    import L from "leaflet";
    
    export default function LeafletCanvasMarker() {
      const map = useMap();
    
      useEffect(() => {
        if (!map) return;
    
        var ciLayer = L.canvasIconLayer({}).addTo(map);
    
        ciLayer.addOnClickListener(function (e, data) {
          console.log(data);
        });
        ciLayer.addOnHoverListener(function (e, data) {
          console.log(data[0].data._leaflet_id);
        });
    
        var icon = L.icon({
          iconUrl: "https://unpkg.com/[email protected]/dist/images/marker-icon.png",
          iconSize: [20, 18],
          iconAnchor: [10, 9],
        });
    
        var markers = [];
        for (var i = 0; i < 50000; i++) {
          var marker = L.marker(
            [58.5578 + Math.random() * 1.8, 29.0087 + Math.random() * 3.6],
            { icon: icon }
          ).bindPopup("I Am " + i);
          markers.push(marker);
        }
        ciLayer.addLayers(markers);
      }, [map]);
    
      return null;
    }
    

    Include your custom component as a MapContainer child

    <MapContainer center={position} zoom={10} style={{ height: "100vh" }}>
       <TileLayer
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
          />
       <LeafletCanvasMarker />
    </MapContainer>
    

    You should get a result similar to the following picture: enter image description here