前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >如何使用 Python 更加精确地计算两地距离

如何使用 Python 更加精确地计算两地距离

作者头像
用户11172986
发布2025-02-08 14:02:29
发布2025-02-08 14:02:29
9200
代码可运行
举报
文章被收录于专栏:气python风雨气python风雨
运行总次数:0
代码可运行

使用 Python 进行大圆计算:基于 Vincenty 公式的应用

项目概述

在地理信息处理中,计算两点之间的距离、方位角以及从一个点出发给定距离和方位角求解另一个点的位置等问题是非常常见的需求。Python 提供了多种方式来实现这些功能,其中 pygc 是一个特别强大的库,它使用 Vincenty 的公式来精确地进行大圆相关的计算。

环境设置

安装依赖

无论你是使用 pip 还是 conda 来管理你的 Python 环境,安装 pygc 都非常简单:

pip 安装命令:

代码语言:javascript
代码运行次数:0
复制
pip install pygc  

conda 安装命令:

代码语言:javascript
代码运行次数:0
复制
conda install -c conda-forge pygc  

如果你想要获取最新的开发版本,可以通过以下命令直接从 GitHub 上安装:

代码语言:javascript
代码运行次数:0
复制
pip install git+https://github.com/axiom-data-science/pygc.git  
代码语言:javascript
代码运行次数:0
复制
!pip install pygc -i https://pypi.mirrors.ustc.edu.cn/simple/
代码语言:javascript
代码运行次数:0
复制
Looking in indexes: https://pypi.mirrors.ustc.edu.cn/simple/
Collecting pygc
  Downloading https://mirrors.ustc.edu.cn/pypi/packages/49/7c/af09d2f53967326c0d605c55a22f2f432b5034ca0c943287375695e743f7/pygc-2.0.0-py3-none-any.whl (19 kB)
Requirement already satisfied: pyproj in /opt/conda/lib/python3.9/site-packages (from pygc) (3.4.1)
Requirement already satisfied: numpy in /opt/conda/lib/python3.9/site-packages (from pygc) (1.26.4)
Requirement already satisfied: certifi in /opt/conda/lib/python3.9/site-packages (from pyproj->pygc) (2024.2.2)
Installing collected packages: pygc
Successfully installed pygc-2.0.0

大圆计算实例

根据初始点、距离和方位角创建新点

我们可以利用 great_circle 函数来根据给定的起始点(纬度和经度)、距离(单位:米)和方位角(角度)来计算到达的新点的位置。例如:

代码语言:javascript
代码运行次数:0
复制
from pygc import great_circle
result = great_circle(distance=111000, azimuth=65, latitude=30, longitude=-74)
result

这个例子将会返回一个新的点,其纬度为约 30.419,经度约为 -72.953,反方位角约为 245.527°。

创建圆形分布的多个点

代码语言:javascript
代码运行次数:0
复制
from pygc import great_circle
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

# 设置参数
distance_km = 111# 假设距离为111公里(大约等于一度纬度)
start_latitude = 30
start_longitude = -74
azimuths = np.arange(0, 360, 10)  # 每隔10度计算一个点

# 计算新点位置
results = [great_circle(distance=distance_km*1000, azimuth=az, latitude=start_latitude, longitude=start_longitude) for az in azimuths]

# 提取经纬度
lats = [res['latitude'][0] for res in results]
lons = [res['longitude'][0] for res in results]

# 可视化
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())

# 设置地图范围
ax.set_extent([start_longitude-5, start_longitude+5, start_latitude-5, start_latitude+5], crs=ccrs.PlateCarree())

# 添加地理特征
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')
ax.add_feature(cfeature.LAND, color='lightgray')
ax.add_feature(cfeature.OCEAN, color='lightblue')

# 绘制起点和新点
ax.plot(start_longitude, start_latitude, 'bo', markersize=12, transform=ccrs.Geodetic())  # 起点

for lon, lat in zip(lons, lats):
    ax.plot(lon, lat, 'r.', transform=ccrs.Geodetic())  # 新点

# 连接线
for lon, lat in zip(lons, lats):
    ax.plot([start_longitude, lon], [start_latitude, lat], linewidth=1, color='b', transform=ccrs.Geodetic())

plt.title('Visualization of Points at Different Azimuths using Cartopy')
plt.show()

创建雪花形分布的多个点

为了生成以某个中心点为中心向不同方向延伸的多个点,你可以这样操作:

简单示例

代码语言:javascript
代码运行次数:0
复制
result = great_circle(distance=100000, azimuth=[0, 60, 120, 180, 240, 300], latitude=30, longitude=-74)


代码语言:javascript
代码运行次数:0
复制
#可视化
代码语言:javascript
代码运行次数:0
复制
from pygc import great_circle
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

# 设置参数
distance_km = 100# 距离为100公里
start_latitude = 30
start_longitude = -74
azimuths = [0, 60, 120, 180, 240, 300]  # 方位角列表

# 计算新点位置
result = great_circle(distance=distance_km*1000, azimuth=azimuths, latitude=start_latitude, longitude=start_longitude)

# 提取经纬度
lats = result['latitude']
lons = result['longitude']

# 可视化
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())

# 设置地图范围,确保所有点都在图内
ax.set_extent([min(lons)-5, max(lons)+5, min(lats)-5, max(lats)+5], crs=ccrs.PlateCarree())

# 添加地理特征
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')
ax.add_feature(cfeature.LAND, color='lightgray')
ax.add_feature(cfeature.OCEAN, color='lightblue')

# 绘制起点和新点
ax.plot(start_longitude, start_latitude, 'bo', markersize=12, transform=ccrs.Geodetic(), label='Start Point')  # 起点

for lon, lat in zip(lons, lats):
    ax.plot(lon, lat, 'r.', transform=ccrs.Geodetic())  # 新点

# 连接线
for lon, lat in zip(lons, lats):
    ax.plot([start_longitude, lon], [start_latitude, lat], linewidth=1, color='b', transform=ccrs.Geodetic())

plt.legend()
plt.title('Visualization of Points at Different Azimuths using Cartopy')
plt.show()

这将围绕指定的中心点创建六个等距的点,每个点与前一个点之间的方位差为 60°。

计算两点间的大圆距离

great_distance 函数可以用来计算两个点之间的距离(单位:米)和方位角。例如:

代码语言:javascript
代码运行次数:0
复制
from pygc import great_distance
result = great_distance(start_latitude=30, start_longitude=-74, end_latitude=40, end_longitude=-74)
result

此例中的结果表示两地之间的大圆距离大约为 1109415.6 米,且由于它们位于同一经度线上,所以方位角为 0°。

数组计算测试

代码语言:javascript
代码运行次数:0
复制
from pygc import great_distance

# 定义多组起点和终点坐标
start_latitudes = [30, 35]  # 起始点纬度数组
start_longitudes = [-74, -79]  # 起始点经度数组
end_latitudes = [40, 45]  # 结束点纬度数组
end_longitudes = [-74, -79]  # 结束点经度数组

# 使用 great_distance 计算距离和方位角
result = great_distance(start_latitude=start_latitudes, start_longitude=start_longitudes,
                        end_latitude=end_latitudes, end_longitude=end_longitudes)

print(result)
代码语言:javascript
代码运行次数:0
复制
{'distance': array([1109415.63240213, 1110351.47627678]), 'azimuth': array([0., 0.]), 'reverse_azimuth': array([180., 180.])}

计算台风移动速度

假设我们有一个台风的轨迹数据,包含一系列时间戳以及相应的经纬度位置。我们可以使用 pygc 库来计算两个连续观测点之间的距离,并结合时间差来估算台风的移动速度。

代码语言:javascript
代码运行次数:0
复制
from pygc import great_distance

# 示例台风轨迹数据
times = ['2025-02-06T00:00:00Z', '2025-02-06T01:00:00Z']  # 时间戳
latitudes = [18.5, 19.0]  # 纬度
longitudes = [120.5, 121.0]  # 经度

# 计算距离和方位角
result = great_distance(start_latitude=latitudes[0], start_longitude=longitudes[0],
                        end_latitude=latitudes[1], end_longitude=longitudes[1])

distance = result['distance'][0]  # 单位:米
time_diff_seconds = (1 * 60 * 60)  # 假设时间差为1小时,转换为秒

# 计算速度
speed_m_per_s = distance / time_diff_seconds
print(f"台风的平均移动速度约为 {speed_m_per_s:.2f} 米/秒")
代码语言:javascript
代码运行次数:0
复制
台风的平均移动速度约为 21.23 米/秒

计算雷达的方位角与目标的距离

在雷达系统中,如果已知雷达站的位置和探测到的目标位置,可以使用 pygc 来计算两者之间的距离和方位角

代码语言:javascript
代码运行次数:0
复制
# 雷达站位置
radar_lat, radar_lon = 40.7128, -74.0060  # 纽约市为例

# 目标位置
target_lat, target_lon = 40.730610, -73.935242  # 自由女神像为例

result = great_distance(start_latitude=radar_lat, start_longitude=radar_lon,
                        end_latitude=target_lat, end_longitude=target_lon)

distance_to_target = result['distance'][0]  # 目标距离,单位:米
azimuth_to_target = result['azimuth'][0]    # 方位角

print(f"从雷达站到目标的距离是 {distance_to_target:.2f} 米,方位角是 {azimuth_to_target:.2f} 度。")
代码语言:javascript
代码运行次数:0
复制
从雷达站到目标的距离是 6296.87 米,方位角是 71.67 度。
结论

pygc 库以其高效性和准确性,在执行基于 Vincenty 公式的大圆计算方面表现出色,无论是简单的距离测量还是复杂的方位分析任务都能胜任。本文旨在帮助读者快速上手,并将所学应用于实际项目中。对于深入学习和探索更多高级应用,推荐参考相关技术手册或文档。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-02-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 气python风雨 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用 Python 进行大圆计算:基于 Vincenty 公式的应用
    • 项目概述
    • 环境设置
      • 安装依赖
    • 大圆计算实例
      • 根据初始点、距离和方位角创建新点
      • 创建圆形分布的多个点
      • 创建雪花形分布的多个点
      • 计算两点间的大圆距离
      • 数组计算测试
      • 计算台风移动速度
      • 计算雷达的方位角与目标的距离
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档