从GeoPy地理编码器返回单个地址组件(城市,州等)

12

我正在使用GeoPy将地址解析为经度和纬度。我也想提取每个地址的项目化地址组件(街道、城市、州、邮编)。

GeoPy返回一个包含地址的字符串——但我找不到可靠的方法来分隔每个组件。例如:

123 Main Street, Los Angeles, CA 90034, USA =>
{street: '123 Main Street', city: 'Los Angeles', state: 'CA', zip: 90034, country: 'USA'}

谷歌地理编码API确实返回了这些个体组件...有没有一种方法可以从GeoPy(或其他地理编码工具)中获取它们?

4个回答

28

你还可以从Nominatim()地理编码器(这是来自geopy的标准开源地理编码器)获取单独的地址部分。

from geopy.geocoders import Nominatim

# address is a String e.g. 'Berlin, Germany'
# addressdetails=True does the magic and gives you also the details
location = geolocator.geocode(address, addressdetails=True)

print(location.raw)

提供

{'type': 'house',
 'class': 'place',
 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright',
 'display_name': '2, Stralauer Allee, Fhain, Friedrichshain-Kreuzberg, Berlin, 10245, Deutschland',
 'place_id': '35120946',
 'osm_id': '2825035484',
 'lon': '13.4489063',
 'osm_type': 'node',
 'address': {'country_code': 'de',
             'road': 'Stralauer Allee',
             'postcode': '10245',
             'house_number': '2',
             'state': 'Berlin',
             'country': 'Deutschland',
             'suburb': 'Fhain',
             'city_district': 'Friedrichshain-Kreuzberg'},
 'lat': '52.5018003',
 'importance': 0.421,
 'boundingbox': ['52.5017503', '52.5018503', '13.4488563', '13.4489563']}

location.raw['address']

您只需使用组件即可获得字典。

查看geopy文档以获取更多参数或Nominatim以获取所有地址组件。


3
代码中缺少这一行,让我感到困惑:geolocator = Nominatim(user_agent="specify_your_app_name_here") - Justin Furuness
根据Nomatim的文档,显然用户代理字符串并不重要,但你需要它才能在不违反他们的服务条款的情况下使用Nomatim。 - Justin Furuness

5

使用 usaddress (由 DataMade 开发)进行文本翻译。这是 GitHub 代码库

它的使用方式如下:usaddress.parse('123 Main St. Suite 100 Chicago, IL'),并返回以下数组:

[('123', 'AddressNumber'), ('Main', 'StreetName'), ('St.', 'StreetNamePostType'), ('Suite', 'OccupancyType'), ('100', 'OccupancyIdentifier'), ('Chicago,', 'PlaceName'), ('IL', 'StateName')]


2

这就是我实现这种拆分的方式,因为我想要的结果地址格式始终相同。您只需跳过连接并返回每个值...或将其放入列表中。由您决定。

 def getaddress(self, lat, lng, language="en"):
        try:
            geolocator = Nominatim()
            string = str(lat) + ', ' +str(lng)
            location = geolocator.reverse(string, language=language)
            data = location.raw
            data = data['address']
            address = str(data)

            street = district = postalCode= state = country = countryCode = ""

            district    =str(data['city_district'])
            postalCode  =str(data['postcode'])
            state       =str(data['state'])
            country     =str(data['country'])
            countryCode =str(data['country_code']).upper()
            address = street +' '+ district  +' '+  postalCode  +' '+  state  +' '+  country  +' '+  countryCode
        except:
            address="Error"
        return str(address.decode('utf8'))

1

我不久前帮忙编写了一个名为LiveAddress的工具,它刚刚升级以支持单行(自由格式)地址并实现地理编码功能。

GeoPy是一个地理编码实用程序,而不是地址解析器/标准化程序。然而,LiveAddress API可以验证地址的有效性,并为您填充缺失的信息。您会发现,像Google和Yahoo这样的服务只是近似地址,而像LiveAddress这样的CASS认证服务实际上会验证地址,并且只有在地址真实存在时才返回结果。

在使用LiveAddress进行大量研究和开发后,我在此Stack Overflow帖子中撰写了一篇总结。它记录了地址可能出现的疯狂但完整的格式,并最终提供了解决解析问题(针对美国地址)的方案。

要使用Python将单行地址解析为组件,请将整个地址放入“street”字段中:

import json
import pprint
import urllib

LOCATION = 'https://api.qualifiedaddress.com/street-address/'
QUERY_STRING = urllib.urlencode({ # entire query sting must be URL-Encoded
    'auth-token': r'YOUR_API_KEY_HERE',
    'street': '1 infinite loop cupertino ca 95014'
})
URL = LOCATION + '?' + QUERY_STRING

response = urllib.urlopen(URL).read()
structure = json.loads(response)
pprint.pprint(structure)

生成的JSON对象将包含一个components对象,它看起来会像这样:

"components": {
        "primary_number": "1",
        "street_name": "Infinite",
        "street_suffix": "Loop",
        "city_name": "Cupertino",
        "state_abbreviation": "CA",
        "zipcode": "95014",
        "plus4_code": "2083",
        "delivery_point": "01",
        "delivery_point_check_digit": "7"
}

响应还将包括组合的first_line和delivery_line_2,因此如果您需要它们,就不必手动连接它们。有关地址的纬度/经度和其他信息也可用。

谢谢Matt - 这非常有帮助。我在网站上尝试了LiveAddress,看起来不错,可能是我应用程序的解决方案。但是,我的最初问题仍然是如何从GeoPy中获取组件 - 有任何想法吗? - lubar
当然。按逗号分割很诱人,但这会产生不可靠/不一致的结果,因为GeoPy集成的地理编码服务以不同的格式返回其结果;而且地址本质上是有很大变化的。看起来GeoPy使用已弃用的Google Maps v2 API,该API在AddressDetails字段中返回组件。我想知道是否可以将google.py的第147行更改为从该字段读取,但您可能需要适应读取对象而不是单个字符串... - Matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接