社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python实现经纬度换算+计算两地距离+地理可视化(代码全分享)

Python绿色通道 • 4 年前 • 618 次点击  

↑ 关注 + 星标 ,每天学Python新技能

后台回复【 大礼包】送你Python自学大礼包


前几天我发了一篇文章《啊?北京确诊病例曾距离我650米!》,文中提到了如何使用Python获取坐标点的经纬度,计算坐标点间的距离,以及地理可视化等。其实里面的内容主要摘自本文,所以今天干脆把原文发出来👇


故事的起因:小五的驾驶证在今年有效期满了,需要提交体检信息才可以进行换证。那么哪些医院是支持驾驶员体检的呢?

打开北京市公安局公安交通管理局,可以查到对应的体检医院。网址:http://jtgl.beijing.gov.cn/jgj/qtym/1734494/index.html

▲点击查看大图

在上方的网页中,交管局提供了223个医院地址和相关的联系方式、工作时间等信息,非常详细。

但是,但是,在这么多信息中,我无法得知到底哪个医院是离我家最近的。。。

于是乎,我希望能用Python帮我解决这个问题,并且以后遇到类似问题时,也能一键得出结论。

查询经纬度

首先从官方公布的网页信息中,我将可以体检的医院相关数据复制到“北京驾驶人体检医院信息.csv”中,具体详情如下图所示。

想要查询距离,就要先获取各个坐标点的经纬度。

我们可以使用Python编程,调用百度地图API得到各个地点的经纬度信息。

注册百度地图开放平台

打开百度地图开放平台的网址后(https://lbs.baidu.com/),点击控制台,然后激活个人开发者账号才能申请自己的免费密钥,这样才能完全使用该API。注册成功之后,就可以在开放平台上点击“创建应用”,填写相关信息后即可获得自己创建应用对应的密钥,如下图红圈标注所示。

注意,“创建应用”时IP白名单中,输入0.0.0.0/0即可。

我们依此就可以编写一段Python代码,来调用百度地图API得到某点的经纬度信息。注意要将代码中url出的key值替换成自己刚刚得到的密钥,这样才能使得程序正常运行。

import requests

def get_ll(x):
    url = f"http://api.map.baidu.com/geocoding/v3/?address={x}&output=json&ak=自己的key值&callback=showLocation"
    Post_data = {'address': x}
    se = requests.session()
    Text = se.post(url, data=Post_data).text.replace("'"'"').replace('/ ''/')[27:-1]
    jsonValue = json.loads(Text)
    if('result' in jsonValue):
        return [jsonValue['result']['location']['lng'], jsonValue['result']['location']['lat']]
    else:
        return ' '

接下来,在北京地图上随便选一个地点,分别用【Python调用百度地图API】和【手动】的办法,验证一下我们的Python程序是否有效。

事实证明,坐标经纬度基本一致,我们的程序没有问题。

计算距离

如何通过经纬度信息,计算两地距离呢?

我们都知道,地球的赤道半径是 6378 公里,极半径是 6356 公里,平均半径为6371公里,所以它并不是一个完美的球体。

但我们并不是要做科研追求极致,只要地球简化为一个球体,那么就可以使用数学公式计算两地的近似距离。

通过搜索学习,我查到了非常清晰且简练的方法——半正矢公式(Haversine公式)。相关计算成果可以见对应的维基百科:https://en.wikipedia.org/wiki/Haversine_formula

感兴趣的小伙伴可以自己去学习了解,这里我们只需要将公式转换为Python程序。下方的Python代码中我们分别预设了两个坐标值,它们是【五道口地铁站】和【北京市第二医院】的经纬度坐标。

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

address_me = [116.344434,39.998568]

def get_address_distance(ddd):
    lon1, lat1, lon2, lat2 = map(radians, [address_me[0],address_me[1],ddd[0],ddd[1]])
    # 半正矢公式
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a))
    r = 6371
    dis = round((c * r * 1000)/10002)
    return dis

instance = get_address_distance([116.3826792554698539.90878484073634])
print(f"两点距离为:{str(instance)}公里")

同样,我们也可以使用Python自定义函数去计算两个坐标点之间的距离。那么,这里同样在北京地图上随便选两个地点,分别用【Python自定义函数】和【手动】的办法,验证一下。

事实证明,两点之间直线距离基本一致,我们的程序没有问题。

需要注意一点,这里我们是根据两地的经纬度进行计算的直线距离,跟我们平时使用地图查询的规划路线距离肯定不同。

接着,就可以应用该自定义函数去计算每一个途经点距离我的距离了!

df['距离(公里)'] = df['经纬度'].apply(get_address_distance)

最后,倒序即可看到距离我最近的医院及其相关信息。

距离我最近的驾驶员体检医院:朝阳区南磨房社区卫生服务中心、朝阳区平房社区卫生服务中心、朝阳区八里庄社区卫生服务中心。

其中,朝阳区南磨房社区卫生服务中心距离直线距离不到3公里,就去这里了!

地理可视化

本来事情就可以告一段落了,但是正好已经获取了经纬度坐标点,干脆就一鼓作气直接把这些医院的位置可视化了吧!

同时为了简单方便,直接使用使用Pyecharts进行地理可视化(下方为部分代码,完整代码下载见文末)。

from pyecharts import options as opts
from pyecharts.charts import Geo
from pyecharts.globals import ThemeType

data_pair = [(df.iloc[i]['医院名称'], df.iloc[i]['距离(公里)'])
             for i in range(len(df))]

geo = Geo(init_opts=opts.InitOpts(theme=ThemeType.DARK))
geo.add_schema(maptype='北京')

打开生成的北京驾驶员体检医院分布图.html文件,具体效果如下图所示:

简单解释一下上图,我按照距离远近将223家医院分为了4类,并标记了颜色,其中红色是距离我 5公里以内。

Pyecharts生成的可视化文件支持交互,鼠标移至每个途经点时,都会出现该医院的名称和距离我多远!

PS:代码中我使用的是Geo,觉得百度地图作为底图更好看的小伙伴,可以尝试使用BAMP。




    
推荐阅读

  1. 吴恩达,新冠阳性

  2. 谁再说不熟悉 Linux 命令,就把这个给他扔过去!

  3. 冒死曝光这个软件,希望不要被封杀!

  4. 用 Python 自动化下载抖X无水印短视频


您看此文用   分  秒,转发只需1秒哦~

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/126982