我正在使用GeoPy将地址编码为lat,lng。我还想提取每个地址的逐项地址组件(街道,城市,州,邮编)。
GeoPy返回一个包含地址的字符串 - 但我找不到一种可靠的方法来分隔每个组件。例如:
123 Main Street, Los Angeles, CA 90034, USA =>
{street: '123 Main Street', city: 'Los Angeles', state: 'CA', zip: 90034, country: 'USA'}
Google地理编码API会返回这些单独的组件......有没有办法从GeoPy获取这些内容? (或不同的地理编码工具?)
答案 0 :(得分:7)
以防万一有人仍有同样的问题。您还可以从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 documentation以获取更多参数,或Nominatim查看所有地址组件。
希望我能帮助那些仍然遇到麻烦的人。也许赞成其他人可以更容易地找到这个,因为我认为这是这个问题的正确答案。
答案 1 :(得分:2)
我不久前帮助写了一个叫LiveAddress的人;它刚刚升级为支持单行(自由格式)地址并实现地理编码功能。
GeoPy是一种地理编码实用程序,而不是地址解析器/标准化程序。但是,LiveAddress API 是,并且还可以验证地址的有效性,填写缺少的信息。您会发现Google和Yahoo 等服务近似地址,而像LiveAddress这样的CASS认证服务实际上会对其进行验证,除非地址是真实的,否则不会返回结果。
在通过实施LiveAddress进行大量研究和开发之后,我写了一个summary in this Stack Overflow post。它记录了一些疯狂但完整的格式,地址可以进入并最终导致解析问题的解决方案(对于美国地址)。
要使用Python将单行地址解析为组件,只需将整个地址放入“街道”字段:
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,因此您不必在需要时手动连接它们。有关地址的纬度/经度和其他信息。
答案 2 :(得分:1)
使用DataMade的usaddress
。这是GitHub repo。
它的工作方式与usaddress.parse('123 Main St. Suite 100 Chicago, IL')
类似,并返回此数组
[('123', 'AddressNumber'),
('Main', 'StreetName'),
('St.', 'StreetNamePostType'),
('Suite', 'OccupancyType'),
('100', 'OccupancyIdentifier'),
('Chicago,', 'PlaceName'),
('IL', 'StateName')]
答案 3 :(得分:1)
这是我实现这种分割的方式,因为我希望结果地址始终采用相同的格式。您只需跳过串联并重新运行每个值...或将其放入列表中。由你决定。
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'))