您当前位置:首页>项目技能>技能技巧

自定义地址计算两地址间最优路线距离代码参考

发布时间:2025-11-26 阅读量:191 超级管理员

当我们因为某种需求,需要判断两个指定地址之间,相隔的距离,虽然可以通过地图来判断,但每次都去翻地图还是挺麻烦的,在这里提供一种免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_info



上一篇 服装箱包行业AI电商出图系统相关提示词参考
下一篇 PBOOTCMS在本地通过小皮面板phpstudy来实现伪静态配置介绍

内容版权声明

Copyright Notice

内容链接: https://www.diezanrpa.com/jinengjiqiao/1196.html
内容标题: 自定义地址计算两地址间最优路线距离代码参考

当前文章由【付涛】本人原创开发与文案内容写作,内容版权归当前平台所有,如需转载,请务必注明来源及链接,谢谢合作!

本文最后更新发布于【2025-11-26】,某些文章具有时效性,若有错误或已失效,请联系客服

争议处理:针对本站内容若有异义,亦可直接与【法律顾问:易兴俊,律师联系电话:13825799821】直接联系沟通

GEO