【导语】:GeoPy 是一款提供了不同地理编码服务实现的 Python 库,可让开发者使用第三方地理编码服务和其他数据源,轻松地在全球范围内定位坐标。

简介

在日常开发工作中,对于地理信息编码功能,我们可以找到许多不同的第三方服务,比如 OpenStreetMap Nominatim,Google Geocoding API 等,但在对接不同的服务时,需要按照各自的开发文档做很多定制且冗余的工作。

想象一下,如果有一个开源且免费的库,可以同时集成多种地理信息编码服务,是不是非常的简洁?geopy 就是这么一款神器。

geopy 是一款免费开源的库,在单个包中为许多不同地理编码服务提供了实现,从而避免了直接对接不同地理编码服务的 API,简化了代码的逻辑。

如图,geopy 相当于一个代理,让我们方便地对接第三方地理编码 API。需要注意的是不同的服务有不同的使用条款、配额、定价、地理数据等等,所以在使用过程中具体地理编码服务无法完成某些查询,或在计算机与地理编码服务间出现的任何网络问题,和 geopy 都是无关的。

我个人实际试用的体验非常好,使用简便。

开源地址

https://github.com/geopy/geopy  

(在 GitHub 已有 3100 Star)

下载安装

使用pip安装即可

pip install geopy  

地理编码器

geopy.geocoders中,我们可以找到每个地理定位服务(如谷歌地图、必应地图)的类,用于抽象地理编码服务的 API。每个地理编码程序至少定义了一个 geocode 方法,用于从给定位置字符串中解析出经纬度坐标和位置细节,并且可以定义 reverse 方法,将一对给定经纬度坐标解析为一个地址。另外,在初始化每个地理编码程序时,需要传入与其服务交互所需的凭证或设置,例如 API 密钥或区域设置。

如果要解析给定位置的经纬度坐标及位置细节,可按如下步骤:

>>> from geopy.geocoders import Nominatim  
>>> geolocator = Nominatim(user_agent="test_geo")  
>>> location = geolocator.geocode("上海中心")  
>>> print(location.address)  
上海中心大厦, 501, 银城中路, 浦东新区, 200010, 中国  
>>> print((location.latitude, location.longitude))  
(31.23564615, 121.5012662299473)  
>>> print(location.raw)  
{'place_id': 130257928, 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', 'osm_type': 'way', 'osm_id': 165792123, 'boundingbox': ['31.235266', '31.2360377', '121.5007425', '121.5017465'], 'lat': '31.23564615', 'lon': '121.5012662299473', 'display_name': '上海中心大厦, 501, 银城中路, 浦东新区, 200010, 中国', 'class': 'tourism', 'type': 'attraction', 'importance': 0.5597014410814095, 'icon': 'https://nominatim.openstreetmap.org/ui/mapicons//poi_point_of_interest.p.20.png'}  

如果要解析给定经纬度坐标的具体位置,可按如下步骤:

>>> from geopy.geocoders import Nominatim  
>>> geolocator = Nominatim(user_agent="test_geo")  
>>> location = geolocator.reverse("31.23564615, 121.5012662299473")  
>>> print(location.address)  
上海中心大厦, 501, 银城中路, 浦东新区, 200010, 中国  
>>> print((location.latitude, location.longitude))  
(31.23564615, 121.5012662299473)  
>>> print(location.raw)  
{'place_id': 130257928, 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', 'osm_type': 'way', 'osm_id': 165792123, 'lat': '31.23564615', 'lon': '121.5012662299473', 'display_name': '上海中心大厦, 501, 银城中路, 浦东新区, 200010, 中国', 'address': {'tourism': '上海中心大厦', 'house_number': '501', 'road': '银城中路', 'city': '浦东新区', 'postcode': '200010', 'country': '中国', 'country_code': 'cn'}, 'boundingbox': ['31.235266', '31.2360377', '121.5007425', '121.5017465']}  

计算距离

在计算地理距离时,我们可以使用测地距离(geodesic distance)和大圆距离(great-circle distance),在 geopy 中geopy.distance.distance默认使用测地距离来计算距离。

如果要计算测地距离,可按如下步骤:

>>> from geopy import distance  
>>> wellington = (-41.32, 174.81)  
>>> shanghai = (31.23564615, 121.5012662299473)  
>>> print(distance.distance(wellington, shanghai).miles)  
6039.930578215586  
>>> print(distance.distance(wellington, shanghai).km)  
9720.326036467784  

如果要指定计算大圆距离,可按如下步骤:

>>> print(distance.great_circle(wellington, shanghai).miles)  
6054.82585437528  

geopy 还提供了异步模式、单位换算等模块,更多细节可以 查看官方文档

参考资料

开源前哨 日常分享热门、有趣和实用的开源项目。参与维护 10万+ Star 的开源技术资源库,包括:Python、Java、C/C++、Go、JS、CSS、Node.js、PHP、.NET 等。

开源前哨
133 声望12 粉丝