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

使用Bing Maps API与folium时坐标结果不一致问题排查

Bing Maps API获取坐标与距离出现不一致问题

问题描述

我通过Bing Maps API获取地址坐标及距离时,发现同一起始地址在JSON响应中返回的坐标不一致,想请教这是我的代码存在问题,还是API响应本身就有较大差异?

背景信息

  • 输入数据源:包含起始地址、配送地址的Excel文件(附图)
  • 代码实现如下:
import urllib.parse
import requests
from haversine import haversine, Unit
import pandas as pd

df = df[['Starting Address', 'Delivery Address', 'Driving Distance (Miles)', 'Radial Distance (Miles)']]

df = df.reset_index()
for index, row in df.iterrows():
    # 编码地址
    enc_start = urllib.parse.quote(df['Starting Address'][index], safe='')
    print(enc_start)
    enc_del = urllib.parse.quote(df['Delivery Address'][index], safe='')
    print(enc_del)
    # 调用API
    url = f"http://dev.virtualearth.net/REST/V1/Routes/Driving?wp.0={enc_start}&wp.1={enc_del}&distanceUnit=mi&optmz=distance&key={bingMapsKey}"
    response = requests.get(url).json()  # 获取JSON格式的API响应

    try:
        # 从bbox中提取起始/配送地址坐标
        s_lat = response["resourceSets"][0]["resources"][0]["bbox"][2]  # 起始地址纬度
        s_lon = response["resourceSets"][0]["resources"][0]["bbox"][3]  # 起始地址经度
        d_lat = response["resourceSets"][0]["resources"][0]["bbox"][0]  # 配送地址纬度
        d_lon = response["resourceSets"][0]["resources"][0]["bbox"][1]  # 配送地址经度

        coords_start = (s_lat, s_lon)  # 起始地址坐标
        coords_del = (d_lat, d_lon)  # 配送地址坐标
        print("c_str ", coords_start)
        print("c_del ", coords_del)

        # 获取优化后的驾车距离
        travelDistance = response["resourceSets"][0]["resources"][0]["travelDistance"]
        print("travel dist ", travelDistance)
        df.loc[[index], 'Driving Distance (Miles)'] = travelDistance

        # folium.Marker(location=[d_lat, d_lon], popup = df["Delivery Address"][index]).add_to(mc) # 创建输出地图

    except IndexError:
        pass

    # 计算直线距离
    radialDistance = haversine(coords_start, coords_del, unit=Unit.MILES)
    df.loc[[index], 'Radial Distance (Miles)'] = radialDistance

输出异常

同一起始地址多次调用API后,返回的坐标值存在差异(附图)


问题原因及解决方案

1. 核心问题:用边界框(bbox)提取坐标完全错误

你当前从bbox中提取坐标的逻辑是错误的。Bing Maps路由API返回的bbox是整个驾车路线覆盖的地理范围,格式为[西南纬度, 西南经度, 东北纬度, 东北经度],并不是起始/终点的精准坐标。每次路线规划的路径可能因实时路况、道路优先级等因素略有差异,导致边界框变化,所以你提取的“起始坐标”其实是边界框的东北角,自然会出现不一致。

2. 正确的坐标提取方式

应该从路线的routeLegs节点下的startLocation/endLocation获取精准的起始/终点坐标:

# 替换原有的坐标提取代码
route = response["resourceSets"][0]["resources"][0]
# 起始地址坐标
start_coords = route["routeLegs"][0]["startLocation"]["point"]["coordinates"]
s_lat, s_lon = start_coords[0], start_coords[1]
# 配送地址坐标
end_coords = route["routeLegs"][0]["endLocation"]["point"]["coordinates"]
d_lat, d_lon = end_coords[0], end_coords[1]

3. 其他优化建议

  • 地址精度优化:如果输入的起始地址不够精确(比如仅包含城市名),Bing Maps的地理编码服务可能返回不同的默认点位(如城市中心不同位置)。建议使用规范的地址格式(包含街道、门牌号、邮编)。
  • API版本升级:你使用的REST/V1是旧版API,建议升级到REST/V8版本,响应结构更稳定,功能更完善。
  • 异常处理修复:原代码except: IndexError的写法错误,应明确捕获异常,且异常发生时避免执行后续的直线距离计算(否则会复用之前的坐标值,导致错误数据)。

修正后的核心代码片段

try:
    route = response["resourceSets"][0]["resources"][0]
    # 获取准确的起始/终点坐标
    start_coords = route["routeLegs"][0]["startLocation"]["point"]["coordinates"]
    s_lat, s_lon = start_coords[0], start_coords[1]
    end_coords = route["routeLegs"][0]["endLocation"]["point"]["coordinates"]
    d_lat, d_lon = end_coords[0], end_coords[1]

    coords_start = (s_lat, s_lon)
    coords_del = (d_lat, d_lon)
    print("c_str ", coords_start)
    print("c_del ", coords_del)

    travelDistance = route["travelDistance"]
    print("travel dist ", travelDistance)
    df.loc[index, 'Driving Distance (Miles)'] = travelDistance

except IndexError as e:
    print(f"处理行{index}时出错: {e}")
    # 异常时设置默认值或跳过
    df.loc[index, 'Driving Distance (Miles)'] = None
    df.loc[index, 'Radial Distance (Miles)'] = None
else:
    # 仅在无异常时计算直线距离
    radialDistance = haversine(coords_start, coords_del, unit=Unit.MILES)
    df.loc[index, 'Radial Distance (Miles)'] = radialDistance

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:06:28