Search code examples
leafletmapsreact-leaflet

Gray areas around the map when the map is dragged


I have implemented an offline leaflet map with react. When the map gets dragged around, there are gray areas that show up. To avoid gray areas on the right and left, I have set noWrap={false} in my <TileLayer> and so I have a continuous map horizontally. Code for this part is shown below:

<TileLayer url={offlineURL} attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' **noWrap={false}** ref={map => {this.map = map; }}/>

However, there are gray areas near the poles (top and bottom). I understand that I have a 2D representation of the Earth and so there should technically be no continuous flow near the poles but I don't want the gray areas. Instead, I want to programmatically move the map or set some boundaries to not show the gray areas.

I also set the minZoom for the MapContainer as shown below and this does not fix the issue either. Which makes sense since it only sets the maximum zoom out ability of the map.

<MapContainer center={[0,0]} zoom={2} maxZoom={9} minZoom={2}>

I have attached a picture to show what I'm talking about image showing gray areas past the poles

I have searched to find a solution to this and could not find any. Any help will be greatly appreciated. Thanks!

EDIT:

Christopher's answer was extremely helpful and pointed me in the right direction, however my implementation was class based so I had to modify it slightly. Here's what my code looks like now:

const worldBounds = new L.LatLngBounds( new L.LatLng(-88, -180), new L.LatLng(88, 180));


<MapContainer center={[0,0]} zoom={2} maxZoom={9} minZoom={2} maxBounds={worldBounds} maxBoundsViscosity={1}>
    <TileLayer url={mapURL}/>           
</MapContainer>

I also referred to the following link: https://github.com/Leaflet/Leaflet/blob/v1.0.0/debug/map/max-bounds-bouncy.html


Solution

  • You can use panInsideBounds to snap it back to a world bounds in the drag event handler.

    useEffect(() => {
        const leafletMap = mapRef.current.leafletElement;
        const worldBounds = new LatLngBounds( new LatLng(-88, -180), new LatLng(88, 180));
    
        leafletMap.on('drag', () => {
            leafletMap.panInsideBounds(worldBounds, { animate: false });
        });   
    
    }, [mapRef]);