0

I am trying to change the color of my GeoJSON-Layer on every click in my Ionic React App, but I only managed to change it once for the first click... My idea was to change the color between blue and red everytime a feature is clicked. I had the idea to check for the color in the options of the GeoJSON-Layer, but as written, it only changes the color once for the first click and afterwards nothing happens on any other click.

function LeafletMap() {
  const [map, setMap] = useState(null)

  const onEachClick = (info, layer) => {
    const part = info.properties.Objekt_ID
    const id = info.properties.FID_

    layer.bindPopup("Object ID: <b>" + part + "</b><br>FID: <b>" + id + "</b>")

    if(layer.options.color != "blue") {
      layer.on({
        click: (event) => {
          event.target.setStyle({
            color: "blue",
          });
        }
      }) 
    } else {
      layer.on({
        click: (event) => {
          event.target.setStyle({
            color: "red",
          });
        }
      }) 
    }
  }

  const displayMap = useMemo(
    () => (
      <MapContainer
        center={center}
        zoom={zoom}
        scrollWheelZoom={false}
        whenCreated={setMap}>
        <LayersControl position="topright">
          <LayersControl.BaseLayer checked name="OpenStreetMap - Map">
            <TileLayer
              attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
              url="https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png"
            />
          </LayersControl.BaseLayer>
          <LayersControl.BaseLayer name="Esri - Satelite">
            <TileLayer
              attribution='Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
              url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
            />
          </LayersControl.BaseLayer>
        </LayersControl>

        <GeoJSON data={PL.features} onEachFeature={onEachClick} color="blue"/>
        <GeoJSON data={WWD.features} onEachFeature={onEachClick} color="blue"/>
      </MapContainer>
    ),
    [],
  )

  window.dispatchEvent(new Event('resize'));

  return (
    <div>
      {displayMap}
    </div>
  )

}
export default LeafletMap
2
  • If you can share a little more code on codesandbox or stackblitz it will be easier to help you ...
    – MB_
    Commented Nov 6, 2021 at 11:19
  • This is the whole code, the rest ist just rendering of the app interface. I tried to get it running on JSFiddle, but unfortunatly I did not manage to get my React App running so far with JSFiddle
    – jonsken
    Commented Nov 6, 2021 at 15:00

1 Answer 1

2

There is a really much simpler way to achieve the desired behavior. I can give an example using one geojson and then you can adjust it to your needs.

You need to reset geojson style after each layer click. You can achieve that by taking a geojson reference using react ref and leaflet's resetStyle method. And regarding the change of the style you only need to set the color after each click. No need for if statements there.

const geoJsonRef = useRef();

  const onEachClick = (feature, layer) => {
    const name = feature.properties.name;
    const density = feature.properties.density;

    layer.bindPopup(
      "Name: <b>" + name + "</b><br>Density: <b>" + density + "</b>"
    );

    layer.on({ click: handleFeatureClick });
  };

  const handleFeatureClick = (e) => {
    if (!geoJsonRef.current) return;
    geoJsonRef.current.resetStyle();

    const layer = e.target;

    layer.setStyle({ color: "red" });
  };

...
<GeoJSON ref={geoJsonRef} />

Here is a demo with some data taken from leaflet website

2
  • 1
    thanks @kboul for your answer, helped me a lout! Do you have an idea how to handle it with more than one <GeoJSON /> objects? Because I dont want to declare a useRef() and handleFeatureClick() for each of them?
    – jonsken
    Commented Nov 13, 2021 at 16:49
  • nvm just added everything with a single GeoJSON element, works just as expected
    – jonsken
    Commented Nov 14, 2021 at 13:50

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