0
点赞
收藏
分享

微信扫一扫

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

墨春 2022-10-19 阅读 131


文章目录

  • ​​1、简介​​
  • ​​2、百度​​
  • ​​3、高德​​
  • ​​4、google map​​
  • ​​5、nominatim​​
  • ​​5.1 overview​​
  • ​​5.2 web api​​
  • ​​5.3 python api (geopy)​​
  • ​​6、geocode​​
  • ​​7、geocoder​​
  • ​​7.1 arcgis通过地址查询经纬度​​
  • ​​7.2 arcgis通过经纬度查询地址​​
  • ​​7.3 osm通过地址查询经纬度​​
  • ​​7.4 osm通过经纬度查询地址​​
  • ​​7.5 mapbox通过地址查询经纬度​​
  • ​​7.6 mapbox通过经纬度查询地址​​
  • ​​8、其他​​
  • ​​后记​​

1、简介

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

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

2、百度

  • 拾取坐标系统
    ​​https://api.map.baidu.com/lbsapi/getpoint/index.html​​ 1、支持地址 精确/模糊 查询;
    2、支持POI点坐标显示、复制;
    3、坐标鼠标跟随显示;
    4、 支持坐标查询(需要将坐标反查框勾选);
  • 【GIS开发】地理编码服务Geocoder(Python)_javascript_02

  • Geocoding API
    ​​https://api.map.baidu.com/lbsapi/cloud/webservice-geocoding.htm​​
  • 【GIS开发】地理编码服务Geocoder(Python)_python_03

Geocoding API 是一类简单的HTTP接口,用于提供从地址到经纬度坐标或者从经纬度坐标到地址的转换服务,用户可以使用C# 、C++、Java等开发语言发送HTTP请求且接收JSON、XML的返回数据。

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


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)

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

3、高德

​​https://lbs.amap.com/demo/javascript-api/example/geocoder/geocoding​​

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

4、google map

​​https://developers.google.com/maps/documentation/javascript/geocoding​​

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

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,) {
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.
  • 【GIS开发】地理编码服务Geocoder(Python)_python_08

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

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


这里通过编写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.

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

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

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

  • Providers

Provider

Optimal

Usage Policy

Multiple results

Reverse

Proximity

Batch

[ArcGIS][ArcGIS]

World

yes

yes

[Baidu][Baidu]

China

API key

yes

[Bing][Bing]

World

API key

yes

yes

yes

[CanadaPost][CanadaPost]

Canada

API key

yes

[FreeGeoIP][FreeGeoIP]

World

[Gaode][Gaode]

China

API key

yes

[Geocoder.ca][Geocoder.ca] (Geolytica)

CA & US

Rate Limit

[GeocodeFarm][GeocodeFarm]

World

[Policy][GeocodeFarm-Policy]

yes

yes

[GeoNames][GeoNames]

World

Username

yes

yes

[GeoOttawa][GeoOttawa]

Ottawa

yes

[Gisgraphy][Gisgraphy]

World

API key

yes

yes

yes

[Google][Google]

World

Rate Limit, [Policy][G-Policy]

yes

yes

yes

[HERE][HERE]

World

API key

yes

yes

[IPInfo][IPInfo]

World

Rate Limit, [Plans][IP-Plans]

[Komoot][Komoot] (OSM powered)

World

yes

yes

[LocationIQ][LocationIQ]

World

API Key

yes

yes

[Mapbox][Mapbox]

World

API key

yes

yes

yes

[MapQuest][MapQuest]

World

API key

yes

yes

yes

[Mapzen][Mapzen]

Shutdown

API key

yes

yes

[MaxMind][MaxMind]

World

[OpenCage][OpenCage]

World

API key

yes

yes

[OpenStreetMap][OpenStreetMap]

World

[Policy][OpenStreetMap-Policy]

yes

yes

[Tamu][Tamu]

US

API key

[TGOS][TGOS]

Taiwan

[TomTom][TomTom]

World

API key

yes

[USCensus][USCensus]

US

yes

yes

[What3Words][What3Words]

World

API key

yes

[Yahoo][Yahoo]

World

[Yandex][Yandex]

Russia

yes

yes

这里我们看看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???
谢谢各位童鞋们啦( ´ ▽´ )ノ ( ´ ▽´)っ!!!


举报

相关推荐

0 条评论