Python经纬度坐标转换为距离及角度的实现

Python中经纬度坐标转换为距离以及角度的实现可以通过使用Haversine公式来实现。

Haversine公式

Haversine公式是一种通过经纬度计算球面距离的算法,它的计算方式基于圆心角,其公式如下:

$d = 2r\arcsin\sqrt{\sin^2\frac{\phi_2-\phi_2}{2}+\cos\phi_1\cos\phi_2\sin^2\frac{\lambda_2-\lambda_1}{2}}$

其中,$d$表示两点间的距离,$r$为球体的半径,$\phi_1,\phi_2,\lambda_1,\lambda_2$分别表示两点的纬度和经度。

下面是Python中利用Haversine公式实现经纬度坐标转换为距离及角度的代码:

from math import radians, cos, sin, sqrt, atan2

def haversine(lat1, lon1, lat2, lon2):
    R = 6371  # 地球半径,单位为千米
    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])

    a = sin((lat2-lat1)/2)**2 + cos(lat1)*cos(lat2)*sin((lon2-lon1)/2)**2
    distance = 2 * R * atan2(sqrt(a), sqrt(1-a))

    bearing = atan2(sin(lon2-lon1)*cos(lat2), cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1))
    bearing = (bearing + 360) % 360

    return distance, bearing

该函数需要输入四个参数:原点的纬度($lat_1$)和经度($lon_1$),目标点的纬度($lat_2$)和经度($lon_2$),输出为一个包含距离和角度的元组。其中,距离以千米为单位,角度以度数表示,以北为0度,东为90度,南为180度,西为270度。

例如,我们希望计算北京市和上海市两个城市的距离和角度,其经纬度坐标分别为。

北京市 (39.9042° N, 116.4074° E)
上海市 (31.2304° N, 121.4737° E)

那么我们可以运行以下代码进行计算:

distance, bearing = haversine(39.9042, 116.4074, 31.2304, 121.4737)
print(f"Distance between Beijing and Shanghai is {distance:.2f} km, bearing {bearing:.2f} degrees")

输出结果为:

Distance between Beijing and Shanghai is 1061.44 km, bearing 117.61 degrees

这说明北京到上海的距离约为1061.44公里,方位角为117.61度。

Vincenty公式

除了Haversine公式,还可以使用Vincenty公式来计算两个经纬度之间的距离,Vincenty公式可以更准确地计算球面距离。下面是Python中利用Vincenty公式实现经纬度坐标转换为距离及角度的代码:

from math import radians, atan2, tan, sin, cos
from numpy import arctan2, sqrt, deg2rad


def vincenty(lat1, lon1, lat2, lon2, a=6378137.0, b=6356752.314245, f=1/298.257223563):

    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])

    L = lon2 - lon1
    U1 = atan2((1 - f) * tan(lat1), cos(L))
    U2 = atan2((1 - f) * tan(lat2), cos(L))

    sinU1, cosU1 = sin(U1), cos(U1)
    sinU2, cosU2 = sin(U2), cos(U2)

    lambda_old = L

    for i in range(1000):
        sinLambda, cosLambda = sin(lambda_old), cos(lambda_old)
        sinSigma = sqrt((cosU2*sinLambda)**2 + (cosU1*sinU2 - sinU1*cosU2*cosLambda)**2)
        cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda
        sigma = atan2(sinSigma, cosSigma)
        sinAlpha = (cosU1*cosU2*sinLambda) / sinSigma
        cosSqAlpha = 1 - sinAlpha**2
        if cosSqAlpha == 0:
            cos2SigmaM = 0
        else:
            cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha
        C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha))

        lambda_new = L + (1-C)*f*sinAlpha*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM**2)))

        if abs(lambda_new - lambda_old) < 1e-12:
            break

        lambda_old = lambda_new

    uSq = cosSqAlpha*(a**2 - b**2)/b**2
    A = 1 + uSq/16384*(4096 + uSq*(-768 + uSq*(320 - 175*uSq)))
    B = uSq/1024*(256 + uSq*(-128 + uSq*(74 - 47*uSq)))
    deltaSigma = B*sinSigma*(cos2SigmaM + 1/4*B*(cosSigma*(-1+2*cos2SigmaM**2) - 1/6*B*cos2SigmaM*(-3+4*sinSigma**2)*(-3+4*cos2SigmaM**2)))

    distance = b*A*(sigma-deltaSigma)
    bearing = arctan2(cosU2*sin(L), cosU1*sinU2 - sinU1*cosU2*cos(L))
    bearing = (bearing + 360) % 360

    return distance, bearing

同样的,输入为原点的纬度($lat_1$)和经度($lon_1$),目标点的纬度($lat_2$)和经度($lon_2$),输出结果仍为一个包含距离和角度的元组。距离以米为单位,角度以度数表示,以北为0度,东为90度,南为180度,西为270度。

例如,我们想要计算纽约到旧金山的距离和角度。

纽约市 (40.7128° N, 74.0059° W)

旧金山 (37.7749° N, 122.4194° W)

现在,我们可以使用以下代码计算距离和角度:

distance, bearing = vincenty(40.7128, -74.0059, 37.7749, -122.4194)
print(f"Distance between New York and San Francisco is {distance/1000:.2f} km, bearing {bearing:.2f} degrees")

输出结果为:

Distance between New York and San Francisco is 4152.37 km, bearing 295.27 degrees

这说明纽约到旧金山的距离约为4152.37公里,方位角为295.27度。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python经纬度坐标转换为距离及角度的实现 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Python使用遗传算法解决最大流问题

    Python使用遗传算法解决最大流问题 本文将详细介绍如何使用Python和遗传算法解决最大流问题。我们将介绍最大流问题的基本原理和遗传算法的基本原理,以及如何使用Python实现遗传算法解决最大流问题。同时,我们提供两个示例说明,分别使用遗传算法解决最大流问题和最小割问题。 最大流问题简介 最大流问题是指在一个有向图中,从源点到汇点的最大流量。最大流问题是…

    python 2023年5月14日
    00
  • Python函数any()和all()的用法及区别介绍

    Python函数any()和all()的用法及区别介绍 1. any()函数 1.1 概述 python内置的any()函数用于判断可迭代对象中的元素是否存在True值,如果存在则返回True,否则返回False。 1.2 语法 any(iterable) 1.3 参数解释 iterable : 可迭代对象(列表、元组、字典、集合、字符串等); 1.4 返回…

    python 2023年5月14日
    00
  • Python中的内存共享多线程编程

    【问题标题】:Memory sharing multithreading programming in PythonPython中的内存共享多线程编程 【发布时间】:2023-04-03 03:39:01 【问题描述】: 是否可以在 python 中处理共享内存并行任务?我的任务应该在多个内核上并行(尽管线程模块不适合这里,据我所知,唯一可以做到这一点的工具…

    Python开发 2023年4月8日
    00
  • Python3.5基础之函数的定义与使用实例详解【参数、作用域、递归、重载等】

    Python3.5基础之函数的定义与使用实例详解【参数、作用域、递归、重载等】 函数的定义 定义方式 在Python中定义一个函数使用关键字def,后跟函数名称和括号,其中括号内可以定义函数的参数。函数代码块以冒号起始,并且缩进。如下面的示例: def function_name(parameters): """docstrin…

    python 2023年5月13日
    00
  • python导入库的具体方法

    通过导入内置、第三方或自定义的Python库,我们可以扩展 Python 的功能并让开发更高效。下面是 Python 导入库的具体方法攻略。 1. 导入内置库 Python 内置了许多常用库,例如os、time和re等。导入内置库只需要使用 import 关键字加上库名即可。 示例代码: import os # 使用os模块的方法 os.chdir(‘/pa…

    python 2023年6月2日
    00
  • Pythony运维入门之Socket网络编程详解

    Pythony运维入门之Socket网络编程详解 本文将介绍Python中的Socket网络编程,内容分为以下几个部分: Socket基础知识 Python中的Socket编程 示例说明 Socket基础知识 Socket是计算机网络中的一个术语,它指的是一个使用TCP/IP协议通信的网络端点。Socket通常用于两个不同主机之间的通信。在Socket中,一…

    python 2023年6月6日
    00
  • Python离线安装openpyxl模块的步骤

    Python是一门流行的编程语言,而openpyxl是Python中处理Excel文件的常用模块。有时候,我们需要进行Python离线安装openpyxl模块。下面是完整步骤: 步骤一:下载openpyxl模块 在某些情况下,由于网络原因,我们无法连接到Python包管理器pip,这时我们需要下载openpyxl的安装文件。在官网下载openpyxl的最新版…

    python 2023年6月3日
    00
  • 基于Python编写一个计算器程序,实现简单的加减乘除和取余二元运算

    基于Python编写一个计算器程序 1. 确定程序功能 在编写计算器程序之前需要确定程序的具体功能,本文假设只实现简单的加减乘除和取余二元运算。 2. 编写代码 以下是一个简单的计算器程序示例: def add(a, b): """加法运算""" return a + b def sub(a, b)…

    python 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部