初探地理编码(2023.11.12)

引言

        谈及地理编码一词,每个人可能有不同的理解和体会,从字面意思来看可分为地理编码两个词语,这样理解似乎更加直观深刻。
        一、地理与人们的日常生活密不可分,海量动态的地理信息涉及时空位置、方位定向,姿态角度、距离面积等的计算和分析,因此地理信息与位置角度等数据紧密相关的,并且是极为重要的,在众多信息中占有不可替代的地位,信息由数据经过加工和再生产得来,能够为人类社会的生产和生活实践提供知识指导。二、编码则是对数据或信息经过二次处理后,直接或间接地进行特殊加密,加密后的信息也可称为报文,不难理解的是,有编码就有解码,有加密就有解密,正如世间万物,相克相生,此起彼伏。
        基于上述的理解或先验知识,那么就不难理解平面坐标 (x,y) 是对二维平面上的某点进行描述三维空间坐标 (X,Y,Z) 能够对立体空间中的点位进行表达,地理学的地理坐标系采用(λ,φ)经纬度来表示地球表面的某处位置。通过进行数字化、参数化的编码和描述来达到对现实场景空间位置的精确表达,进而更好地服务于社会经济的发展,如科学技术研究探讨、文化文明交流互鉴、贸易往来道路通畅、人文艺术中西融合等多个方面。

1、地理编码简介

        地理编码也称地址匹配它是为识别点、线、面的位置和属性而设置的编码,它将全部实体按照预先拟定的分类系统,选择最适宜的量化方法,按实体的属性特征和几何坐标的数据结构记录在计算机的储存设备上。地址编码不仅要实现从地名地址到具体位置经纬度的转换,还需要根据给定的空间位置坐标来反馈与之相关度最高的地名地址。前者被称为正向地理编码,更加侧重得到空间位置坐标从而进行地址定位;后者则为反向地理编码,作为坐标引擎来实现由位置到地名地址的解析转换。

在这里插入图片描述

        地理编码犹如海上航行的指南针,亦犹如黑夜的灯塔,它可以照亮前方的道路,更好地帮助我们定位和显示自己的足迹,追寻人生的理想。人生轨迹由每个时刻的落脚点连接而成,地理编码宛如罗盘,可以让自己认清自己当前的真实处境和航向,在必要的时刻予以纠偏和掌舵,方能拨开迷雾见云天,顺利到达目标的彼岸。

2、地理编码API和服务(解决方案供应商 / 厂商)

        互联网、计算机、信息技术、云计算、大数据、微服务、容器化、人工智能、生成式等技术的飞速发展,催生了众多的软件服务公司、云计算厂商、数据库和信息技术服务解决方案供应商等企业,分布在教育、游戏、办公、交通、医疗、工业制造、音视频转发和定位导航通信等领域,可谓是百花齐放,百家争鸣,任何一家优秀的企业想要在所涉及的行业中占据一席之地,毫无疑问离不开人才和技术,离不开应用和市场,离不开服务的品质和诚信

        正所谓实践是检验真理的唯一标准,广大的用户绝对能够为各种App应用、软件和解决方案来打分评价,货比三家,对比分析优劣所在,进而选择适合自身需求的满意产品和服务方案。

        下面简单介绍一下国内外与地理编码相关的服务厂商及其各自提供的API,有高德地图、百度地图、超图、天地图、ArcGIS、MapBox、Cesium以及MapLocation等,希望能够给大家带来直观真实的感受。

2.1 高德

        高德地理/逆地理编码API通过 HTTP/HTTPS 协议访问远程服务的接口,提供结构化地址与经纬度之间的相互转化的能力。此API可将结构化地址转换为高德经纬度坐标,尤其支持著名的城市地标建筑物、风景名胜的查询和坐标转换,而且地理编码匹配支持国家、省、市、区县、开发区、乡镇、村庄、热点商圈、兴趣点、门牌号、单元号、道路、道路交叉路口、公交站台、地铁站等多种级别,对于地址的分级分类十分广泛。(注:个人、企业和商用的服务需要授权申请Key,调用量有受限说明

地理编码说明(高德)
地理编码服务示例(高德)

2.2 百度

        百度地理编码接口可帮助用户将将结构化地址解析为对应的位置坐标,当然解析的结果精度与输入地址的结构完整性有关。官网提供了在线运行示例,同时还特意给出了PHP、Go、C++、Python、JavaBash(Curl)调用请求的程序代码,感兴趣的小伙伴都可以体验一下哦,非常不错,当然用户也需要申请AK方能调用服务!

https://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation
不同编程语言进行地理编码服务调用代码(百度)
百度——地理编码服务示例

2.3 超图

        超图在线GIS工具提供了地理编码功能,用户通过登录后方可体验;同时超图地理编码API页面十分详细地给出了使用说明和适用场景,同样地需要用户自行申请秘钥(key)方可适用,支持批量地址匹配采用五级地址库搜索策略,具有较高的检索效率和匹配精度。

2.4 天地图

        天地图地理编码API支持将结构化的地址数据转化为对应坐标点的经纬度,范围仅限国内,在申请接口调用和服务请求前需要自己申请key,同时也支持逆地理编码查询地名搜索

2.5 ArcGIS

        ArcGIS Desktop在线帮助中对于地理编码具有其他厂商无法比拟的内容输出,其介绍程度之详细,过程描述之简洁堪称经典,个人觉得大家可认真学习地理编码过程、框架、工作流等的理论和应用工具,以便有更加深刻的理解。

ArcGIS在线帮助文档
ArcGIS 工具箱中的地理编码工具集
ArcGIS桌面帮助之地理编码

2.6 MapBox

        MapBox地图页面中的搜索框支持地理编码中英文搜索,用户可以亲身体验在候选结果中进行选择并查看匹配的地址结果,具体参数说明和使用可参考Mapbox Geocoding API,另外值得一提的是,官网提供了一个在线Playground环境供广大用户测试,有兴趣的朋友不妨试试!

MapBox中的Geocoder控件
Geocoding API Playground

2.7 Cesium

        Cesium在线示例提供了地理编码功能,该功能需要用户使用access_token来进行服务调用,在输入框中会实时调用自动补全功能(autocomplete),输入结束后点击搜索框才会调用单个确定地址的搜索功能(search),查询结果会返回地址所对应的边界范围(bbox),但是主要面对国外用户且对中文支持不太友好,对国外地址感兴趣的可以试一试!

https://api.cesium.com/v1/geocode/search?text=your_interested_name&access_token=your_token
https://api.cesium.com/v1/geocode/autocomplete?text=your_interested_name&access_token=your_token
San Francisco
Peking University

2.8 MapLocation

        MapLocation的作者秉持开源初心,搭建了一个专注于地址批量转换经纬度的在线地址匹配网站,感兴趣的开发者可以在Map Location 批量转换地址为经纬度批量工具网这两个网站进行即时学习体验,目前支持百度、高德等正逆地理编码和坐标转换处理,效果实用且已在Github开源哦!!!

MapLocation(调用百度API)
MapLocation(调用高德API)

3、python实例

        接下来利用Python脚本编程语言进行地理编码API的实际调用和服务接口封装,具体会调用高德、百度、Cesium以及MapBox地理编码API进行实操。

3.1 pip安装依赖库(python 3.6)

在这里插入图片描述

Python 3.6

        测试环境为python 3.6,利用pip安装requests、flask、flask_cors、pyinstaller四个依赖库。

pip install requests
pip install flask
pip install flask_cors
pip install pyinstaller

3.2 request请求调用API + flask二次封装服务接口 + (高德 + 百度 + Cesium + MapBox)

        话不多说,自己申请各家平台对应的token后,编写如下代码进行地理编码API的调用测试(test_GeocoderAPI.py),这里使用的IDEPyCharm

baidu_apiKey = 'your_baidu_key'
gaode_apiKey = 'your_gaode_key'
 cesium_access_token = 'your_cesium_key'
 mapbox_access_token = 'your_mapbox_key'
 import requests
# from flask import Flask
# from flask_cors import CORS, cross_origin
# from datetime import datetime

def getGaodeGeoCode(location, GaodeApiKey):
    result = ''
    response = requests.get('https://restapi.amap.com/v3/geocode/geo?' + 'key=' + GaodeApiKey + '&address=' + location + '&output=json&callback=', data={
    
    })
    if response.status_code == 200:
        result = response.json()
    else:
        result = {
    
    
            "status": 0
        }
    return result

headers = {
    
    
    'Referer': 'https://www.piliang.tech/'
}
headers2 = {
    
    
    'Referer': 'https://maplocation.sjfkai.com/'
}

def getBaiduGeoCode(headers, location, baiduApiKey):
    result = ''
    response = requests.get('https://api.map.baidu.com/geocoding/v3/?' + 'ak=' + baiduApiKey + '&address=' + location + '&output=json&callback=', headers=headers, data={
    
    })
    if response.status_code == 200:
        result = response.json()
    return result

headers3 = {
    
    
    'Referer': 'https://sandcastle.cesium.com/'
}

def getCesiumGeoCode(location, access_token):
    result = ''
    response = requests.get('https://api.cesium.com/v1/geocode/search?' + 'access_token=' + access_token + '&text=' + location, headers=headers3, data={
    
    })
    if response.status_code == 200:
        result = response.json()
    return result['features']

headers4 = {
    
    
    'Referer': 'https://docs.mapbox.com/'
}
def getMapboxGeoCode(location, access_token):
    result = ''
    response = requests.get('https://api.mapbox.com/geocoding/v5/mapbox.places/' + location + '.json?access_token=' + access_token, headers=headers4, data={
    
    })
    if response.status_code == 200:
        result = response.json()
    return result['features']


# app = Flask(__name__)
# @app.route('/geocode/<location>', methods=['GET'])
# @cross_origin()
# def getLocationAddress(location):
#     return getBaiduGeoCode(headers2, location, baidu_apiKey)

if __name__ == "__main__":

    locations = [
        '北京市海淀区上地十街十号',
        '北京市西城区复兴门内大街101号',
        '北京市东城区王府井西街6号',
    ]

    print('百度-地理编码API调用查询结果:\n')
    for i in range(0, len(locations)):
        print(locations[i], getBaiduGeoCode(headers2, locations[i], baidu_apiKey))

    print('高德-地理编码API调用查询结果:\n')
    for i in range(0, len(locations)):
        print(locations[i], getGaodeGeoCode(locations[i], gaode_apiKey))

    print('Cesium-地理编码API调用查询结果:\n')
    for i in range(0, len(locations)):
        print(locations[i], getCesiumGeoCode(locations[i], cesium_access_token))

    print('MapBox-地理编码API调用查询结果:\n')
    for i in range(0, len(locations)):
        print(locations[i], getMapboxGeoCode(locations[i], mapbox_access_token))

    # app.run(debug=False, port=8081, host='0.0.0.0')

3.3 pyInstaller打包为exe

        输入如下打包命令后,在dist文件夹下会得到exe文件,双击运行即可在浏览器发起服务请求,测试地理编码功能。

pyinstaller -F test_GeocoderAPI.py

4、小结

        对于GISer来说,用好地理编码工具和服务可以快速地获取一些感兴趣点位的地理坐标,从而快速满足场景定位、地图模型展示的需求,可进行二次封装和服务链集成调用。一般来说,地理编码Geocode)和基于位置的服务Location Based Service,简称LBS)息息相关,相辅相成,和大家的生活密不可分,与人们的需求十分贴切,小到查询一个学校、运动场地、住宅小区、商超的具体位置,大到旅游出行、物流交通运输、快递配送。如地铁线路图上的每个站点用圆圈表示,旁边伴有站名,不同的地铁线路采用不同颜色的线条进行表达,更能够从宏观上为人们展示全局视野,从而做到“心中有数”、“目标可达”;如售楼处的房地产商都要在大厅展示楼盘的三维模型,以此更加直观逼真、生动形象地展示所售楼房的区位优势、交通便利程度、小区绿化环境等设施条件,给人一种身临其境之感。
        当然,许多的WebGIS应用都离不开地址搜索、地址匹配、地址定位通过正向地理编码实现快速定位功能由文本描述到坐标 ),可用于地址信息的空间三维表达;利用反向地理编码获取最佳地址从坐标到文本信息 ),更多地是从位置数据来获取尽可能标准化、精准详细的地名描述。尤其需要注意的是,不同厂商的API所提供的服务能力肯定是有所差异的,具体与背后的技术实现思路、顶层设计、专业化精细化程度、数据库等方面息息相关,大家在选择相应的API服务,也要多加思考,择优利用哦。任何一项先进的理念和技术往往都需要和应该首先应用于军事和国防安全领域,不断提高现代化作战环境下精准打击、快速高效防卫的水平和能力。当今时代,全球化、多元化、信息化、数字化、智能化和智慧化的需求日益膨胀,尽管新技术、新方法、新问题和新挑战都层出不穷,但还是需要不断进行优化迭代后方可深化行业应用。如果小伙伴们有兴趣自己实现地理编码功能和服务的话,应该广泛阅读优秀期刊上的学术论文,这里推荐大家可从以下几点深入思考,也可事半功倍:

  • 地名地址标准化
  • 地名地址分层分级
  • 兴趣点按门类划分
  • 数据分库分表
  • 快速精准得分匹配
  • 贪婪式进化式搜索策略
  • 海纳百川,集众家之长

        尽管OpenAI自问世以来异常火热,但还望诸位头脑清晰,理智对待和谨慎使用,国产自主可控尤为关键和必要。
        注:本文旨在分享个人对于地理编码的学习体会和感受,观点并非完全正确,望各位伙伴同仁见谅,疏漏错误之处在所难免,同时欢迎广大开发者和专业爱好者共同交流,批评指正!!!

猜你喜欢

转载自blog.csdn.net/jing_zhong/article/details/133996944