如何在Python中获取地理位置?详细实现教程

2021年11月16日18:07:59 发表评论 1,889 次浏览

Python如何获取地理位置?本文带你了解如何使用 GeoPy 库将物理地址地理编码为纬度和经度,反之亦然;使用 Python 从地址、城镇、城市等获取纬度和经度。

地理编码是将位置描述(例如物理地址或地点名称)转换为地球表面上该地点的一对纬度和经度的过程。

它还指将地理坐标转换为位置的描述(例如地址),这通常称为反向地理编码。在本教程中,我们将学习如何借助 Python 中的 GeoPy 库来完成这两项工作。

Python获取地理位置示例 - GeoPy是一个 Python 客户端,提供了几种流行的地理编码 Web 服务,它使 Python 开发人员可以轻松定位地址、城市或国家/地区的坐标,反之亦然。

如何在Python中获取地理位置?首先,让我们安装它:

pip3 install geopy

GeoPy 提供了许多地理编码服务包装器,例如OpenStreetMap NominatimGoogle Geocoding API V3、Bing Maps 等。在本教程中,我们将坚持使用 OpenStreetMap Nominatim。

以下是我们将要介绍的内容:

  • 从地址获取纬度和经度(地理编码)
  • 从纬度和经度获取地址(反向地理编码)

从地址获取纬度和经度(地理编码)

Python如何获取地理位置?在本节中,我们将使用 OpenStreetMap Nominatim API 从物理地址、城市或任何位置名称获取纬度和经度。

我们先导入库:

from geopy.geocoders import Nominatim
import time
from pprint import pprint

注意我们选择了 Nominatim geocoder,现在创建它的一个新实例:

# instantiate a new Nominatim client
app = Nominatim(user_agent="tutorial")

如何在Python中获取地理位置?现在让我们尝试从地址获取地理数据:

# get location raw data
location = app.geocode("Nairobi, Kenya").raw
# print raw data
pprint(location)

输出:

{'boundingbox': ['-1.444471', '-1.163332', '36.6509378', '37.1038871'],
 'class': 'place',
 'display_name': 'Nairobi, Kenya',
 'icon': 'https://nominatim.openstreetmap.org/images/mapicons/poi_place_city.p.20.png',
 'importance': 0.845026759433763,
 'lat': '-1.2832533',
 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '
            'https://osm.org/copyright',
 'lon': '36.8172449',
 'osm_id': 9185096,
 'osm_type': 'relation',
 'place_id': 273942566,
 'type': 'city'}

Python如何获取地理位置?我们在lat属性上有纬度(我们可以通过 访问location['lat'])和经度在lon属性上,我们还可以访问boundingbox属性上地址的边界框。

如你所见,Nominatim API 不需要完整地址(由街道、门牌号和城市组成),你还可以传递商业地址和你的兴趣点,它支持!

Python获取地理位置示例解析 - 但是,如果重复调用此函数(例如遍历地址列表),则会遇到超时错误,这是因为如果你阅读Nominatim Usage Policy,它要求你每秒最多使用 1 个请求,这是完全可以接受的,因为它是一项免费服务。因此,以下函数尊重该要求并在发出请求之前休眠一秒钟:

def get_location_by_address(address):
    """This function returns a location as raw from an address
    will repeat until success"""
    time.sleep(1)
    try:
        return app.geocode(address).raw
    except:
        return get_location_by_address(address)

因此,每当出现超时错误时,我们都会捕获该错误并递归调用该函数,该函数将再休眠一秒钟,并希望检索结果:

address = "Makai Road, Masaki, Dar es Salaam, Tanzania"
location = get_location_by_address(address)
latitude = location["lat"]
longitude = location["lon"]
print(f"{latitude}, {longitude}")
# print all returned data
pprint(location)

输出:

-6.7460493, 39.2750804
{'boundingbox': ['-6.7467061', '-6.7454602', '39.2741806', '39.2760514'],
 'class': 'highway',
 'display_name': 'Makai Road, Masaki, Msasani, Dar es-Salaam, Dar es Salaam, '
                 'Coastal Zone, 2585, Tanzania',
 'importance': 0.82,
 'lat': '-6.7460493',
 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '
            'https://osm.org/copyright',
 'lon': '39.2750804',
 'osm_id': 23347726,
 'osm_type': 'way',
 'place_id': 89652779,
 'type': 'residential'}

从纬度和经度获取地址(反向地理编码)

如何在Python中获取地理位置?现在要检索地址,城市和国家以及各种其他信息,仅从纬度和经度,我们只需使用reverse()method 而不是geocode(),它接受坐标(latitudelongitude)作为以逗号分隔的字符串。

以下函数根据 Nominatim 使用政策对坐标进行反向地理编码:

def get_address_by_location(latitude, longitude, language="en"):
    """This function returns an address as raw from a location
    will repeat until success"""
    # build coordinates string to pass to reverse() function
    coordinates = f"{latitude}, {longitude}"
    # sleep for a second to respect Usage Policy
    time.sleep(1)
    try:
        return app.reverse(coordinates, language=language).raw
    except:
        return get_address_by_location(latitude, longitude)

Python获取地理位置示例介绍 - 所以这个函数需要纬度和经度作为参数并返回原始地理数据,这里是一个示例用法:

# define your coordinates
latitude = 36.723
longitude = 3.188
# get the address info
address = get_address_by_location(latitude, longitude)
# print all returned data
pprint(address)

输出:

{'address': {'country': 'Algeria',
             'country_code': 'dz',
             'county': 'Dar El Beida District',
             'postcode': '16110',
             'state': 'Algiers',
             'town': 'Bab Ezzouar'},
 'boundingbox': ['36.7231765', '36.7242661', '3.1866439', '3.1903998'],
 'display_name': 'Bab Ezzouar, Dar El Beida District, Algiers, 16110, Algeria',
 'lat': '36.72380363740118',
 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '
            'https://osm.org/copyright',
 'lon': '3.188236679492425',
 'osm_id': 42812185,
 'osm_type': 'way',
 'place_id': 98075368}

Python如何获取地理位置?所以这将返回所有地址数据,包括州、镇、邮政编码、地区等。如果你希望以特定语言返回这些信息,你可以将language参数设置为你想要的语言,或者你可以将其设置False为该特定位置的默认语言。

结论

与往常一样,我们只看到了 GeoPy 可以做什么的简单示例,如果你对更高级的实用程序感兴趣,我强烈建议你阅读文档

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: