I want to drag route from many point using leaflet
and leaflet-routing-machine
. I do not know How to pass all of locations into the waypoints
.
import { useEffect, useState } from "react";
import L from "leaflet";
import "leaflet-routing-machine/dist/leaflet-routing-machine.css";
import "leaflet-routing-machine";
import { useMap } from "react-leaflet";
L.Marker.prototype.options.icon = L.icon({
iconUrl: "https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png"
});
export default function RoutingLayer({ route }) {
const map = useMap();
const waypoints = route ? route : null;
const [routing, setRouting] = useState([]);
useEffect(() => {
var temp = get_route(waypoints)
setRouting(temp);
if (!map) return;
const routingControl = L.Routing.control({
waypoints: routing.length > 0 && routing,
// waypoints: [L.latLng(37.2461188, 49.6219894), L.latLng(35.7074147, 51.3376843)],
routeWhileDragging: true
}).addTo(map);
return () => map.removeControl(routingControl);
}, [map, waypoints]);
async function get_route(waypoints) {
let temp = []
for (let i = 0; i < waypoints.length; i++) {
temp.push(L.latLng(waypoints[i][0], waypoints[i][1]))
}
return temp;
}
return null;
}
Above code works with waypoints: [L.latLng(37.2461188, 49.6219894), L.latLng(35.7074147, 51.3376843)],
But I want to make dynamic this points. This code has not error but does not drag route. Because waypoints is empty.
I guess to use async await for get_route
but does not work.
This is MapContainer
:
import React, { useEffect, useState } from 'react'
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
import "./monitoring.css";
import RoutingLayer from "./RoutingLayer";
function Map() {
const [allLocations, setAllLocations] = useState([])
const [allDetails, setAllDetails] = useState([])
const [route, setRoute] = useState([])
useEffect(() => {
GetAllBusLocation().then((res) => {
const data = res.data.data;
var points = []
setAllDetails(data);
for (let i = 0; i < data.length; i++) {
points.push(data[i].spanData.coordinates)
}
data.map((bus) => {
points.push(bus.spanData.coordinates)
})
setAllLocations(points)
map_route(points);
})
}, [])
const map_route = (waypoints) => {
let route = []
for (let i = 0; i < waypoints.length; i++) {
let temp = []
temp.push(waypoints[i][0], waypoints[i][1])
route.push(temp)
}
setRoute(route);
return route;
}
return (
<div style={{ width: "100%", height: "100%" }}>
<MapContainer center={[32.4279, 53.6880]} zoom={7} scrolWheelZoom={true}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<RoutingLayer route={route ? route : null} />
</MapContainer>
</div>
)
}
export default Map
Finally, I solved this problem. It was an asynchrony issue. First, load points or locations and then convert to route and then draw route. So, I stopped running the rest until complete execution of get_route(points)
using await
.
import L from "leaflet";
function Map() {
const [waypoints, setWaypoints] = useState([])
useEffect(() => {
GetAllBusLocation(user).then(async (res) => {
...
// points is my coordinates
var route = await get_route(points);
setWaypoints(route);
})
}, [])
async function get_route(waypoints) {
let temp = []
for (let i = 0; i < waypoints?.length; i++) {
temp.push(L.latLng(waypoints[i][0], waypoints[i][1]))
}
return temp;
}
return (
<MapContainer>
...
<RoutingBusLayer waypoints={waypoints ? waypoints : null} />
</MapContainer>
)
}
export default Map