rolo
rolo

Reputation: 543

React leaflet map get corners lat and long

Im working with react-leaflet and Im trying to do the following thing:

In my map I need to show pointers (lat,long) that are in the database, to do this I have to call the backend and get the pointers, the problem is that there are a lot of pointers, and get all of theme in a single call could generate problems.

My idea is that depending the position of the user in the map, make a call to the backend that only get the pointers related to the quadrant that the user is watching, and only call the backend when the zoom of the map is close to the surface.

To achieve this I need two things, the first one is get the (longitude, latitude) of every corner of what the user is watching in the map, the second one is get the zoom (so, I only execute the backend call is the zoom is bigger than 15).

So for example, when the zoom of the map is 15 and the corners are:

corner_top_left: [40.06957696,-105.10070800781251]

corner_top_right: [40.06957696,-104.30969238281251]

corner_bottom_left: [39.81477752660833,-105.10070800781251]

corner_bottom_right: [39.81477752660833,-104.30969238281251]

I could generate a request that get only the pointers that belongs there.

Is there a way to achieve to get this data? Do you think that theres a better way to resolve this problem? thanks for answers.

This is an example of the code used to work with maps, the following code have nothing to do with the problem, is just to let you know how I work with the map.

 import React from 'react'
import { MapContainer, Marker, TileLayer, useMapEvents } from 'react-leaflet'
import { iconMap } from '../../assets/customeIcon/iconMap';
import 'leaflet/dist/leaflet.css'



const MapView = ({ selectedPosition, setSelectedPosition, editable }) => {

    

    const [initialPosition, setInitialPosition] = React.useState([38, -101]); 
 

    const Markers = () => {

        const map = useMapEvents({
            click(e) {
                if(editable){
                setSelectedPosition([
                    e.latlng.lat,
                    e.latlng.lng
                ]);
            }
            },
        })

        return (
            selectedPosition ?
                <Marker
                    key={selectedPosition[0]}
                    position={selectedPosition}
                    interactive={false}
                    icon={iconMap}
                />
                : null
        )

    }



    return  <MapContainer center={selectedPosition || initialPosition} zoom={editable? 5:15} >
        <TileLayer url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
        ></TileLayer>
      <Markers />         
    </MapContainer>
}

export default MapView

Upvotes: 1

Views: 2152

Answers (1)

Seth Lutske
Seth Lutske

Reputation: 10686

This can be done, and with react-leaflet v3's new event handling, it can be done nicely in its own component. What you need first is a reference to the underlying L.map, and you need to hook into the map's native events. You can do this with RLV3's new useMapEvents hook:

function makeACall(bounds, zoom, zoomThreshold = 8) {
  if (zoom > zoomThreshold) {
    fetch('your.endpoint')
      .then(res => res.json())
      .then(res => setMarkersArray(res.markers))
  }
}

const MapEvents = () => {
  const map = useMapEvents({
    moveend: () => makeACall(map.getBounds(), map.getZoom()),
    zoomend: () => makeACall(map.getBounds(), map.getZoom())
  });
  return null;
};

Then include <MapEvents /> as a child of the MapContainer. Now your map will fetch the markers on every zoomend or moveend. This format I showed you assumes the marker data comes in the form of an array of latlngs, and you can .map over those to render them in the MapContainer.

Working codesandbox

Upvotes: 1

Related Questions