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 PIL Image.getdata()

    Python PIL(Python Imaging Library)是一个开源的图像处理库,其中Image类提供了一系列的方法,其中一个十分实用的方法是getdata(),本文将详细讲解该方法的使用。 一、getdata()方法 getdata()方法是Image类中的一个方法,它的作用是返回该图像的像素值,像素值以扁平的一维元组的形式返回。返回的像素值可以…

    python-answer 2023年3月25日
    00
  • pip报错“ValueError: invalid literal for int() with base 10: ‘3.3’”怎么处理?

    原因 “ValueError: invalid literal for int() with base 10: ‘3.3’” 错误通常是以下原因引起的: 版本号格式错误:如果您的版本号格式不正确,则可能会出现此错误。在这种情况下,您需要检查版本号格式是否正确。 版本号包含非数字字符:如果您的版本号包含非数字字符,则可能会出现此错误。在这种情况下,您需要删除版…

    python 2023年5月4日
    00
  • Python基于Tkinter模块实现的弹球小游戏

    Python基于Tkinter模块实现的弹球小游戏攻略 前置知识 在学习实现弹球小游戏前,需要掌握以下知识: Python基础语法 Python面向对象编程 Tkinter模块的使用方法 Canvas画布操作的基本方法 实现步骤 2.1 创建主窗口和画布 在Tkinter中,创建一个窗口需要使用Tk()函数。在窗口中创建画布需要用到Canvas()函数。代码…

    python 2023年6月13日
    00
  • 详解Python中方法和函数的区别

    在Python中,方法和函数都是用来完成某一特定任务的代码块。虽然这两个术语经常被混淆使用,但它们之间还是有一些关键的区别。下面我们详细讲解一下方法和函数的区别: 方法和函数的基本定义 函数 函数是一段具有特定功能的代码块,可以被重复地调用,以完成相关任务。函数可以接受参数,也可以返回值。Python中的函数由def关键字定义。 方法 方法是对象的行为,即对…

    python-answer 2023年3月25日
    00
  • CentOS 7下安装Python3.6 及遇到的问题小结

    CentOS7下安装Python3.6及遇到的问题小结 在CentOS7系统中,安装Python3.6可能会遇到一些问题。本文将详细讲解如何在CentOS7下安装Python3.6总结遇到的问题及解决方法,包括依赖问题、编译问题和两个示例。 安装Python3.6 以下是在CentOS下安装Python3.6的步骤: 安装依赖:使用yum命令安装必的依赖。 …

    python 2023年5月13日
    00
  • python使用jpype导入多个Jar的异常问题及解决

    介绍 在使用 Python 调用 Java 的过程中,如果需要导入多个 Jar 包,可能会遇到一些异常问题。本篇文章将详细讲解如何解决这个问题。 问题探究 先来看看一个简单的例子。假设我们有两个 Jar 包:a.jar 和 b.jar。以下代码尝试调用 b.jar 中的一个类: import jpype jar_path = ‘b.jar’ jpype.st…

    python 2023年5月13日
    00
  • Python爬虫实现(伪)球迷速成

    Python爬虫实现(伪)球迷速成 前言 随着互联网和数码科技的发展,越来越多的人开始使用网络了解和观看体育比赛。如果你想成为一名(伪)球迷,了解更多的比赛信息和球队积分情况是必要的。本文将介绍如何使用Python爬虫技术来获取体育赛事数据,帮助你更好地了解各个联赛和球队的情况。 准备工作 首先,我们需要准备Python环境和相关的爬虫库。Python 3.…

    python 2023年6月3日
    00
  • Python中的基本数据类型介绍

    Python中的基本数据类型包括数字、字符串、列表、元组、集合和字典。下面将逐一介绍这些数据类型。 数字 Python中的数字包括整数、浮点数和复数。其中,整数可以表示为十进制、二进制、八进制和十六进制等形式。以下是一个示例: a = 10 b = 0b1010 c = 0o12 d = 0xa print(a, b, c, d) # 输出:10 10 10…

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