Reputation: 817
I'm using React and React-Leaflet to generate a map of circleMarkers given data points and their Lat/Long coordinates. I have no issues rendering a map of data, and even being able to change the data rendered if a user filters by filter type on a sidebar.
<Map center={[this.props.data[0].Latitude, this.props.data[0].Longitude]} zoom={12}>
<TileLayer
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
/* code for rendering circleMarkers goes here */
</Map>
When a user clicks on a marker, I have it so a popup appears on the map for the data with a little blurb about the corresponding point.
<CircleMarker center={[entry.Latitude, entry.Longitude]} color={this.determineMarkerColor(entry)} radius={this.computeMarkerSize(entry)}>
<Popup>
<span>Radius is for: {this.props.filterType} </span>
</Popup>
</CircleMarker>
Is there a way to configure the Map so that it can figure out when a user is trying to, for example, shift click to select multiple points and then pass the selected points as an array? Or, even better, how can I make the Map interactive so a user can drag and drop a custom area (like drawing a square or circle) and select all rendered points WITHIN that area?
I'm planning on passing this array of selected data to another component that will graph it.
Any advice on where to look for this would be appreciated.
Upvotes: 2
Views: 3732
Reputation: 51
It's already almost 3 years passed away but here is my solution with pressing shift and selecting an area of markers, maybe it will be useful for somebody
Map
has onmousedown
& onmouseup
methods
<Map
ref={saveMap}
onmousedown={onMouseDown} // set start position in state
onmouseup={onMouseUp} // end position and logic to select markers
className="leaflet-container"
center={position}
zoom={viewport.zoom}
>
With onmousedown
it is possible to find the start position
when the user pressed shift and started to move the mouse to select an area
onmousedown
returns an event with latlng
property - start position:
const onMouseDown = useCallback((e: LeafletMouseEvent) => {
if (e.originalEvent.shiftKey) { // check if the shift key been pressed
setStartPoint(e.latlng);
}
}, []);
onmouseup
also returns an event with latlng
property - end position:
const onMouseUp = useCallback((e: LeafletMouseEvent) => {
if (e.originalEvent.shiftKey && startPoint) {
const bounds = new L.LatLngBounds(startPoint, e.latlng); // creates a class which will help to identify if an element is within the selection boundaries
const selectedIds: string[] = [];
for (let i = 0; i < orders?.length; i++) {
const { geometry: { coordinates } } = orders[i];
const point = new L.LatLng(coordinates[0], coordinates[1]);
bounds.contains(point) && selectedIds.push(orders[i].properties.entry);
}
onSelectOrder(selectedIds);
setStartPoint(null);
}
}, [onSelectOrder, orders, startPoint]);
It works pretty well for my purposes to select multiple orders on the map
Upvotes: 5
Reputation: 2311
You could play around with leaflet-draw in order to get the selection tool that you want. With leaflet-draw you can draw polygons, circles, rectangles, etc and get the bounds of the figure you've drawn. There's also a library called point-in-polygon that can return the coordinates inside a boundaries parameter.
TLDR:
Upvotes: 4