【问题标题】:How To Get Latitude & Longitude with python如何使用python获取纬度和经度
【发布时间】:2014-09-17 10:39:14
【问题描述】:

我正在尝试通过以下脚本检索物理地址的经度和纬度。但我收到错误消息。我已经安装了 googlemaps 。 请回复 提前致谢

#!/usr/bin/env python
import urllib,urllib2


"""This Programs Fetch The Address"""

from googlemaps import GoogleMaps


address='Mahatma Gandhi Rd, Shivaji Nagar, Bangalore, KA 560001'

add=GoogleMaps().address_to_latlng(address)
print add

输出:

Traceback (most recent call last):
  File "Fetching.py", line 12, in <module>
    add=GoogleMaps().address_to_latlng(address)
  File "/usr/local/lib/python2.7/dist-packages/googlemaps.py", line 310, in address_to_latlng
    return tuple(self.geocode(address)['Placemark'][0]['Point']['coordinates'][1::-1])
  File "/usr/local/lib/python2.7/dist-packages/googlemaps.py", line 259, in geocode
    url, response = fetch_json(self._GEOCODE_QUERY_URL, params=params)
  File "/usr/local/lib/python2.7/dist-packages/googlemaps.py", line 50, in fetch_json
    response = urllib2.urlopen(request)
  File "/usr/lib/python2.7/urllib2.py", line 127, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 407, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 520, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 445, in error
    return self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 379, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 528, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden

【问题讨论】:

标签: python google-maps python-2.7


【解决方案1】:

您使用的 googlemaps 包不是官方包,并且不使用谷歌最新的 google maps API v3。

您可以使用 google 的 geocode REST api 从地址获取坐标。这是一个例子。

import requests

response = requests.get('https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA')

resp_json_payload = response.json()

print(resp_json_payload['results'][0]['geometry']['location'])

【讨论】:

  • 此答案确实需要 API 密钥。
  • API 密钥是免费的还是收费的?
  • 据我所知,这需要一把钥匙才能工作并且是收费的。我希望有一个免费的解决方案。
  • 查看下面的答案以获得没有 api 密钥的免费解决方案。
  • 如果您有 API 密钥,请将其添加到 URL 的末尾,如下所示 response = requests.get('https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&amp;key=&lt;YOUR_KEY&gt;')
【解决方案2】:

对于不需要 API 密钥或外部库的 Python 脚本,您可以查询 Nominatim 服务,该服务反过来查询 Open Street Map 数据库。

有关如何使用它的更多信息,请参阅https://nominatim.org/release-docs/develop/api/Search/

一个简单的例子如下:

import requests
import urllib.parse

address = 'Shivaji Nagar, Bangalore, KA 560001'
url = 'https://nominatim.openstreetmap.org/search/' + urllib.parse.quote(address) +'?format=json'

response = requests.get(url).json()
print(response[0]["lat"])
print(response[0]["lon"])

【讨论】:

  • 您能稍微解释一下它是如何工作的吗?
  • 在选择 Nominatim/OSM API 之前阅读此 API 的使用政策:operations.osmfoundation.org/policies/nominatim
  • 对那些使用这个sn-p的人来说只是一个警告,它并不总是产生响应。只是这样我可以为你们节省一些时间。
【解决方案3】:

试试这个代码:

from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="my_user_agent")
city ="London"
country ="Uk"
loc = geolocator.geocode(city+','+ country)
print("latitude is :-" ,loc.latitude,"\nlongtitude is:-" ,loc.longitude)

【讨论】:

  • 不支持 utf-8 字符。它只适合拉丁语。有什么方法可以使它适用于 utf-8?
  • 你不知道这有多大帮助...谢谢...
【解决方案4】:

使用 google api、Python 和 Django 获取纬度和经度的最简单方法。

# Simplest way to get the lat, long of any address.

# Using Python requests and the Google Maps Geocoding API.

        import requests

        GOOGLE_MAPS_API_URL = 'http://maps.googleapis.com/maps/api/geocode/json'

        params = {
            'address': 'oshiwara industerial center goregaon west mumbai',
            'sensor': 'false',
            'region': 'india'
        }

        # Do the request and get the response data
        req = requests.get(GOOGLE_MAPS_API_URL, params=params)
        res = req.json()

        # Use the first result
        result = res['results'][0]

        geodata = dict()
        geodata['lat'] = result['geometry']['location']['lat']
        geodata['lng'] = result['geometry']['location']['lng']
        geodata['address'] = result['formatted_address']

    print('{address}. (lat, lng) = ({lat}, {lng})'.format(**geodata))

# Result => Link Rd, Best Nagar, Goregaon West, Mumbai, Maharashtra 400104, India. (lat, lng) = (19.1528967, 72.8371262)

【讨论】:

  • 这会出现在您的观点还是模型中?另外,如果我想将 lat 和 long 存储在一个字段中,我该怎么做?
  • 这也需要一个 api-key 必须在参数中设置,如'key': 'AIza...'
  • 为什么需要 Django?
【解决方案5】:

您好,这是我最常使用物理地址获取纬度和经度的一个。 注意:请将NaN 填空。 df.adress.fillna('')

from geopy.exc import GeocoderTimedOut
# You define col corresponding to adress, it can be one
col_addr = ['street','postcode','town']
geocode = geopy.geocoders.BANFrance().geocode  

def geopoints(row):
    search=""
    for x in col_addr:
        search = search + str(row[x]) +' '

    if search is not None:
        print(row.name+1,end="\r")
        try:
            search_location = geocode(search, timeout=5)
            return search_location.latitude,search_location.longitude
        except (AttributeError, GeocoderTimedOut):
            print("Got an error on index : ",row.name)
            return 0,0


print("Number adress to located /",len(df),":")
df['latitude'],df['longitude'] = zip(*df.apply(geopoints, axis=1))

注意:我使用 BANFrance() 作为 API,你可以在这里找到其他 API Geocoders

【讨论】:

    【解决方案6】:

    正如@WSaitama 所说,geopy 运行良好,并且不需要身份验证。下载:https://pypi.org/project/geopy/。如何使用它的一个例子是:

    from geopy.geocoders import Nominatim
    
    address='Barcelona'
    geolocator = Nominatim(user_agent="Your_Name")
    location = geolocator.geocode(address)
    print(location.address)
    print((location.latitude, location.longitude))
    #Barcelona, Barcelonès, Barcelona, Catalunya, 08001, España
    #(41.3828939, 2.1774322)
    

    【讨论】:

      【解决方案7】:

      我在这个主题中采用了一个解决方案,但它对我不起作用,因此它对其进行了调整并且它起作用了。 不需要令牌。

      请参考文档以进一步了解:https://nominatim.org/release-docs/latest/api/Search/

      这里是代码。

      import requests
      import urllib.parse
      
      city = "Paris"
      country = "France"
      url = "https://nominatim.openstreetmap.org/?addressdetails=1&q=" + city + "+" + country +"&format=json&limit=1"
      
      response = requests.get(url).json()
      print(response[0]["lat"])
      print(response[0]["lon"])
      

      输出:

      48.8566969 2.3514616

      【讨论】:

        【解决方案8】:

        您还可以将地理编码器与 Bing 地图 API 结合使用。 API 为我获取所有地址的纬度和经度数据(不像 Nominatim 仅适用于 60% 的地址),并且它有一个非常好的非商业用途免费版本(每年最多 125000 个免费请求)。要获取免费 API,请转到 here 并单击“获取免费基本密钥”。得到你的 API 后,你可以在下面的代码中使用它:

        import geocoder # pip install geocoder
        g = geocoder.bing('Mountain View, CA', key='<API KEY>')
        results = g.json
        print(results['lat'], results['lng'])
        

        results 包含比经度和纬度更多的信息。看看吧。

        【讨论】:

          【解决方案9】:

          您是否尝试使用库 geopy ? https://pypi.org/project/geopy/

          它适用于 python 2.7 到 3.8。 它也适用于 OpenStreetMap Nominatim、Google Geocoding API (V3) 等。

          希望对你有帮助。

          【讨论】:

          • 而且,它非常好用
          【解决方案10】:

          这是我使用 geopypositionstack API 备份的 nominatim 解决方案

          Positionstack API 每月免费支持多达 25,000 个请求

          import requests
          
          from geopy.geocoders import Nominatim
          
          geolocator = Nominatim(user_agent='myapplication')
          
          def get_nominatim_geocode(address):
              try:
                location = geolocator.geocode(address)
                return location.raw['lon'], location.raw['lat']
              except Exception as e:
                  # print(e)
                  return None, None
          
          def get_positionstack_geocode(address):
            BASE_URL = "http://api.positionstack.com/v1/forward?access_key="
            API_KEY = "YOUR_API_KEY"
            
            url = BASE_URL +API_KEY+'&query='+urllib.parse.quote(address)
            try:
                response = requests.get(url).json()
                # print( response["data"][0])
                return response["data"][0]["longitude"], response["data"][0]["latitude"]
            except Exception as e:
                # print(e)
                return None,None
          
          def get_geocode(address):
            long,lat = get_nominatim_geocode(address)
            if long == None:
              return get_positionstack_geocode(address)
            else:
              return long,lat
          
          address = "50TH ST S"
          
          get_geocode(address)
          

          输出:

          ('-80.2581662', '26.6077474'
          

          您也可以在没有geopy 客户端的情况下使用nominatim

          import requests
          import urllib
          
          def get_nominatim_geocode(address):
              url = 'https://nominatim.openstreetmap.org/search/' + urllib.parse.quote(address) + '?format=json'
              try:
                  response = requests.get(url).json()
                  return response[0]["lon"], response[0]["lat"]
              except Exception as e:
                  # print(e)
                  return None, None
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-25
            • 2016-09-29
            • 1970-01-01
            相关资源
            最近更新 更多