吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1031|回复: 52
收起左侧

[Python 原创] 百度地图API 基于起点及终点GPS数据 分别计算起点到各点的直接距离 导航距离及耗时

[复制链接]
chh322 发表于 2024-10-25 15:18
本帖最后由 chh322 于 2024-10-25 15:56 编辑

QQ截图20241025150951.png
百度地图API  基于起点及终点GPS数据 分别计算起点到各点的直接距离 导航距离及耗时
(GCJ-02坐标) 奥维直接复制即可
[Python] 纯文本查看 复制代码
import sys
import json
import requests
from math import radians, cos, sin, sqrt, atan2
from PyQt5 import QtWidgets

class MapApp(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.load_config()

    def init_ui(self):
        self.setWindowTitle("百度地图多点路径计算")
        
        self.api_key_label = QtWidgets.QLabel("API密钥:")
        self.api_key_input = QtWidgets.QLineEdit(self)
        
        self.origin_label = QtWidgets.QLabel("起点 (地点|经度,纬度):")
        self.origin_input = QtWidgets.QLineEdit(self)
        
        self.destination_label = QtWidgets.QLabel("终点 (每行一个地点|经度,纬度):")
        self.destination_input = QtWidgets.QTextEdit(self)
        
        self.calculate_button = QtWidgets.QPushButton("计算路径", self)
        self.calculate_button.clicked.connect(self.calculate_routes)
        
        self.save_button = QtWidgets.QPushButton("保存配置", self)
        self.save_button.clicked.connect(self.save_config)

        # 调试信息文本框
        self.debug_text = QtWidgets.QTextEdit(self)
        self.debug_text.setReadOnly(True)

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.api_key_label)
        layout.addWidget(self.api_key_input)
        layout.addWidget(self.origin_label)
        layout.addWidget(self.origin_input)
        layout.addWidget(self.destination_label)
        layout.addWidget(self.destination_input)
        layout.addWidget(self.calculate_button)
        layout.addWidget(self.save_button)
        layout.addWidget(self.debug_text)  # 将调试文本框添加到布局中

        self.setLayout(layout)

    def load_config(self):
        try:
            with open('config.json', 'r') as file:
                config = json.load(file)
                self.api_key_input.setText(config.get("api_key", ""))
                self.origin_input.setText(config.get("origin", ""))
                self.destination_input.setPlainText(config.get("destination", ""))
        except FileNotFoundError:
            self.debug_text.append("未找到配置文件,加载默认值。")

    def save_config(self):
        config = {
            "api_key": self.api_key_input.text(),
            "origin": self.origin_input.text(),
            "destination": self.destination_input.toPlainText(),
        }
        with open('config.json', 'w') as file:
            json.dump(config, file)
            self.debug_text.append("配置已保存。")

    def parse_location(self, location_str):
        """解析'地点|经度,纬度'格式并返回名称、经度和纬度"""
        try:
            name, coords = location_str.split('|')
            lng, lat = coords.split(',')
            return name, float(lat), float(lng)
        except ValueError:
            self.debug_text.append(f"解析错误: 无效的格式 '{location_str}'")
            return None, None, None

    def calculate_straight_distance(self, lat1, lon1, lat2, lon2):
        """计算两个经纬度之间的直线距离(单位:公里)"""
        R = 6371.0  # 地球半径,单位为公里
        dlat = radians(lat2 - lat1)
        dlon = radians(lon2 - lon1)
        a = sin(dlat / 2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon / 2)**2
        c = 2 * atan2(sqrt(a), sqrt(1 - a))
        distance = R * c
        return round(distance, 2)

    def format_duration(self, duration_seconds):
        """格式化导航时间,当时间小于1小时时显示分钟,否则显示小时"""
        duration_hours = duration_seconds / 3600
        if duration_hours < 1:
            duration_minutes = round(duration_seconds / 60)
            return f"{duration_minutes} 分钟"
        else:
            return f"{round(duration_hours, 2)} 小时"

    def calculate_routes(self):
        api_key = self.api_key_input.text()
        origin_str = self.origin_input.text()
        destinations_str = self.destination_input.toPlainText().strip().splitlines()

        origin_name, origin_lat, origin_lng = self.parse_location(origin_str)
        if not origin_name or not origin_lat or not origin_lng:
            self.debug_text.append("起点格式错误")
            return
        
        # 清空调试文本框内容
        self.debug_text.clear()
        self.debug_text.append("开始计算路径...\n")

        results = []
        
        for destination_str in destinations_str:
            dest_name, dest_lat, dest_lng = self.parse_location(destination_str)
            if not dest_name or not dest_lat or not dest_lng:
                self.debug_text.append(f"终点格式错误: {destination_str}")
                continue

            # 计算直线距离
            straight_distance = self.calculate_straight_distance(origin_lat, origin_lng, dest_lat, dest_lng)

            # 输出请求参数到调试文本框
            #self.debug_text.append(f"\n计算路径 - 起点: {origin_name}({origin_lat},{origin_lng}) 到 终点: {dest_name}({dest_lat},{dest_lng})")

            url = f"https://api.map.baidu.com/directionlite/v1/driving?origin={origin_lat},{origin_lng}&destination={dest_lat},{dest_lng}&ak={api_key}&coord_type=gcj02"
            
            try:
                response = requests.get(url)
                data = response.json()
                
                if data.get('status') == 0:
                    route = data['result']['routes'][0]
                    nav_distance_km = round(route['distance'] / 1000, 2)  # 导航距离转换为公里
                    duration_formatted = self.format_duration(route['duration'])  # 格式化时间
                    
                    # 格式化输出结果
                    result_text = f"{origin_name} - {dest_name}: 直线距离 {straight_distance} 公里, 导航距离 {nav_distance_km} 公里, 耗时 {duration_formatted}"
                    results.append(result_text)
                    #self.debug_text.append(f"结果: {result_text}")
                else:
                    error_msg = f"错误计算路径到 {dest_name}: {data.get('msg')}"
                    results.append(error_msg)
                    self.debug_text.append(error_msg)
            except Exception as e:
                self.debug_text.append(f"异常: {str(e)}")

        # 显示所有结果
        self.debug_text.append("\n".join(results))

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MapApp()
    window.resize(800, 600)
    window.show()
    sys.exit(app.exec_())



回复可见成品下载地址
https://chh322.lanzouw.com/iaeUO2dbejza
密码:bedf

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

hanbazhen 发表于 2024-10-26 09:23
楼主

1、上次回老家根据实时路况拥堵、设置了几个途经点,设计了8条路线,在手机端弄的

网页版比手机版好处是什么呢,鼠标可以随意拖动一段路线,自动更改路线,比手机设置方便。

但这个问题是拖动是会设置途经点,并且途经点不能更改顺序,不能像手机那样更改顺序,这个就不方便了,往往是这里改动好了,发现前面路线还能更快,这时候拖动更改,会变成新的途经点,这时候导航会绕回去,因为你生成了新的途经点


2、这个路径计算好了,但不能发到手机上看,我都是设计好了点收藏,下次回去从收藏里选一条路线出来,希望增加登录百度账号点收藏功能,或者生成二维码,手机端地图扫码再收藏路线
bachelor66 发表于 2024-10-25 17:15
这个真的厉害了,还能算导航距离                        
63298368 发表于 2024-10-25 15:44
taylorgg 发表于 2024-10-25 16:22
6666666666666666
wd6688 发表于 2024-10-25 16:38
感谢楼主分享!!
zhaojianshen 发表于 2024-10-25 16:44
66666666666.今晚就试试
Yourme93 发表于 2024-10-25 16:51
777777777,6翻了
whtaoo 发表于 2024-10-25 16:52
先看看吧。。。。
yy5198758 发表于 2024-10-25 17:07

感谢楼主分享!!
baoyu1201 发表于 2024-10-25 17:30
这个高端操作必须赞一个,感谢楼主
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-1 09:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表