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

如何通过Google Maps JS API实时更新路线起点与途经点?

解决方案

核心问题分析

你的代码存在以下关键问题,导致无法实现路线实时更新:

  1. 使用同步AJAX(async: false)阻塞主线程,性能差且易引发执行异常;
  2. 每次调用route()都新建Marker,而非复用已有实例更新位置,造成地图标记堆积;
  3. 起点(origin)采用硬编码模板变量,无法实时获取最新值;
  4. 未处理异步操作的错误边界,单次请求失败会导致后续定时任务中断。

修改后的完整代码

// 全局实例(放在页面加载完成回调或组件初始化逻辑中)
let map;
let directionsService;
let directionsRenderer;
// 保存标记实例,用于后续更新位置
let startMarker, endMarker, carrierMarker;
// 固定终点(若无需更新,提前从模板获取)
const destination = '{{ $order->customer_post->from_latitude }},{{ $order->customer_post->from_longitude }}';
// 定时任务ID,用于后续取消任务
let updateInterval;

// 初始化地图及相关服务
function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
        zoom: 12,
        center: new google.maps.LatLng('{{ $order->car->latitude }}', '{{ $order->car->longitude }}')
    });
    
    directionsService = new google.maps.DirectionsService();
    directionsRenderer = new google.maps.DirectionsRenderer({ map: map });
    
    // 创建初始标记(后续仅更新位置,不再重复创建)
    startMarker = new google.maps.Marker({
        map: map,
        icon: {
            url: '{{ asset('front/dist/images/red-flag.png') }}',
            scaledSize: new google.maps.Size(35, 40),
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(15, 15)
        },
        title: 'start'
    });
    
    endMarker = new google.maps.Marker({
        position: new google.maps.LatLng('{{ $order->customer_post->from_latitude }}', '{{ $order->customer_post->from_longitude }}'),
        map: map,
        icon: {
            url: '{{ asset('front/dist/images/placeholder.png') }}',
            scaledSize: new google.maps.Size(35, 35),
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(16, 36)
        },
        title: 'end'
    });
    
    carrierMarker = new google.maps.Marker({
        map: map,
        icon: {
            url: '{{ asset('front/dist/images/truck_icon.png') }}',
            scaledSize: new google.maps.Size(35, 35),
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(16, 36)
        },
        title: 'waypoint0'
    });
    
    // 启动定时更新(间隔5秒,可按需调整)
    updateInterval = setInterval(updateRoute, 5000);
    // 首次加载立即执行一次
    updateRoute();
}

// 实时更新路线的核心逻辑
function updateRoute() {
    // 异步获取最新位置数据(假设接口返回JSON格式,包含起点和途经点)
    $.ajax({
        type: "GET",
        url: '{{ route("get-carrier-location", $order->car_id) }}',
        dataType: 'json',
        success: function(data) {
            // 解析接口返回的位置数据(示例格式:{ origin: "lat,lng", carrier: "lat,lng" })
            const origin = data.origin;
            const carrierLocation = data.carrier;
            
            // 更新起点标记位置
            const originLatLng = new google.maps.LatLng(...origin.split(','));
            startMarker.setPosition(originLatLng);
            
            // 更新途经点标记位置
            const carrierLatLng = new google.maps.LatLng(...carrierLocation.split(','));
            carrierMarker.setPosition(carrierLatLng);
            
            // 重新请求并更新路线
            directionsService.route({
                origin: origin,
                waypoints: [{ location: carrierLocation }],
                destination: destination,
                travelMode: 'DRIVING', // 若需动态切换,可替换为全局变量或组件属性
            }, function(response, status) {
                if (status === "OK") {
                    directionsRenderer.setDirections(response);
                } else {
                    console.error('路线请求失败:', status);
                }
            });
        },
        error: function(xhr, status, error) {
            console.error('获取位置数据失败:', error);
        }
    });
}

// 页面销毁时清除定时任务(可选)
// window.addEventListener('beforeunload', function() {
//     clearInterval(updateInterval);
// });

关键修改说明

  1. 异步AJAX替代同步请求:避免阻塞主线程,保证页面正常响应;
  2. 复用Marker实例:提前创建标记并保存引用,通过setPosition()更新位置,避免标记堆积;
  3. 分离初始化与更新逻辑:initMap()负责地图、服务和标记的初始化,updateRoute()专注于数据获取和路线更新;
  4. 添加错误处理:捕获AJAX和路线请求的异常,防止单次失败导致整个定时任务崩溃;
  5. 动态获取位置数据:通过接口实时获取起点和途经点,确保路线与最新位置同步。

对应解决你的三个问题

  • 问题1:每次更新时,先通过setPosition()移动标记,再重新调用directionsService.route()生成新路线并更新,实现标记与路线同步;
  • 问题2:将路线更新逻辑封装为独立函数,通过setInterval定时调用,异步请求不会阻塞,确保每次都能获取新响应;
  • 问题3:移除同步AJAX,确保directionsService实例可正常访问,错误处理避免单次请求失败后任务中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:52:57