You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Leaflet-Routing-Machine通过点数组绘制可拖拽动态路线?

Leaflet + leaflet-routing-machine 动态多点可拖拽路线问题修复

问题核心

使用静态坐标数组时路线正常可拖拽,但动态传入后端返回的坐标点后,waypoints为空导致路线无法生成且不可拖拽。

问题分析

  1. 异步函数误用:get_route是async函数,直接赋值会返回Promise而非转换后的坐标数组,且useEffect中同步调用setRouting后,state更新是异步的,创建routingControl时routing仍为空数组。
  2. 坐标点重复添加:Map组件中同时用for循环和map方法向points数组push坐标,导致点位重复。
  3. 依赖state传递waypoints冗余:无需将转换后的坐标存入state,可直接在创建routingControl时同步转换,避免异步更新延迟。

修复方案

  1. 移除不必要的async函数,直接在useEffect中同步转换传入的route坐标为L.latLng实例数组。
  2. 修复Map组件中重复添加坐标的逻辑,保留一种循环方式即可。
  3. 直接使用转换后的坐标数组初始化routingControl,无需依赖组件state。

修改后的代码

RoutingLayer组件

import { useEffect } 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();

    useEffect(() => {
        if (!map || !route || route.length === 0) return;

        // 同步转换坐标为L.latLng实例
        const waypoints = route.map(point => L.latLng(point[0], point[1]));

        const routingControl = L.Routing.control({
            waypoints: waypoints,
            routeWhileDragging: true
        }).addTo(map);

        return () => map.removeControl(routingControl);
    }, [map, route]);

    return null;
}

Map组件

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;
            const points = data.map(bus => bus.spanData.coordinates);
            setAllDetails(data);
            setAllLocations(points);
            map_route(points);
        })
    }, [])

    const map_route = (waypoints) => {
        // 直接转换格式,无需额外循环嵌套
        const route = waypoints.map(coords => [coords[0], coords[1]]);
        setRoute(route);
    }

    return (
        <div style={{ width: "100%", height: "100%" }}>
            <MapContainer center={[32.4279, 53.6880]} zoom={7} scrollWheelZoom={true}>
                <TileLayer
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                <RoutingLayer route={route} />
            </MapContainer>
        </div>
    )
}

export default Map

内容的提问来源于stack exchange,提问作者ParisaN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:18:25