码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 经纬度计算距离公式(测地线距离)


    目录

    • 前言
    • 计算测地线距离
      • 方法1: 调用geopy库函数
      • 方法2: 使用半正矢公式
      • geopy和半正矢公式误差比较
      • geopy和半正矢公式耗时比较
    • 附

    前言

    做的几个项目都和两个poi测地线距离相关,特地总结一下,方便使用。

    计算测地线距离

    求上海和西安的距离。

    # (纬度,经度)
    point1 = (31.231706, 121.472644) # 上海
    point2 = (34.263161, 108.948024) # 西安
    
    • 1
    • 2
    • 3

    方法1: 调用geopy库函数

    geopy 可以使用第三方地理编码器和其他数据源定位全球地址、城市、国家和地标的坐标。它的一个重要功能就是实现经纬度地理位置转换,即求两点之间的测地线距离。但geopy速度相对较慢。

    # geopy版本为'2.2.0'
    import geopy.distance
    # 输出距离,单位为km
    geopy.distance.geodesic(point1, point2).km
    """
    输出:
    1220.029989895109
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方法2: 使用半正矢公式

    半正矢公式是一种根据两点的经度和纬度来确定球面两点之间距离的计算方法。原理参见 wiki百科-Haversine formula。

    from math import radians, sin, cos, asin, sqrt
    def get_geodesic(point1, point2):
        """
        point1,point2格式为(纬度,经度)
        如(121.472644, 31.231706)
        """
        lat1,lon1 = map(radians, point1)
        lat2,lon2 = map(radians, point2)
        # 半正矢公式(经纬度求解两点球面距离)
        # Haversine formula
        diff_lon = lon2 - lon1 
        diff_lat = lat2 - lat1 
        P = sin(diff_lat/2)**2 + cos(lat1)*cos(lat2)*sin(diff_lon/2)**2
        Q = 2 * asin(sqrt(P))   
        # 地球半径(km)
        R = 6371  
        # 测地线距离
        geodesic = Q * R
        return geodesic
    get_geodesic(point1, point2)
    """
    输出:
    1217.912379941211
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    注意,方法1和方法2之间存在一定误差,大量的数据表明,半正矢公式相比于geopy.distance.geodesic的平均误差为 0.16%,即1000km相差约1.6km,见下一节。

    geopy和半正矢公式误差比较

    平均误差计算:

    import numpy as np
    from tqdm import tqdm
    L = []
    for i in tqdm(range(10000)):
        # 纬度范围为[-90,90],经度范围为[-180,180]
        lat1, lat2 = np.random.random(2)*np.sign(np.random.randn(2))*90
        lon1, lon2 = np.random.random(2)*np.sign(np.random.randn(2))*180
        point1 = (lat1, lon1)
        point2 = (lat2, lon2)
        d1 = geopy.distance.geodesic(point1, point2).km
        d2 = get_geodesic(point1, point2)
        L.append((d1, d2))
    L1 = [abs(x[0]-x[1])/x[0] for x in L]
    print(np.mean(L1))
    """
    输出:
    0.0016
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    geopy和半正矢公式耗时比较

    在AMD Ryzen 7 5800U上测试了两个函数的耗时,其结果如下:

    geopy.distance.geodesic(point1, point2).km 万次计算平均每次耗时

    155 µs ± 3.97 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
    
    • 1

    get_geodesic(point1, point2) 百万次计算平均每次耗时

    1.08 µs ± 14.4 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
    
    • 1

    可见,geopy时间复杂度较大,单次运行时长是半正矢公式的143.5倍。

    附

    计算两个坐标之间的距离资料:

    • https://www.hhlink.com/%E7%BB%8F%E7%BA%AC%E5%BA%A6/
    • 谷歌地球
  • 相关阅读:
    MongoDB副本集特点验证
    Yolov8涨点技巧:MobileViTAttention助力小目标检测,涨点显著,MobileViT移动端轻量通用视觉transformer
    ansible安装
    无胁科技-TVD每日漏洞情报-2022-7-30
    股票价格预测 | Python实现基于LSTM与Transfomer的股票预测模型(pytorch)
    企业运维之 kubernetes(k8s) 的存储
    vue实战入门后台篇五:springboot+mybatis实现网站后台-操作日志功能实现
    js实现放大镜(详细注释)
    PMP每日一练 | 考试不迷路-12.3(包含敏捷+多选)
    SQL中的数据类型和规范化,助力数据存储优化
  • 原文地址:https://blog.csdn.net/u012762410/article/details/127660385
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号