perliedman / leaflet-routing-machine

Control for routing in Leaflet
https://www.liedman.net/leaflet-routing-machine/
Other
1.08k stars 350 forks source link

React - cannot clear old routes from map #596

Open JStant95 opened 4 years ago

JStant95 commented 4 years ago

Hi there,

Thank you for your service, its great!

I'm currently using LRM with react, and I'm having an issue in deleting an old route after posting a new one.

let leafletElement = L.Routing.control({
      waypoints: [
        L.latLng(startingCoords[0], startingCoords[1]),
        L.latLng(endingCoords[0], endingCoords[1]),
      ],
      router: L.Routing.graphHopper(apiGraphHopper, {
        urlParameters: {
          vehicle: vehicle,
        },
      }),
    });
    leafletElement.addTo(map.leafletElement);

I've tried using removeLayer, removeControl and splicewaypoints without success, have you got any suggestions?

perliedman commented 4 years ago

Hard to tell without seeing an example, but removeControl should definitely clear any routes on the map. spliceWaypoints will clear the route if all waypoints are removed, but not the control itself.

If you really think this is a LRM issues, please post an example exhibiting the problem without using React - I suspect the issue is rather with how you are integrating with the library rather than with removeControl, which is pretty straight forward.

alumedot commented 4 years ago

Hey, @JStant95 , did you solve the issue? I have the same problem, I'm trying to implement adding routes dynamically to the map

Screenshot 2020-08-18 at 09 47 20

I check the element in the grid on the left and route appear on the map, when the element checked out, it doesn't remove from the map, the line still there, only markers removed:

Screenshot 2020-08-18 at 10 00 03

Code, just iterate through the active routes, array with checked elements:

return activeRoutes.map(route => (
     <RoutingMachine key={route.id} orders={route.orders} map={map} />
 ));

and render the RoutingMachine component:

class Routing extends MapLayer<Props & MapLayerProps> {
  createLeafletElement() {
    let leafletElement = L.Routing.control({
      waypoints: this.props.orders.map(order => L.latLng(order.lat, order.lng)),
      draggableWaypoints: false,
      addWaypoints: true,
      show: false,
    });
    leafletElement.addTo(this.props.map.leafletElement);
    return leafletElement.getPlan();
  }
}
export default withLeaflet(Routing);

And if you switch the checkbox multiple times, the line is added multiple times to HTML:

Screenshot 2020-08-18 at 10 05 25

I did research about adding/removing multiple routes to the map with leaflet-routing-machine but not successful yet

Taimoor0217 commented 4 years ago

@JStant95 @alumedot I came across the same issue while using LRM with react-leaflet. I am shraring my solution if someone comes accross a similar scenario. I was able to remove the previous path by passing an empty array to setWayPoints.

  updateLeafletElement(props) {
    if(this.leafletElement){
      if(this.props.show){
        this.leafletElement.setWaypoints(this.props.waypoints);
      }else{
        this.leafletElement.setWaypoints([]);
      }
    }
  }

You can check my implementation here

dfernandos commented 1 year ago

I'm also having this issue.

Currently everytime when I click in one markers it shows the route from the current location to the marker clicked.

I want that when I click in another marker the previous route disappear and shows only the new route.

This is how the UI is behaving right now. I have 2 routes.

image

` function RoutingMachine({ currentLocation, selectedTerritory }) { const map = useMap(); const routingControlRef = useRef(null); const routeLineLayerRef = useRef(null);

useEffect(() => {
  if (!map) return; // Wait for the map to be ready

  if (!routingControlRef.current) {
    // Create the routing control only once
    routingControlRef.current = L.Routing.control({
      waypoints: [],
      routeWhileDragging: true,
      plan: L.Routing.plan([], {
        show: true
      })
    });

    routingControlRef.current.addTo(map);
  }

  // Update the waypoints and remove the previous route when currentLocation or selectedTerritory changes
  if (currentLocation && selectedTerritory) {
    const waypoints = [
      L.latLng(currentLocation[0], currentLocation[1]),
      L.latLng(selectedTerritory.latLong[0], selectedTerritory.latLong[1])
    ];

    // Remove the previous route line layer from the map if it exists
    if (routeLineLayerRef.current) {
      map.removeLayer(routeLineLayerRef.current);
    }

    // Set the new waypoints and automatically display the new route
    routingControlRef.current.setWaypoints(waypoints);

    // Store the reference to the new route line layer
    routeLineLayerRef.current = routingControlRef.current.getPlan().getWaypoints()[0].latLng;
  } else {
    // If either currentLocation or selectedTerritory is null, remove the waypoints and the route from the map
    routingControlRef.current.setWaypoints([]);
    if (routeLineLayerRef.current) {
      map.removeLayer(routeLineLayerRef.current);
      routeLineLayerRef.current = null; // Reset the routeLineLayerRef
    }
  }
}, [map, currentLocation, selectedTerritory]);

return null;

} `

curtisy1 commented 1 year ago

@dfernandos Can you put together some kind of codepen or codesandbox so I could have a look? Your solution should work since setWaypoints removes all the waypoints internally if called with an empty array. That being said, if you're not using TypeScript, you could also do the following:

routingControlRef.current._clearLines();

Which is defined here and directly removes all lines and alternatives from the map

codestudent24 commented 12 months ago

Best practive to clear routes in React leaflet-routing-machine in this sandbox