3

map2

map

How do I get an array of elements (id, checked) that are checked in the panel?

Example: I need the list of "talhão" that are checked===true.

import React, { useRef, useState } from 'react'

import L from 'leaflet'
import { MapContainer, LayersControl, GeoJSON } from 'react-leaflet'
import 'leaflet/dist/leaflet.css'
import 'leaflet-draw/dist/leaflet.draw.css'

import {
  GoogleSatelite,
  OpenStreetMap_Mapnik,
  Osm
} from '../../core/map-providers/providers'
import { sendRequest } from '../../api/api-rest'
import { BASEURL } from '../../service'

const MapGrid = (props: any) => {
  const [center, setCenter] = useState({ lat: -17.8916, lng: -51.7406 })
  const layerControlRef = useRef<L.Control.Layers>(null)
  const [plots, setPlots] = useState(null)
  const [thereisPlots, setThereisPlots] = useState(false)
  const ZOOM_LEVEL = 12

  const onClick = async (e) => {
    e.preventDefault()
    setThereisPlots(false)
    setPlots(null)
    const retorno = await sendRequest({
      url: `${BASEURL}/test`
    })

    if (retorno) {
      const lat = retorno[0].centroid.coordinates[1]
      const lng = retorno[0].centroid.coordinates[0]
      setCenter({ lat: lat, lng: lng })
      setPlots(retorno)
      setThereisPlots(true)
    }
  }

  const Plots = () => {
    if (thereisPlots === true) {
      return (
        <>
          {plots.map((item) => {
            const newidly = `${item.plotid}ly`
            const newidgj = `${item.plotid}ly`
            return (
              <LayersControl.Overlay
                key={newidly}
                checked={true}
                name={item.description}
              >
                <GeoJSON
                  key={newidgj}
                  data={item.geom}
                  eventHandlers={{
                    click: (e) => {
                      console.log('Event handler')
                      console.log(e)
                    }
                  }}
                />
              </LayersControl.Overlay>
            )
          })}
        </>
      )
    } else return null
  }

  return (
    <>
      <h2 className={'content-block'}>Map</h2>

      <div>
        <MapContainer
          center={center}
          zoom={ZOOM_LEVEL}
          scrollWheelZoom={true}
          style={{ height: '100%', width: '100%' }}
        >
          <LayersControl
            position="topright"
            ref={layerControlRef}
            collapsed={false}
          >
            <LayersControl.BaseLayer checked name="Maps">
              <Osm />
              <GoogleSatelite />
              <OpenStreetMap_Mapnik />
            </LayersControl.BaseLayer>
            <Plots />
          </LayersControl>
        </MapContainer>
      </div>
      <div>
        <button onClick={onClick}>Get Data from Farm</button>
      </div>
    </>
  )
}

export default MapGrid
2
  • I'm not familiar with React, but I can provide answer in vanilla Leaflet if that's OK with you.
    – TomazicM
    Apr 15 at 15:04
  • Yes. Any help is welcome.
    – Reuber
    Apr 15 at 19:54

1 Answer 1

1

Since I'm not familiar with React, answer will be for vanilla Leaflet JS.

One possibility to get list of overlay from layers control is to use internal control property ._layers, which contains an array of objects, one for each layer in the control. Each object has three properties: .name for layer name in the control, .layer is actual layer, and .overlay, which is true for overlays.

If layer control would be defined/created like this:

var overlayLayers = {
  "layer1": layer1,
  "layer2": layer2
};

layerControl = L.control.layers(baseLayers, overlayLayers, {position: 'topleft', collapsed: false });

then function for creating array of all checked overlays could look like this:

function getCheckedOverlays() {
  var checkedOverlays = [];
  layerControl._layers.forEach(function(layer) {
    if (layer.overlay && map.hasLayer(layer.layer)) {
      checkedOverlays.push({'name': layer.name, 'layer': layer.layer});
    }
  });
  return(checkedOverlays);
}

Since practice of using library internals is not recommended one, it would be better to use overlayLayers object, used to define overlays for the layers ontrol, to iterate though overlays:

function getCheckedOverlays2() {
  var checkedOverlays = [];
  for (let overlayName in overlayLayers) {
    var overlay = overlayLayers[overlayName];
    if (map.hasLayer(overlay)) {
      checkedOverlays.push({'name': overlayName, 'layer': overlay});
    }
  }
  return(checkedOverlays);
}       

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.