文章目录
1、简介
地理编码是将地址(如"1600 Amphitheatre Parkway, Mountain View, CA")转换为地理坐标(如纬度 37.423021 和经度 -122.083739)的过程,可用于放置标记或定位地图。反向地理编码是将地理坐标转换为人类可读地址的过程。此外,您还可以使用地理编码器查找给定地点 ID 的地址。
地理编码/逆地理编码 API 是通过 HTTP/HTTPS 协议访问远程服务的接口,提供结构化地址与经纬度之间的相互转化的能力。结构化地址的定义: 首先,地址肯定是一串字符,内含国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦等建筑物名称。按照由大区域名称到小区域名称组合在一起的字符。一个有效的地址应该是独一无二的。
1、百度
-
拾取坐标系统
https://api.map.baidu.com/lbsapi/getpoint/index.html
-
Geocoding API
https://api.map.baidu.com/lbsapi/cloud/webservice-geocoding.htm
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库实现地理编码功能
# Author: 爱看书的小沐
# Date: 2022-3-25
# Languages: Python
# Platform: Python 3.9.7 win64
# OS: Win10 win64
# ***********************************************************************
import requests
addr="上海市浦东新区世博园区"
key="your key"
url= f'http://api.map.baidu.com/geocoder?address={addr}&output=json&key={key}'
ret = requests.get(url).json()
print("**************************************")
print("【地址转经纬度】:", 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("【经纬度转地址】:", ret)
2、高德
https://lbs.amap.com/demo/javascript-api/example/geocoder/geocoding
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>地理编码(地址->经纬度)</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
<style>
html,body,#container{
height:100%;
width:100%;
}
.btn{
width:10rem;
margin-left:6.8rem;
}
</style>
</head>
<body>
<div id="container"></div>
<div class="input-card" style='width:28rem;'>
<label style='color:grey'>地理编码,根据地址获取经纬度坐标</label>
<div class="input-item">
<div class="input-item-prepend"><span class="input-item-text" >地址</span></div>
<input id='address' type="text" value='北京市朝阳区阜荣街10号' >
</div>
<div class="input-item">
<div class="input-item-prepend"><span class="input-item-text">经纬度</span></div>
<input id='lnglat' disabled type="text">
</div>
<input id="geo" type="button" class="btn" value="地址 -> 经纬度" />
</div>
<script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&plugin=AMap.Geocoder"></script>
<script type="text/javascript">
var map = new AMap.Map("container", {
resizeEnable: true
});
var geocoder = new AMap.Geocoder({
city: "010", //城市设为北京,默认:“全国”
});
var marker = new AMap.Marker();
function geoCode() {
var address = document.getElementById('address').value;
geocoder.getLocation(address, function(status, result) {
if (status === 'complete'&&result.geocodes.length) {
var lnglat = result.geocodes[0].location
document.getElementById('lnglat').value = lnglat;
marker.setPosition(lnglat);
map.add(marker);
map.setFitView(marker);
}else{
log.error('根据地址查询位置失败');
}
});
}
document.getElementById("geo").onclick = geoCode;
document.getElementById('address').onkeydown = function(e) {
if (e.keyCode === 13) {
geoCode();
return false;
}
return true;
};
</script>
</body>
</html>
3、google
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>
4、nominatim
https://nominatim.openstreetmap.org/ui/search.html
http://localhost:8088/status.php
http://localhost:8088/search.php?q=Berlin
http://localhost:8088/reverse.php?lat=27.1750090510034&lon=78.04209025
访问地址如下:
https://nominatim.openstreetmap.org/search.php?q=%E6%B5%99%E6%B1%9F%E5%A4%A7%E5%AD%A6&format=jsonv2
https://nominatim.openstreetmap.org/reverse.php?lat=30.278166739369016&lon=120.13608139999998&zoom=18&format=jsonv2
search.php查询结果如下:
[{
"place_id": 285851350,
"licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
"osm_type": "relation",
"osm_id": 9346819,
"boundingbox": ["30.2739785", "30.2823548", "120.1313499", "120.1408129"],
"lat": "30.2768278",
"lon": "120.13663990955736",
"display_name": "浙江大学(西溪校区), 148号, 天目山路, 西湖区, 杭州市, 西溪街道, 浙江省, 310028, 中国",
"place_rank": 30,
"category": "amenity",
"type": "university",
"importance": 0.001,
"icon": "https://nominatim.openstreetmap.org/ui/mapicons//education_university.p.20.png"
}
]
reverse.php查询结果如下:
{
"place_id": 285851350,
"licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
"osm_type": "relation",
"osm_id": 9346819,
"lat": "30.2768278",
"lon": "120.13663990955736",
"place_rank": 30,
"category": "amenity",
"type": "university",
"importance": 0,
"addresstype": "amenity",
"name": "浙江大学(西溪校区)",
"display_name": "浙江大学(西溪校区), 148号, 天目山路, 西湖区, 杭州市, 西溪街道, 浙江省, 310028, 中国",
"address": {
"amenity": "浙江大学(西溪校区)",
"house_number": "148号",
"road": "天目山路",
"suburb": "西湖区",
"city": "杭州市",
"state": "浙江省",
"postcode": "310028",
"country": "中国",
"country_code": "cn"
},
"boundingbox": ["30.2739785", "30.2823548", "120.1313499", "120.1408129"]
}
安装python的第三方库geopy,如下:
pip install geopy
- 地理编码(python)
这里通过编写Python脚本实现地理编码功能如下:
#***********************************************************************
# Purpose: 基于geopy库实现地理编码功能
# 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("浙江省浙江大学")
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库实现地理编码功能
# 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.")
5、geocode
https://geocode.maps.co/search?q={address}
https://geocode.maps.co/reverse?lat={latitude}&lon={longitude}
https://geocode.maps.co/search?q=上海世博园
查询结果如下:
[{“place_id”:116401503,“licence”:“Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright”,“osm_type”:“way”,“osm_id”:48759637,“boundingbox”:[“31.1819189”,“31.1897892”,“121.4867975”,“121.4892059”],“lat”:“31.1861836”,“lon”:“121.48792978129018”,“display_name”:“世博源, 上南路, 浦东新区, 上海市, 200126, 中国”,“class”:“shop”,“type”:“mall”,“importance”:0.25130841619905603}]