百度地图初体验
背景:
最近在处理一个疫情专区的业务,准备引入百度地图作为展示的载体,所以前期需要调研百度地图的一些功能是否满足业务需求,比如:地图上描点,画区域、经纬度转换等等。而作为一名后端呢,也会关注一些数据处理,很庆幸调研下来是可以基本满足业务需求的。
接下来篇幅,会比较倾向后端与百度地图交互的一些数据处理。
实现步骤:
1、账号申请
申请百度开发者账号,生成百度地图key,用于调用api和组件服务。
2、数据准备
已知的基础数据有:
(1)个人住址信息(纯文本,不规范的数据集合)
(2)腾讯疫情区域数据(区域疫情等级、区域腾讯系坐标点集合、中心点腾讯系坐标点等)
3、数据处理
需处理成格式化数据有:
(1)住址百度系坐标点
(2)住址所属的省市区
(3)疫情区域数据相关腾讯系坐标点转换为百度系坐标点
(4)判断住址坐标点是否在疫情区域内
4、后端实现
(1)住址信息转换为百度系坐标点
参考api文档:https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
请求示例:
https://api.map.baidu.com/geocoding/v3/?&output=json&ak=你的密钥&address=文本住址
返回:
{"status": 0,"result": {"location": {"lng": 113.38019997218298,"lat": 23.13976601798625},"precise": 1,"confidence": 75,"comprehension": 100,"level": "商务大厦"}}
根据以上接口结果,result[“location”]就可以获取文本地址的经纬度了
(2)住址信息输出所属的省市区
基于第(1)步,已经得到了住址的经纬度,接下来再使用百度api就可以反推出对应的省市区。
参考api文档:https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding-abroad
请求示例:
https://api.map.baidu.com/reverse_geocoding/v3/?ak=你的密钥&output=json&location=维度,经度
返回:
{"status": 0,"result": {"location": {"lng": 113.38019997218297,"lat": 23.13976602925034},"formatted_address": "广东省广州市天河区荷光四横路6号","business": "棠下,车陂","addressComponent": {"country": "中国","country_code": 0,"country_code_iso": "CHN","country_code_iso2": "CN","province": "广东省","city": "广州市","city_level": 2,"district": "天河区","town": "","town_code": "","distance": "24","direction": "附近","adcode": "440106","street": "荷光四横路","street_number": "6号"}}}
根据以上接口结果,result[“addressComponent”]就可以获取文本地址的对应的省市区了。
(3)疫情区域数据相关腾讯系坐标点转换为百度系坐标点
已知的腾讯疫情区域接口数据格式如下:
{"result": {"count": 1,"data": [{"title": "夏湾二巷-东升东街围合区域","address": "广东省珠海市香洲区夏湾二巷,东升东街围合区域","location": {"lat": 22.225798,"lng": 113.543028},"id": "62b13913c11482400253c562","x": {"class": "2022年06月28日 更新","level": "管控区","news_push_msg": "2022062105","parent_polygon_ids": "","source": "人不出区、严禁聚集","tags": "管控区"},"_distance": 6079.23438,"ud_id": "2174941526611193089","polygon": "22.226382,113.542568;22.225128,113.542723;22.225204,113.543471;22.22582,113.543416;22.22646,113.543349;22.226382,113.542568","tel": ""}]}}
由于腾讯接口返回的是腾讯系坐标点,而业务使用了百度地图作为载体,为了避免坐标点偏移,所以得把坐标点统一处理成百度系坐标点,不同地图的坐标系区别可以参考文档:https://www.cnblogs.com/66w66/p/13838783.html,当然百度地图也提供具体的转换api。
参考api文档:https://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
请求示例:
https://api.map.baidu.com/geoconv/v1/?coords=经度,维度;经度,维度&from=3&to=5&ak=你的密钥
返回:
{"status": 0,"result": [{"x": 113.38664754541813,"y": 23.14593567532157},{"x": 113.3961781365075,"y": 23.804920782948654}]}
根据以上接口结果,我们就可以把疫情区域的里面的result[“data"][“location"]和result[“data"][“polygon"]数据处理为百度系坐标。
(4)判断住址坐标点是否在疫情区域内
由于这个是比较定制的逻辑,所以没有官方的api支持,后面查阅相关资料,还是可以实现的,有兴趣可以参考下地址:https://www.freesion.com/article/2003853352/
由于后端服务使用了golang语言,后面借鉴了对应方法进行实现:
https://blog.csdn.net/mctlilac/article/details/120807372
5、前端实现
有了第4步的格式化数据后,接下来就是使用百度地图作为前端载体,进行业务的实现。
下面贴了一小段调研过程示例代码和效果。
(1)简单代码使用
<!DOCTYPE html><html><head><meta name="viewport" content="initial-scale=1.0, user-scalable=no" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Hello, World</title><style type="text/css">html {height: 100%}body {height: 100%;margin: 0px;padding: 0px}#container {height: 100%}</style><script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=您的密钥">//v3.0版本的引用方式:src="https://api.map.baidu.com/api?v=3.0&ak=您的密钥"</script></head><body><div id="container"></div><script type="text/javascript">// 创建地图实例var map = new BMap.Map("container")// 设置中心点坐标和地图级别map.centerAndZoom('广州市', 13);// 开启鼠标滚轮缩放map.enableScrollWheelZoom(true);// 创建点坐标var point = new BMap.Point(113.390351,23.12297)// 标注const marker = new BMap.Marker(point)// 添加覆盖物map.addOverlay(marker)//创建区域var lnglatArr = new Array();lnglatArr.push(new BMap.Point(113.380408,23.123958));lnglatArr.push(new BMap.Point(113.345078,23.10954));lnglatArr.push(new BMap.Point(113.331062,23.155823));lnglatArr.push(new BMap.Point(113.324652,23.093846));var hole = new BMap.Polygon(lnglatArr, {strokeColor: 'black', //边线颜色。fillColor: "red", //填充颜色。当参数为空时,圆形将没有填充效果。strokeWeight: 2, //边线的宽度,以像素为单位。strokeOpacity: 0.8, //边线透明度,取值范围0 - 1。fillOpacity: 0.5, //填充的透明度,取值范围0 - 1。strokeStyle: 'solid' //边线的样式,solid或dashed。});map.addOverlay(hole);</script></body></html>
(2)实现效果:
总结:
从前期调研web地图的相关组件到数据处理再到与前端同事配合处理业务实现,过程中不仅体验到了地图的有趣之处,也涉猎了下新领域。所以,继续保持好奇心,多挑战,多学习吧,以上内容,如有不对或错漏的地方,欢迎大家指正。