37DATA

百度地图初体验

背景:

最近在处理一个疫情专区的业务,准备引入百度地图作为展示的载体,所以前期需要调研百度地图的一些功能是否满足业务需求,比如:地图上描点,画区域、经纬度转换等等。而作为一名后端呢,也会关注一些数据处理,很庆幸调研下来是可以基本满足业务需求的。

接下来篇幅,会比较倾向后端与百度地图交互的一些数据处理。

实现步骤:

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)实现效果:

Image

总结:

从前期调研web地图的相关组件到数据处理再到与前端同事配合处理业务实现,过程中不仅体验到了地图的有趣之处,也涉猎了下新领域。所以,继续保持好奇心,多挑战,多学习吧,以上内容,如有不对或错漏的地方,欢迎大家指正。