如何使用python、json和谷歌地图反向编写服务器端地理代码?

如何使用python、json和谷歌地图反向编写服务器端地理代码?,python,google-maps-api-3,reverse-geocoding,Python,Google Maps Api 3,Reverse Geocoding,我正在尝试服务器端反向地理编码,可以得到json响应,现在我想从json响应中得到2到3个变量: 例如,我想解析这个数据,并以eg结尾。 administration\u area\u level\u 1='Stockholm' jsondata=json.load(urllib2.urlopen('http://maps.googleapis.com/maps/api/geocode/json?latlng=59.3,18.1&sensor=false')) 这是我获取json的python代

我正在尝试服务器端反向地理编码,可以得到json响应,现在我想从json响应中得到2到3个变量:

例如,我想解析这个数据,并以eg结尾。
administration\u area\u level\u 1='Stockholm'

jsondata=json.load(urllib2.urlopen('http://maps.googleapis.com/maps/api/geocode/json?latlng=59.3,18.1&sensor=false'))

这是我获取json的python代码,现在我想知道如何解析它以获得

  • 行政区级别长名称(即州或地区名称)
  • 地点长名称(即城市名称)
  • 理解如何解析我的json
我可以解析它,但它并不总是显示为管理区域1:

jsondata[“结果”][0][“地址组件”][5][“长名称”]

上面的行正确地为纽约的一个点输出“纽约”,但对于斯德哥尔摩,它输出的是一个邮政城市,即Johanneshow,它不是行政区1(地区/州)。那么,如何保证函数总是返回管理区1,最好是不循环

我希望它能像以下那样工作,直接访问国家、地区和城市:

logging.info("country:"+str(jsondata["results"][9]["formatted_address"]))
logging.info("administrative_area_level_1:"+str(jsondata["results"][8]["formatted_address"]))
logging.info("locality:"+str(jsondata["results"][8]["formatted_address"]))
提前谢谢

更新

这是一个很好的答案,有我预期的结果。在等待答案的同时,我还尝试自己实施一个解决方案,似乎做到了:

jsondata = json.load(urllib2.urlopen('http://maps.googleapis.com/maps/api/geocode/json?latlng='+str(ad.geopt.lat)+','+str(ad.geopt.lon)+'&sensor=false'))
logging.info("geography:"+str(jsondata["results"][1]["formatted_address"]))
region = None
city = None
for result in jsondata["results"]:
  #logging.info("result:"+str(result))
  for component in result["address_components"]:
    logging.info("components:"+str(component))
    logging.info("components type:"+str(component["types"]))
    if 'administrative_area_level_1' in component["types"]:
      #logging.info(unicode('found admin area:%s' % component["long_name"]))
      region = component["long_name"]
    if 'locality' in component["types"]:
      logging.info("found locality:"+str(component["long_name"]))
      city = component["long_name"]

处理响应 无需解析JSON——它已经被
JSON.load()
解析并作为Python的数据结构返回像使用简单词典一样使用它,其中包含列表或不同的词典

访问响应的所需部分 要访问您应该使用的数据,您可以使用以下命令:

jsondata['results'][0]['address_components']
其中包括所有有关地名的信息:

[{u'long\u name':u'xf6dra L\xe4nken',u'types':[u'route'],u'short\u name':u'xf6dra L\xe4nken',{u'long\u name':u'Stockholm',u'types':[u'locality',u'political',u'short\u name':u'Stockholm',u'long\u'name':u'Stockholm',u'types':[u'administratification areal'level u'1',u'political',u'short\u'u'name':斯德哥尔摩',{u'long_name':u'Sweden',u'types':[u'country',u'political'],u'short_name':u'SE'},{u'long_name':u'12146',u'short_name':u'long_name':u'Johanneshov',u'types':[u'postall_town'],u'short_name':u'Johanneshov']

筛选您需要的数据 正如您所看到的,有很多数据是您不需要的,但您只需要
locality
administration\u area\u level\u 1
信息。您可以使用
filter()
Python函数过滤数据,如下所示:

>>> mydata = jsondata['results'][0]['address_components']
>>> types = ['locality', 'administrative_area_level_1']
>>> geonames = filter(lambda x: len(set(x['types']).intersection(types)), mydata)
基本上,您只能在其“类型”列表中获得具有“Location”或“Administration_area_level_1”的元素。在上述内容之后,
geonames
将是包含您需要的词典的列表:

[{u'long_name':u'Stockholm',u'types':[u'locality',u'political',u'short_name':u'Stockholm',u'long_name':u'Stockholm',u'types':[u'administration_area_level_1',u'political',u'short__name':u'Stockholm}]

显示数据 要显示它们的名称,例如,可以遍历它们,显示
long\u name
s和相应的
类型
值:

>>> for geoname in geonames:
    common_types = set(geoname['types']).intersection(set(types))
    print '{} ({})'.format(geoname['long_name'], str(', '.join(common_types)))


Stockholm (locality)
Stockholm (administrative_area_level_1)
这是你期望的吗

全部代码 代码可能如下所示:

import json
import urllib2

def get_geonames(lat, lng, types):
    url = 'http://maps.googleapis.com/maps/api/geocode/json' + \
            '?latlng={},{}&sensor=false'.format(lat, lng)
    jsondata = json.load(urllib2.urlopen(url))
    address_comps = jsondata['results'][0]['address_components']
    filter_method = lambda x: len(set(x['types']).intersection(types))
    return filter(filter_method, address_comps)

lat, lng = 59.3, 18.1
types = ['locality', 'administrative_area_level_1']

# Display all geographical names along with their types
for geoname in get_geonames(lat, lng, types):
    common_types = set(geoname['types']).intersection(set(types))
    print '{} ({})'.format(geoname['long_name'], ', '.join(common_types))

非常感谢!在此期间,我还开发了一个解决方案,用于过滤区域和管理区域级别1,以便我们可以比较这两个解决方案。我正在用我的“解决方案”更新问题我还将尝试这个答案中的一个。我基本上做的是通过循环结果和循环类型来找到匹配项,然后将这些匹配项分配给变量region和city。谢谢你!@Nickle:你的解决方案也应该有效!:)问题是我专注于代码的可读性、长度和可重用性-它使用
filter()
而不是大循环,
lambda
而不是条件检查,格式化而不是串联。最后一个(字符串格式化)可以大大提高代码的可读性。但正如我所说,它应该可以工作:)