自定义地址计算两地址间最优路线距离代码参考
当我们因为某种需求,需要判断两个指定地址之间,相隔的距离,虽然可以通过地图来判断,但每次都去翻地图还是挺麻烦的,在这里提供一种免API的方式实现地理间隔判断的参考;importmathimportrefromtypingimport*try:fromxbot.app.loggingimport...
扫码分享二维码
当我们因为某种需求,需要判断两个指定地址之间,相隔的距离,虽然可以通过地图来判断,但每次都去翻地图还是挺麻烦的,在这里提供一种免API的方式实现地理间隔判断的参考;importmathimportrefromtypingimport*try:fromxbot.app.loggingimport...
扫码分享二维码
当我们因为某种需求,需要判断两个指定地址之间,相隔的距离,虽然可以通过地图来判断,但每次都去翻地图还是挺麻烦的,在这里提供一种免API的方式实现地理间隔判断的参考;
import math
import re
from typing import *
try:
from xbot.app.logging import trace as print
except:
from xbot import print
def calculate_optimal_route_distance(start_address, end_address):
"""
title: 计算两个地址之间最优路线距离
description: 根据输入的起始地址 % start_address % 和目标地址 % end_address %,计算两地之间的实际道路行驶距离和预估驾车时间(基于道路系数修正)。
inputs:
- start_address (str): 起始地址名称,eg: "海口市秀英区"
- end_address (str): 目标地址名称,eg: "海口市美兰区"
outputs:
- route_info (dict): 包含道路距离和时间的路线信息,eg: "{'distance_km': 12.5, 'duration_minutes': 35}"
"""
if not isinstance(start_address, str) or not isinstance(end_address, str):
raise ValueError("地址必须为字符串类型")
if not start_address.strip() or not end_address.strip():
raise ValueError("地址不能为空")
def _get_detailed_coordinates():
"""
详细的坐标数据库(经度,纬度),按城市分组
"""
return {
# 海口市详细坐标
"海口市秀英区": (110.2950, 20.0178),
"秀英区": (110.2950, 20.0178),
"海口秀英区": (110.2950, 20.0178),
"锦地翰城": (110.2980, 20.0200),
"海口市秀英区锦地翰城": (110.2980, 20.0200),
"海口市秀英区锦地翰城二期": (110.2980, 20.0200),
"海口市秀英区锦地翰城二期B区": (110.2980, 20.0200),
"海口市秀英区锦地翰城二期B区东门": (110.2985, 20.0205),
"海口市美兰区": (110.3692, 20.0311),
"美兰区": (110.3692, 20.0311),
"海口美兰区": (110.3692, 20.0311),
"互联网金融大厦": (110.3720, 20.0330),
"海口市美兰区互联网金融大厦": (110.3720, 20.0330),
"海口市美兰区互联网金融大厦C座": (110.3720, 20.0330),
"海口市美兰区互联网金融大厦C座南门": (110.3725, 20.0325),
"海口市龙华区": (110.3312, 20.0311),
"龙华区": (110.3312, 20.0311),
"海口龙华区": (110.3312, 20.0311),
"海口市琼山区": (110.3540, 19.9817),
"琼山区": (110.3540, 19.9817),
"海口琼山区": (110.3540, 19.9817),
# 原有城市数据
"海口": (110.3312, 20.0311),
"海口市": (110.3312, 20.0311),
"北京": (116.4074, 39.9042),
"天安门": (116.3974, 39.9063),
"天安门广场": (116.3974, 39.9063),
"北京市天安门广场": (116.3974, 39.9063),
"首都国际机场": (116.5844, 40.0801),
"北京首都国际机场": (116.5844, 40.0801),
"北京市首都国际机场": (116.5844, 40.0801),
"上海": (121.4737, 31.2304),
"外滩": (121.4916, 31.2397),
"上海外滩": (121.4916, 31.2397),
"浦东机场": (121.8057, 31.1434),
"上海浦东机场": (121.8057, 31.1434),
"虹桥机场": (121.3365, 31.1979),
"天津": (117.1901, 39.1084),
"重庆": (106.5516, 29.5630),
"广州": (113.2644, 23.1291),
"深圳": (114.0579, 22.5431),
"杭州": (120.1551, 30.2741),
"南京": (118.7969, 32.0603),
"武汉": (114.2998, 30.5928),
"成都": (104.0665, 30.5723),
"西安": (108.9402, 34.3416),
"郑州": (113.6254, 34.7466),
"沈阳": (123.4315, 41.8057),
"长春": (125.3245, 43.8171),
"哈尔滨": (126.5358, 45.8021),
"济南": (117.0009, 36.6758),
"石家庄": (114.5149, 38.0428),
"太原": (112.5489, 37.8706),
"呼和浩特": (111.7519, 40.8424),
"兰州": (103.8236, 36.0581),
"西宁": (101.7782, 36.6171),
"银川": (106.2309, 38.4872),
"乌鲁木齐": (87.6177, 43.7928),
"拉萨": (91.1409, 29.6456),
"昆明": (102.8332, 25.0389),
"贵阳": (106.6302, 26.6477),
"南宁": (108.3669, 22.8170),
"福州": (119.2965, 26.0745),
"南昌": (115.8921, 28.6765),
"长沙": (112.9388, 28.2282),
"合肥": (117.2272, 31.8206),
}
def _smart_match_address(address, coord_db):
"""
智能地址匹配:优先匹配最具体的地址
"""
# 直接完全匹配
if address in coord_db:
return coord_db[address]
# 按地址长度排序,优先匹配更长(更具体)的地址
matches = []
for location_name, coords in coord_db.items():
if location_name in address:
matches.append((len(location_name), location_name, coords))
elif address in location_name:
matches.append((len(location_name), location_name, coords))
# 返回最长匹配的结果
if matches:
matches.sort(key=lambda x: x[0], reverse=True)
return matches[0][2]
# 模糊匹配:移除常见后缀后再匹配
cleaned_address = re.sub(r'(市|省|自治区|特别行政区|区|县|镇|街道|路|号|东门|南门|西门|北门|大厦|二期|C座|B区)', '', address)
for location_name, coords in coord_db.items():
cleaned_location = re.sub(r'(市|省|自治区|特别行政区|区|县|镇|街道|路|号)', '', location_name)
if cleaned_address in cleaned_location or cleaned_location in cleaned_address:
return coords
return None
def _calculate_straight_distance(coord1, coord2):
"""
使用球面距离公式计算两点间直线距离
"""
if coord1 == coord2:
return 0.0
lat1, lon1 = math.radians(coord1[1]), math.radians(coord1[0])
lat2, lon2 = math.radians(coord2[1]), math.radians(coord2[0])
dlat = lat2 - lat1
dlon = lon2 - lon1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.asin(math.sqrt(a))
# 地球半径约为6371公里
distance = 6371 * c
return distance
def _get_road_factor(straight_distance, start_address, end_address):
"""
根据距离和城市类型获取道路系数
"""
# 判断是否为同城内部
same_city = False
for city in ["海口", "北京", "上海", "广州", "深圳", "杭州", "南京", "武汉", "成都", "西安"]:
if city in start_address and city in end_address:
same_city = True
break
if straight_distance == 0:
return 1.0
elif straight_distance <= 2:
# 极短距离,道路因子较小
return 1.2
elif straight_distance <= 10 and same_city:
# 同城短距离,考虑红绿灯、绕路
return 1.5
elif straight_distance <= 30 and same_city:
# 同城中距离
return 1.4
elif straight_distance <= 100:
# 城际短距离或同城长距离
return 1.3
elif straight_distance <= 500:
# 城际中距离,高速公路为主
return 1.25
else:
# 长途,主要是高速公路
return 1.2
def _calculate_road_distance(coord1, coord2, start_address, end_address):
"""
计算实际道路行驶距离
"""
straight_distance = _calculate_straight_distance(coord1, coord2)
road_factor = _get_road_factor(straight_distance, start_address, end_address)
road_distance = straight_distance * road_factor
return round(road_distance, 2)
def _estimate_driving_time(distance_km, start_address, end_address):
"""
根据道路距离估算驾车时间(考虑实际交通状况)
"""
if distance_km == 0:
return 0.0
# 判断是否为同城内部
same_city = False
for city in ["海口", "北京", "上海", "广州", "深圳"]:
if city in start_address and city in end_address:
same_city = True
break
if distance_km <= 3:
# 极短距离,市区道路
avg_speed = 20
elif distance_km <= 15 and same_city:
# 同城短距离,市区道路 + 少量快速路
avg_speed = 25
elif distance_km <= 50 and same_city:
# 同城中长距离,快速路为主
avg_speed = 35
elif distance_km <= 100:
# 城际短距离或同城长距离
avg_speed = 50
elif distance_km <= 300:
# 城际中距离,高速公路
avg_speed = 70
else:
# 长途,高速公路为主
avg_speed = 80
# 计算基础时间
base_time = (distance_km / avg_speed) * 60
# 增加交通拥堵和等红灯时间
if same_city and distance_km <= 30:
# 市内增加30%时间用于等红灯和拥堵
total_time = base_time * 1.3
else:
# 城际增加15%缓冲时间
total_time = base_time * 1.15
return round(total_time, 1)
# 获取详细坐标数据库
coord_db = _get_detailed_coordinates()
# 智能匹配起始地址坐标
start_coord = _smart_match_address(start_address, coord_db)
if start_coord is None:
raise ValueError(f"未找到起始地址'{start_address}'的坐标信息。请提供更具体的地址信息,如:海口市秀英区、海口市美兰区等")
# 智能匹配目标地址坐标
end_coord = _smart_match_address(end_address, coord_db)
if end_coord is None:
raise ValueError(f"未找到目标地址'{end_address}'的坐标信息。请提供更具体的地址信息,如:海口市秀英区、海口市美兰区等")
# 计算实际道路距离
road_distance_km = _calculate_road_distance(start_coord, end_coord, start_address, end_address)
# 估算驾车时间
duration_minutes = _estimate_driving_time(road_distance_km, start_address, end_address)
route_info = {
'distance_km': road_distance_km,
'duration_minutes': duration_minutes
}
print(f"路线计算完成:从 {start_address} 到 {end_address}")
print(f"实际道路距离: {road_distance_km} 公里")
print(f"预估驾车时间: {duration_minutes} 分钟")
return route_infoCopyright Notice
当前文章由【付涛】本人原创开发与文案内容写作,内容版权归当前平台所有,如需转载,请务必注明来源及链接,谢谢合作!
本文最后更新发布于【2025-11-26】,某些文章具有时效性,若有错误或已失效,请联系客服
争议处理:针对本站内容若有异义,亦可直接与【法律顾问:易兴俊,律师联系电话:13825799821】直接联系沟通