How to use Leaflet Routing Machine with React-Leaflet 3?
Asked Answered
C

1

6

The old way of doing things in react-leaflet 2.8.0 was to use MapLayer and withLeaflet.

But now in react-leaflet:

MapLayer and withLeaflet are deprecated as of version 3.

I'm trying to grasp the documentation for core: https://react-leaflet.js.org/docs/core-introduction

but the following doesn't work, I get

The provided object is not a Layer.

import React, { Component, useEffect } from "react";
import { useLeafletContext, leafletElement, createLayerComponent } from '@react-leaflet/core'
import { MapContainer, TileLayer, useMap } from "react-leaflet";
import Leaflet from "leaflet";
import "leaflet-routing-machine";

function Routing(props) {
    const context = useLeafletContext();
    useEffect(() => 
    {
      let routing = createLayerComponent(Leaflet.Routing.control(
      {
        waypoints: [
          Leaflet.latLng(33.52001088075479, 36.26829385757446),
          Leaflet.latLng(33.50546582848033, 36.29547681726967)
        ],
        lineOptions: {
          styles: [{ color: "#6FA1EC", weight: 4 }]
        },
        show: false,
        addWaypoints: false,
        routeWhileDragging: true,
        draggableWaypoints: true,
        fitSelectedRoutes: true,
        showAlternatives: false
      }), )
      const container = context.layerContainer || context.map
      container.addLayer(routing)

      return () => {
        container.removeLayer(routing)
      }
    })
  return null;
}


function MapComponent() {

  return (
      <MapContainer center={[33.5024, 36.2988]} zoom={14} >
        <TileLayer url="https://api.maptiler.com/maps/ch-swisstopo-lbm-dark/256/{z}/{x}/{y}.png?key=gR2UbhjBpXWL68Dc4a3f" />
        <Routing />
      </MapContainer>
    );
  }


export default MapComponent;
Consecution answered 23/5, 2021 at 9:46 Comment(0)
C
13

You're using createLayerComponent, but the routing machine is actually a control. Use createControlComponent.

I also recommend making this as a separate custom component, as described in the docs, rather than putting it in a useEffect. The docs are hard. Feel free to read How to extend TileLayer component in react-leaflet v3? to see if that helps in understanding how to make custom components with react-leaflet v3.

Here's how you'd do it:

import L from "leaflet";
import { createControlComponent } from "@react-leaflet/core";
import "leaflet-routing-machine";

const createRoutineMachineLayer = (props) => {
  const instance = L.Routing.control({
    waypoints: [
      L.latLng(33.52001088075479, 36.26829385757446),
      L.latLng(33.50546582848033, 36.29547681726967)
    ],
    ...otherOptions
  });

  return instance;
};

const RoutingMachine = createControlComponent(createRoutineMachineLayer);

export default RoutingMachine;

Working Codesandbox

Cassidy answered 23/5, 2021 at 15:7 Comment(1)
Awesome answer Seth! really clear with a great working example and suggestions for improvement with references to other answers here on SO.Consecution

© 2022 - 2024 — McMap. All rights reserved.