【GIS开发】地理编码服务Geocoder(Python)

25 篇文章 45 订阅

1、简介

地理编码 (Geocoding)是一个街道、地址或者其他位置(经度、纬度)转化为坐标的过程。反向地理编码 (Reverse geocoding)是将坐标转换为地址(经度、纬度)的过程。一组反向地理编码结果间可能会有所差异。例如:一个结果可能包含最临近建筑的完整街道地址,而另一个可能只包含城市名称和邮政编码。

在这里插入图片描述

2、百度

Geocoding API 是一类简单的HTTP接口,用于提供从地址到经纬度坐标或者从经纬度坐标到地址的转换服务,用户可以使用C# 、C++、Java等开发语言发送HTTP请求且接收JSON、XML的返回数据。
在这里插入图片描述
Geocoding API包括地址解析和逆地址解析功能。

  • 地理编码:即地址解析,由详细到街道的结构化地址得到百度经纬度信息,且支持名胜古迹、标志性建筑名称直接解析返回百度经纬度。例如:“北京市海淀区中关村南大街27号”地址解析的结果是“lng:116.31985,lat:39.959836”,“百度大厦”地址解析的结果是“lng:116.30815,lat:40.056885”
  • 逆地理编码,即逆地址解析,由百度经纬度信息得到结构化地址信息。例如:“lat:31.325152,lng:120.558957”逆地址解析的结果是“江苏省苏州市虎丘区塔园路318号”。

百度地图Geocoding API是一套免费对外开放的API,无使用次数限制。使用方法:

  • 第一步:申请ak(即获取密钥),若无百度账号则首先需要注册百度账号。
  • 第二步,拼写发送http请求的url,注意需使用第一步申请的ak。
  • 第三步,接收http请求返回的数据(支持json和xml格式)。
http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=E4805d16520de693a3fe707cdc9620
http://api.map.baidu.com/geocoder/v2/?ak=E4805d16520de693a3fe707cdc962045&callback=renderReverse&location=39.983424,116.322987&output=json&pois=1
http://api.map.baidu.com/geocoder/v2/?ak=E4805d16520de693a3fe707cdc962045&callback=renderReverse&location=39.983424,116.322987&output=xml&pois=1

这里通过编写Python脚本实现地理编码功能如下:

#***********************************************************************
#   Purpose:   基于geopy库实现geocoder功能
#   Author:    爱看书的小沐
#   Date:      2022-3-25
#   Languages: Python
#   Platform:  Python 3.9.7 win64
#   OS:        Win10 win64
# ***********************************************************************

import requests

addr="Harvard University"
key="your key"
url= f'http://api.map.baidu.com/geocoder?address={addr}&output=json&key={key}'
ret = requests.get(url).json()

print("**************************************")
print("【address to latlon】:", ret)
print(ret['result']['location'])

lng_lat=[121.498794,31.182546]
key="your key"
url=f"http://api.map.baidu.com/geocoder?callback=renderReverse&location={lng_lat[1]},{lng_lat[0]}&output=json&pois=1&key={key}"
ret = requests.get(url).json()
print("**************************************")
print("【latlon to address】:", ret)

在这里插入图片描述

3、高德

https://lbs.amap.com/demo/javascript-api/example/geocoder/geocoding
在这里插入图片描述

4、google map

https://developers.google.com/maps/documentation/javascript/geocoding
在这里插入图片描述

var geocoder;
  var map;
  function initialize() {
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(-34.397, 150.644);
    var mapOptions = {
      zoom: 8,
      center: latlng
    }
    map = new google.maps.Map(document.getElementById('map'), mapOptions);
  }

  function codeAddress() {
    var address = document.getElementById('address').value;
    geocoder.geocode( { 'address': address}, function(results, status) {
      if (status == 'OK') {
        map.setCenter(results[0].geometry.location);
        var marker = new google.maps.Marker({
            map: map,
            position: results[0].geometry.location
        });
      } else {
        alert('Geocode was not successful for the following reason: ' + status);
      }
    });
  }

<body onload="initialize()">
 <div id="map" style="width: 320px; height: 480px;"></div>
  <div>
    <input id="address" type="textbox" value="Sydney, NSW">
    <input type="button" value="Encode" onclick="codeAddress()">
  </div>
</body>

Here is a typical example of retrieving a Lat & Lng from Google using Python,
things shouldn’t be this hard.

import requests
url = 'https://maps.googleapis.com/maps/api/geocode/json'
params = {'sensor': 'false', 'address': 'Mountain View, CA'}
resp = requests.get(url, params=params)
results = resp.json()['results']
location = results[0]['geometry']['location']
location['lat'], location['lng']
(37.3860517, -122.0838511)

5、nominatim

https://nominatim.org/

Nominatim:Open-source geocoding with OpenStreetMap data
Nominatim uses OpenStreetMap data to find locations on Earth by name and address (geocoding). It can also do the reverse, find an address for any location on the planet.

5.1 overview

  • Geocoding
    Find places by name or address (Geocoding):
    Nominatim can power the search box on your website, allowing your users to type free-form queries (“Cafe Paris, New York”) in any language. It also offers a structured query mode (“postcode=12345”, “city=London”, “type=cafe”) that helps you to automate geocoding of extensive address lists.
  • Reverse geocoding
    Look up addresses for a location (Reverse geocoding)
    Given a latitude and longitude anywhere on the planet, Nominatim can find the nearest address. It can do the same for any OSM object given its ID.
    在这里插入图片描述

5.2 web api

https://nominatim.org/release-docs/develop/api/Overview/

Nominatim indexes named (or numbered) features within the OpenStreetMap (OSM) dataset and a subset of other unnamed features (pubs, hotels, churches, etc).

Nominatim API,Its API has the following endpoints for querying the data:

- /search - search OSM objects by name or type
- /reverse - search OSM object by their location
- /lookup - look up address details for OSM objects by their ID
- /status - query the status of the server
- /deletable - list objects that have been deleted in OSM but are held back in Nominatim in case the deletion was accidental
- /polygons - list of broken polygons detected by Nominatim
- /details - show internal details for an object (for debugging only)
http://localhost:8088/status.php
http://localhost:8088/search.php?q=Berlin
http://localhost:8088/reverse.php?lat=27.1750090510034&lon=78.04209025
  • search.php
#***********************************************************************
#   Purpose:   基于https访问search.php实现geocode功能
#   Author:    爱看书的小沐
#   Date:      2022-3-25
#   Languages: Python
#   Platform:  Python 3.9.7 win64
#   OS:        Win10 win64
# ***********************************************************************

import requests
url = 'https://nominatim.openstreetmap.org/search.php?q=哈佛大学&format=jsonv2'
response = requests.get(url)
print(response.text)
# print(response.json())
print(type(response.status_code), response.status_code)
print(type(response.headers), response.headers)
print(type(response.cookies), response.cookies)
print(type(response.url), response.url)
print(type(response.history), response.history)

# import requests
# url = 'https://nominatim.openstreetmap.org/search.php'
# params = {'q': '哈佛大学', 'format': 'jsonv2'}
# response = requests.get(url, params=params)
# print(response.text)
  • reverse.php
#***********************************************************************
#   Purpose:   基于https访问reverse.php实现反向geocode功能
#   Author:    爱看书的小沐
#   Date:      2022-3-25
#   Languages: Python
#   Platform:  Python 3.9.7 win64
#   OS:        Win10 win64
# ***********************************************************************

import requests
url = 'https://nominatim.openstreetmap.org/reverse.php?lat=42.36790855&lon=-71.12678237443698&zoom=18&format=jsonv2'
response = requests.get(url)
print(response.text)
print(response.json())

# import requests
# url = 'https://nominatim.openstreetmap.org/reverse.php'
# params = {'lat': '42.36790855', 'lon': '-71.12678237443698', 'format': 'jsonv2'}
# response = requests.get(url, params=params)
# print(response.text)

5.3 python api (geopy)

安装python的第三方库geopy,如下:

pip install geopy

在这里插入图片描述
这里通过编写Python脚本实现相关功能如下:

  • 地理编码(python)
#***********************************************************************
#   Purpose:   基于geopy库实现geocode功能
#   Author:    爱看书的小沐
#   Date:      2022-3-25
#   Languages: Python
#   Platform:  Python 3.9.7 win64
#   OS:        Win10 win64
# ***********************************************************************

from geopy.geocoders import Nominatim
from geopy.extra.rate_limiter import RateLimiter

geolocator = Nominatim(user_agent="test",timeout=None)
result = geolocator.geocode("Harvard University")
if result != None:
    print(result)
    print("latitude: ", result.latitude)
    print("longitude: ", result.longitude)
    print("address: ", result.address)
    print("altitude: ", result.altitude)
    print("point: ", result.point)
else:
    print("No data.")
  • 反向地理编码(python)
#***********************************************************************
#   Purpose:   基于geopy库实现geocode.reverse功能
#   Author:    爱看书的小沐
#   Date:      2022-3-25
#   Languages: Python
#   Platform:  Python 3.9.7 win64
#   OS:        Win10 win64
# ***********************************************************************

from geopy.geocoders import Nominatim

geolocator = Nominatim(user_agent="test",timeout=None)
lat = 30.2768278
lon = 120.13663990955736
print('.....{}, {}........'.format(lat, lon))
result = geolocator.reverse([lat, lon])
if result != None:
    print(result)
    print("latitude: ", result.latitude)
    print("longitude: ", result.longitude)
    print("address: ", result.address)
    print("altitude: ", result.altitude)
    print("point: ", result.point)
    print("raw: ", result.raw)
else:
    print("No data.")

6、geocode

Many online providers such as Google & Bing have geocoding services,
these providers do not include Python libraries and have different
JSON responses between each other.

It can be very difficult sometimes to parse a particular geocoding provider
since each one of them have their own JSON schema.
在这里插入图片描述

https://geocode.maps.co/search?q={address}
https://geocode.maps.co/reverse?lat={latitude}&lon={longitude}

7、geocoder

Geocoder is a simple and consistent geocoding library.

https://pypi.org/project/geocoder/
https://geocoder.readthedocs.io/

安装如下python第三方库:

pip install geocoder

在这里插入图片描述

  • Providers
ProviderOptimalUsage PolicyMultiple resultsReverseProximityBatch
[ArcGIS][ArcGIS]Worldyesyes
[Baidu][Baidu]ChinaAPI keyyes
[Bing][Bing]WorldAPI keyyesyesyes
[CanadaPost][CanadaPost]CanadaAPI keyyes
[FreeGeoIP][FreeGeoIP]World
[Gaode][Gaode]ChinaAPI keyyes
[Geocoder.ca][Geocoder.ca] (Geolytica)CA & USRate Limit
[GeocodeFarm][GeocodeFarm]World[Policy][GeocodeFarm-Policy]yesyes
[GeoNames][GeoNames]WorldUsernameyesyes
[GeoOttawa][GeoOttawa]Ottawayes
[Gisgraphy][Gisgraphy]WorldAPI keyyesyesyes
[Google][Google]WorldRate Limit, [Policy][G-Policy]yesyesyes
[HERE][HERE]WorldAPI keyyesyes
[IPInfo][IPInfo]WorldRate Limit, [Plans][IP-Plans]
[Komoot][Komoot] (OSM powered)Worldyesyes
[LocationIQ][LocationIQ]WorldAPI Keyyesyes
[Mapbox][Mapbox]WorldAPI keyyesyesyes
[MapQuest][MapQuest]WorldAPI keyyesyesyes
[Mapzen][Mapzen]ShutdownAPI keyyesyes
[MaxMind][MaxMind]World
[OpenCage][OpenCage]WorldAPI keyyesyes
[OpenStreetMap][OpenStreetMap]World[Policy][OpenStreetMap-Policy]yesyes
[Tamu][Tamu]USAPI key
[TGOS][TGOS]Taiwan
[TomTom][TomTom]WorldAPI keyyes
[USCensus][USCensus]USyesyes
[What3Words][What3Words]WorldAPI keyyes
[Yahoo][Yahoo]World
[Yandex][Yandex]Russiayesyes

这里我们看看geocoder都有哪些接口,调试如下:

import geocoder
print(dir(geocoder))

运行结果如下:

[‘author’, ‘author_email’, ‘builtins’, ‘cached’,
copyright’, ‘doc’, ‘file’, ‘license’, ‘loader’,
name’, ‘package’, ‘path’, ‘spec’, ‘title’,
version’, ‘absolute_import’, ‘api’, ‘arcgis’, ‘arcgis_reverse’,
‘baidu’, ‘baidu_reverse’, ‘base’, ‘bing’, ‘bing_batch’,
‘bing_batch_forward’, ‘bing_batch_reverse’, ‘bing_reverse’,
‘canadapost’, ‘cli’, ‘distance’, ‘elevation’, ‘freegeoip’, ‘gaode’,
‘gaode_reverse’, ‘geocodefarm’, ‘geocodefarm_reverse’, ‘geolytica’,
‘geonames’, ‘geonames_children’, ‘geonames_details’,
‘geonames_hierarchy’, ‘get’, ‘gisgraphy’, ‘gisgraphy_reverse’,
‘google’, ‘google_elevation’, ‘google_places’, ‘google_reverse’,
‘google_timezone’, ‘here’, ‘here_reverse’, ‘ip’, ‘ipinfo’, ‘keys’,
‘komoot’, ‘komoot_reverse’, ‘location’, ‘locationiq’,
‘locationiq_reverse’, ‘mapbox’, ‘mapbox_reverse’, ‘mapquest’,
‘mapquest_batch’, ‘mapquest_reverse’, ‘mapzen’, ‘mapzen_reverse’,
‘maxmind’, ‘nokia’, ‘opencage’, ‘opencage_reverse’, ‘osm’,
‘osm_reverse’, ‘ottawa’, ‘places’, ‘reverse’, ‘tamu’, ‘tgos’,
‘timezone’, ‘tomtom’, ‘uscensus’, ‘uscensus_batch’,
‘uscensus_reverse’, ‘w3w’, ‘w3w_reverse’, ‘yahoo’, ‘yandex’,
‘yandex_reverse’]

7.1 arcgis通过地址查询经纬度

import geocoder
g = geocoder.arcgis('Harvard University')
print(g.latlng)
print(g.geojson)
print(g.json)
print(g.wkt)
print(g.osm)

7.2 arcgis通过经纬度查询地址

import geocoder
g = geocoder.arcgis([31.18698, 121.48482], method='reverse')
print(g.address)

7.3 osm通过地址查询经纬度

import geocoder
g = geocoder.osm('Harvard University')
print(g.osm)
#print(g.json)

7.4 osm通过经纬度查询地址

import geocoder
g = geocoder.osm([31.18698, 121.48482], method='reverse')
print(g.osm)
#print(g.json)

7.5 mapbox通过地址查询经纬度

import geocoder
latlng = [34, 114]
g = geocoder.mapbox("Harvard University", proximity=latlng, key='your key')
#print(g.json)
print(g.osm)

7.6 mapbox通过经纬度查询地址

import geocoder
latlng = [31.188118, 121.484889]
g = geocoder.mapbox(latlng, method='reverse', key='your key')
#print(g.json)
print(g.osm)

8、其他

百度地图——拾取坐标系统
网址:http://api.map.baidu.com/lbsapi/getpoint/index.html

高德地图——高德开放平台
网址:https://lbs.amap.com/console/show/picker

腾讯地图——坐标拾取器
网址:https://lbs.qq.com/tool/getpoint/

arcgis
https://developers.arcgis.com/documentation/mapping-apis-and-services/search/tutorials/reverse-geocode/

后记

如果你觉得该方法或代码有一点点用处,可以给作者点个赞、赏杯咖啡;╮( ̄▽ ̄)╭
如果你感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进。o_O???
谢谢各位童鞋们啦( ´ ▽´ )ノ ( ´ ▽´)っ!!!

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值