Search code examples
javascriptreactjsleafletreact-leaflet

How to select an area in react leaflet


I am using react leaflet to interact with leaflet map. Now I want to use a leaflet plugin called leaflet-area-select to select an area on the map and get current long lat of the rectangle selected. However, it is an leaflet plugin and can't be used on react leaflet. How can I use this plugin ? Or do you know any libraries that can select areas from leaflet map ? Thank you very much!

Select area code ( leaflet-area-select):

let map = new L.Map('map', {
  selectArea: true // will enable it by default
});
 
// or
map.selectArea.enable();
 
map.on('areaselected', (e) => {
  console.log(e.bounds.toBBoxString()); // lon, lat, lon, lat
});
 
// You can restrict selection area like this:
const bounds = map.getBounds().pad(-0.25); // save current map bounds as restriction area
// check restricted area on start and move
map.selectArea.setValidate((layerPoint) => {
  return bounds.contains(
    this._map.layerPointToLatLng(layerPoint)
  );
});
 
// now switch it off
map.selectArea.setValidate();

My code :

export default function Home(){
    return(
        <>
        <Header/>
            <MapContainer center={[10.7743, 106.6669]} zoom={6}>
          <TileLayer
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
          {/* <GeoJSON
          style = {this.countryStyle}
          data={polygonData.features}
          onEachFeature={this.onEachContry}
          
          /> */}
        </MapContainer>
        </>
    )
}

Solution

  • Create your own custom react-leaflet component:

    function AreaSelect() {
      const map = useMap();
      console.log(map);
    
      useEffect(() => {
        if (!map.selectArea) return;
    
        map.selectArea.enable();
    
        map.on("areaselected", (e) => {
          console.log(e.bounds.toBBoxString()); // lon, lat, lon, lat
          L.rectangle(e.bounds, { color: "blue", weight: 1 }).addTo(map);
        });
    
        // You can restrict selection area like this:
        const bounds = map.getBounds().pad(-0.25); // save current map bounds as restriction area
        // check restricted area on start and move
        map.selectArea.setValidate((layerPoint) => {
          return bounds.contains(this._map.layerPointToLatLng(layerPoint));
        });
    
        // now switch it off
        map.selectArea.setValidate();
      }, []);
    
      return null;
    }
    

    Use the external library's (leaflet-area-select) code when the comp mounts and add a rectangle, after doing a Ctrl + left mouse click to draw a rectangular area, on the map.

    Include your custom new component as a MapContainer child:

    <MapContainer center={position} zoom={13} style={{ height: "100vh" }}>
        ...
        <AreaSelect />
      </MapContainer>
    

    Demo