Python中经纬度距离计算的实现方式

2025-08-11 22:50

本文主要是介绍Python中经纬度距离计算的实现方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Python中经纬度距离计算的实现方式》文章介绍Python中计算经纬度距离的方法及中国加密坐标系转换工具,主要方法包括geopy(Vincenty/Karney)、Haversine、pyproj...

python中计算经纬度距离可以使用geopy(Vincenty、Karney)、Haversine、pyproj(椭球模型投影计算)、平面近似法(小范围快速估算)等。而针对中国加密坐标系(如GCJ-02/BD-09)也可以使用coord-convert工具转换为WGS84。

以下是对应方法的示例。

一、基本方法

1. 使用geopy库(推荐)

geopy 提供了多种距离计算方式(包括Haversine、Vincenty、Karney),支持WGS84椭球模型。

安装

pip install geopy

示例代码

from geopy.distance import geodesic, great_circle

# 定义两点(纬度, 经度)
point_a = (39.9042, 116.4074)  # 北京
point_b = (31.2304, 121.4737)  # 上海

# 方法1:
# geopy 1.x 版本 Vincenty(默认,高精度)
# geopy 2.0 版本 Karney
distance_karney = geodesic(point_a, point_b).km
print(f"karney距离: {distance_karney:.2f} km")

# 方法2:大圆距离(Haversine,球面近似)
distance_greatjavascript_circle = great_circle(point_a, point_b).km
print(f"大圆距离: {distance_great_circle:.2f} km")

输出:

Karney距离: 1065.85 km
大圆距离: 1067.31 km

说明:
geodesic 2.0版本 使用的是Karney算法,1.x 版本使用的是Vincenty算法。
great_circle 使用Haversine公式,假设地球为完美球体。实际地球是椭球体,其误差范围(通常为 0.5% 左右)。

2. 手动实现 Haversine 公式

适合无需外部库的场景。

示例代码

import math


def haversine(lat1, lon1, lat2, lon2):
    R = 6371  # 地球半径(km)
    phi1, phi2 = math.radians(lat1), math.radians(lat2)
    delta_phi = math.radians(lat2 - lat1)
    delta_lambda = math.radians(lon2 - lon1)

    a = math.sin(delta_phi / 2) ** 2 + \
        math.cos(phi1) * math.cos(phi2) * math.sin(delta_lambda / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    return R * c

distance = haversine(39.9042, 116.4074, 31.2304, 121.4737)
print(f"Haversine距离: {distance:.2f} km")

输出:

Haversine距离: 1067.31 km

注意:与geopygreat_circle结果一致。

3. 使用pyproj进行投影坐标系计算

适合需要平面坐标的高精度场景(如UTM投影)。

安装

pip install pyproj

示例代码

from pyproj import Geod

# 使用WGS84椭球
geod = Geod(ellps="WGS84")

# 计算距离和方位角
# 参数顺序:起点经度、起点纬度、终点经度、终点纬度
_, _, distance = geod.inv(116.4074, 39.9042, 121.4737, 31.2304)
print(f"pyproj椭球距离: {distance / 1000:.2f} km")

输出:

pyproj椭球距离: 1065.85 km

说明:

  • geod.inv 返回前两个值是方位角,第三个是距离(米)。
  • 结果与geopy的Vincenty一致。

4. 平面近似法(小范围适用)

适用于城市内短距离快速估算。

import math

def flat_approximatiowww.chinasem.cnn(lat1, lon1, lat2, lon2):
    R = 6371  # 地球半径(km)
    avg_lat = math.radians((lat1 + lat2) / 2)
    dx = math.radians(lon2 - lon1) * math.cos(avg_lat)
    dy = math.radians(lat2 - lat1)
    return R * math.sqrt(dx**2 + dy**2)

# 示例(北京天安门到北京西站)
distance = flat_approximation(39.9042, 116.4074, 39.8946, 116.3224)
print(f"平面近似距离: {distance:.2f} km")

输出:

平面近似距离: 7.33 km

注意:适用于距离 < 10 km,实际误差还取决于纬度,高纬度地区误差更大。

二、不同坐标系的影响

常见坐标系

许多国家会对地理信息进行加密或偏移,如中国的GCJ-02或BD-09,计算距离前需确保所有坐标点在同一坐标系下,否则结果会有偏差。

可以使用库(如coord-converphpt)将GCJ-02或BD-09坐标转换为WGS84,但不同坐标系之间的转换是不可逆的,多次转换可能会导致精度损失。

  • WGS84(国际标准GPS坐标系):未加密的地心坐标系,高精度。
  • GCJ-02(火星坐标系):基于WGS84通过非线性算法加入随机偏移。
  • BD-09(百度坐标系):在GCJ-02基础上二次加密的坐标系。

coord-convert坐标系转换

安装

pip install coord-convert

示例代码

from coord_convert import transform

# GCJ-02 转 WGS84
gcj_lon, gcj_lat = 116.404, 39.915  # 北京天安门(GCJ-02)
wgs_lon, wgs_lat = transform.gcj2wgs(gcj_lon, gcj_lat)
print(f"WGS84坐标: {wgs_lon:.6f}, {wgs_lat:.6f}")
# WGS84坐标: 116.397756, 39.913596

# BD-09 转 WGS84
bd_lon, bd_lat = 116.410, 39.921  # 北京天安门(BD-09)
wgs_lon, wgs_lat = trwww.chinasem.cnansform.bd2wgs(bd_lon, bd_lat)
print(f"WGS84坐标: {wgs_lon:.6f}, {wgs_lat:.6f}")
# WGS84坐标: 116.397387, 39.913258

坐标系转换方法

函数说明
transform.wgs2gcj(lon, lat)WGS84 → GCJ-02
transform.gcj2wgs(lon, lat)GCJ-02 → WGS84
transform.gcj2bd(lon, lat)GCJ-02 → BD-09
transform.bd2gcj(lon, lat)BD-09 → GCJ-02
transform.bd2wgs(lon, lat)BD-09 &rarrjavascript; WGS84
transform.wgs2bd(lon, lat)WGS84 → BD-09

三、方法对比总结

方法精度适用场景依赖库
geopy.geodesic毫米级全球范围,高精度geopy
geopy.great_circle中等快速球面估算geopy
Haversine手动实现中等无库依赖
pyproj.Geod毫米级复杂椭球模型计算pyproj
平面近似极小范围(城市内)

四、如何选择?

  • 通用场景:直接使用 geopy.geodesic(平衡精度和易用性)。
  • 学术与工程:需要椭球模型时用 pyproj
  • 轻量级需求:手动Haversine或无库平面近似。

五、总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持China编程(www.chinasem.cn)。

这篇关于Python中经纬度距离计算的实现方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155685

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法