Add more than one tile layers to <Mapcontainer> in react-leaflet

1.8k Views Asked by At

I want to add more than one tilelayers to mapcontainer. I am not able to accomplish that. I have one tilelayer like this

const magnifiedTiles = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png")

and another one here:

export default function App(): JSX.Element {
 return (
<>
         <MapContainer center={center} zoom={13} scrollWheelZoom={true} style={{height: 'calc(100% - 30px)'}}>
 <TileLayer
      attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
      url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' 
    /> 

</>)
}

I can either get a map reference from map container and use like magnifiedTiles.addTo(<map>)but I dont know how to get the map reference. Other option is addLayer(). However, I am not able to access it with from L.Tilelayer.

I know it leaflet it was as simple as getting map reference and using map.addLayer().

1

There are 1 best solutions below

5
On BEST ANSWER

You can easily get the map reference via a ref in react-leaflet v.4.x

const [map, setMap] = useState(null)

      <MapContainer
        center={center}
        zoom={zoom}
        scrollWheelZoom={false}
        ref={setMap}>
        <TileLayer
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
      </MapContainer>

and then use a useEffect to add any layer you want.

useEffect(()=> {
if (!map) return ;

map.addLayer(...);
},[])

Edit after you added the typescript tag: Same as before only thing that changes you should install @types/react-leaflet and declare the map ref type.

import { Map as MapProp, tileLayer } from "leaflet";
...
const streets = tileLayer(
  "https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}",
  {
    attribution:
      '<a href="https://www.openstreetmap.org/">OpenStreetMap</a>, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, <a href="https://www.mapbox.com/">Mapbox</a>',
    maxZoom: 18,
    id: "mapbox/streets-v11",
    tileSize: 512,
    zoomOffset: -1,
    accessToken:
      ...
  }
); 

Source for streets layer that includes token

const [map, setMap] = useState<MapProp | null>(null);

...
useEffect(() => {
    if (!map) return;

    map.addLayer(streets);
  }, [map]);

Demo