简体   繁体   中英

how to add leaflet routing machine control to another div instead of map: react-leaflet

I want to display routing machine control div on dashboard (collapse side bar like google maps) instead of map div, because it is covering the map on mobile version. is there any easier way to do that? I have tried this 2 ways: appending control div to another div , appending control div with onAdd(map)

I have 3 components MapComponent, RoutingMachine and Dashboard.

RoutingMachine.jsx

import React from "react";
import L, { control, Map, map, routing } from "leaflet";
import { createControlComponent } from "@react-leaflet/core";
import "leaflet-routing-machine";
import 'lrm-graphhopper'
import "leaflet-routing-machine/dist/leaflet-routing-machine.css";
import { useEffect } from "react";
import { useMap } from "react-leaflet";


const createRoutineMachineLayer = ({ userLat, userLong, bikeLat, bikeLong }) => {
  
  const instance = L.Routing.control({
    waypoints: [
      L.latLng(userLat, userLong),
      L.latLng(bikeLat, bikeLong)
    ],
    lineOptions: {
      styles: [{ color: "#6FA1EC", weight: 4 }]
    },
    createMarker: function() {
      return null
    },
    router: new L.Routing.GraphHopper('deebe34a-a717-4450-aa2a-f6de3ec9b443', {
      urlParameters: {
          vehicle: 'foot'
      }}),
    show: true,
    addWaypoints: false,
    routeWhileDragging: true,
    draggableWaypoints: true,
    fitSelectedRoutes: true,
    showAlternatives: false
  })

  return instance;
};

const RoutingMachine = createControlComponent(createRoutineMachineLayer);

export default RoutingMachine;

You can achieve that behavior using two refs. One will be the div to attach the control and the other other one the ref of the routing machine instance.

const Map = () => {
  const [map, setMap] = useState(null);
  const routingMachineRef = useRef();
  const pluginRef = useRef();

  useEffect(() => {
    if (!map) return;
    const controlContainer = routingMachineRef.current.onAdd(map);
    pluginRef.current.appendChild(controlContainer);
  }, [map]);
  ...

  <div
  style={{
    display: "grid",
    gridTemplateColumns: "repeat(2, minmax(0, 1fr))"
  }}
>
  <MapContainer... 
     <RoutineMachine ref={routingMachineRef} />
  </MapContainer>
  <div style={{ border: "1px solid black" }} ref={pluginRef} />
</div>
);
};

In this demo you can find the control attached in a div vertically. You can modify it to place it horizontally under the map if you want or anywhere else that fit your needs.

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM