0
点赞
收藏
分享

微信扫一扫

【GIS开发】地理编码服务(Geocoding API,Python,Javascript)

文章目录

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}]

后记

举报

相关推荐

0 条评论