GPS转换百度地图坐标&websocket(stomp)实现动态打点


       这会已经下班乐,本来觉得这个好像没有什么新东西。最后决定还是趁现在下班写写是因为要让大家看看单技术组合使用的意义。这里就是在上次springBoot+thymeleaf+layui后端极速做前后端开发的基础上增加内容:

  • 1、接入百度地图
  • 2、接入以前分享过的websocket + stomp
  • 3、实现一个动态地图打点(这里用于做定位设备的实时位置打点)

一、百度地图接入

       这个的接入其实没有什么资源需要下载放到我们自己项目里的,除非是做离线地图接入。
根据官网的接入步骤很简单。

二、websocket+stomp接入

       这个这里我也不重复说了,看我之前的博文。

三、页面代码

       这个里面可以看到第一、二的页面接入

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
    <link rel="shortcut icon" th:href="@{/favicon.ico}"/>
    <link rel="bookmark" th:href="@{/favicon.ico}"/>
    <link rel="stylesheet" type="text/css" th:href="@{/layui/css/layui.css}"/>
    <script type="text/javascript" th:src="@{/layui/layui.js}"></script>
    <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>

    <style>
        body, html, #allmap {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            font-family: "微软雅黑";
        }
    </style>
    <script type="text/javascript"
            src="https://api.map.baidu.com/api?v=3.0&ak=YNxcSCAphFvuPD4LwcgWXwC3SEZZc7Ra"></script>

    <script type="text/javascript" th:src="@{/js/business.js}"></script>


    <script>
        //一般直接写在一个js文件中
        layui.use(['layer', 'form'], function () {
            var layer = layui.layer
                , form = layui.form;

            layer.msg('Hello World');
        });

    </script>
</head>

<body>
    <div id="allmap"></div>
</body>
</html>
<script>
    // GL版命名空间为BMapGL
    // 按住鼠标右键,修改倾斜角和角度
    var map = new BMap.Map("allmap");    // 创建Map实例
    map.centerAndZoom(new BMap.Point(114.406151, 30.476755), 12);  // 初始化地图,设置中心点坐标和地图级别
    map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
    //map.setHeading(64.5);
    //map.setTilt(73);
    map.addControl(new BMap.NavigationControl());   //平移缩放控件
    map.addControl(new BMap.ScaleControl());        //比例尺
    map.addControl(new BMap.OverviewMapControl());  //缩略地图
    map.addControl(new BMap.MapTypeControl());      //地图类型


    var gc = new BMap.Geocoder();
    var geolocation = new BMap.Geolocation();
    // 开启SDK辅助定位
    geolocation.enableSDKLocation();
    geolocation.getCurrentPosition(function (position) {   //定位结果对象会传递给r变量

            if (this.getStatus() == BMAP_STATUS_SUCCESS) {  //通过Geolocation类的getStatus()可以判断是否成功定位。
                var pt = position.point;
                var pcr = "地址:";
                var lat = position.latitude;
                var lng = position.longitude;
                var ggPoint = new BMap.Point(lng, lat);
                gc.getLocation(new BMap.Point(lng, lat), function (rs, error) {
                    if (rs) {
                        var addComp = rs.addressComponents;
                        pcr += addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber;
                        //alert(pcr);
                        console.log("您所在的位置: 经度" + lat + ",纬度" + lng + "," + pcr);

                        var marker = new BMap.Marker(ggPoint);
                        map.addOverlay(marker);
                        var label = new BMap.Label("您所在的位置 [" + pcr + "]", {offset: new BMap.Size(20, -10)});
                        marker.setLabel(label); //添加百度label
                        map.setCenter(ggPoint);

                    } else {
                        alert("获取定位失败");
                    }
                }, {poiRadius: 5, numPois: 1});

            } else {
                //关于状态码
                //BMAP_STATUS_SUCCESS   检索成功。对应数值“0”。
                //BMAP_STATUS_CITY_LIST 城市列表。对应数值“1”。
                //BMAP_STATUS_UNKNOWN_LOCATION  位置结果未知。对应数值“2”。
                //BMAP_STATUS_UNKNOWN_ROUTE 导航结果未知。对应数值“3”。
                //BMAP_STATUS_INVALID_KEY   非法密钥。对应数值“4”。
                //BMAP_STATUS_INVALID_REQUEST   非法请求。对应数值“5”。
                //BMAP_STATUS_PERMISSION_DENIED 没有权限。对应数值“6”。(自 1.1 新增)
                //BMAP_STATUS_SERVICE_UNAVAILABLE   服务不可用。对应数值“7”。(自 1.1 新增)
                //BMAP_STATUS_TIMEOUT   超时。对应数值“8”。(自 1.1 新增)
                switch (this.getStatus()) {
                    case 2:
                        alert('位置结果未知 获取位置失败.');
                        break;
                    case 3:
                        alert('导航结果未知 获取位置失败..');
                        break;
                    case 4:
                        alert('非法密钥 获取位置失败.');
                        break;
                    case 5:
                        alert('对不起,非法请求位置  获取位置失败.');
                        break;
                    case 6:
                        alert('对不起,当前 没有权限 获取位置失败.');
                        break;
                    case 7:
                        alert('对不起,服务不可用 获取位置失败.');
                        break;
                    case 8:
                        alert('对不起,请求超时 获取位置失败.');
                        break;

                }
            }

        },
        {enableHighAccuracy: true}
    )


    //建立ws连接
    var host = "172.16.2.70:8198/datadiver";
    var topic = "address";
    var userName = "zw";
    var token = "token";
    var tenantId = "tenantId";
    var clientId = "clientId";
    stompWsConn(host, topic, userName, token, tenantId, clientId);


</script>

business.js

/**
 * 模块按钮
 * @param pageName
 */
function menuGoUrl(pageName) {
    var pageUrl = "";
    if (pageName != null && pageName != "") {
        switch (pageName) {
            case "baiduMap":
                pageUrl = "./deviceMap/baidu";
                break;
            case "zwCsdn":
                pageUrl = "https://blog.csdn.net/zwrlj527";
                break;
        }
    }
    layui.$("#showBody").attr("src", pageUrl);
}

/**
 * 设置设备新位置
 * @param point 经纬度位置点
 * @param labelName label名称
 */
function setDeviceNewAddress(point, labelName) {
    var marker = new BMap.Marker(point);
    map.addOverlay(marker);
    //var label = new BMap.Label("转换后的百度坐标(正确)", {offset: new BMap.Size(20, -10)});
    var label = new BMap.Label(labelName, {offset: new BMap.Size(20, -10)});
    marker.setLabel(label); //添加百度label
    map.setCenter(point);
    map.centerAndZoom(point, 12);
}

/**
 * 添加地址信息
 * @param point 经纬度位制点
 * @param labelName label名称
 */
function addAddressLabel(point, labelName) {
    gc.getLocation(point, function (rs, error) {
        if (rs) {
            var addComp = rs.addressComponents;
            labelName += " [" + addComp.province + addComp.city + addComp.district + addComp.street + addComp.streetNumber + "]";
            //alert(pcr);
            console.log("设备所在的位置:" + labelName);
            setDeviceNewAddress(point, labelName);
        } else {
            alert("获取定位失败");
        }
    }, {poiRadius: 5, numPois: 1});
}

/**
 * 测试地图打点
 * 这里是GPS位置信息转百度位置信息后再打点,不然不准确,准换js是官网复制的
 * @param wsObj ws信息字符串
 */
function testSetAddres(wsObj) {
    try {
        var address = JSON.parse(wsObj);
        var x = address.lat;
        var y = address.lng;
        var deviceNo = address.deviceNo;
        console.log("deviceNo:" + deviceNo + "经纬度:" + x + "---" + y);
        var ggPoint = new BMap.Point(x, y);

        /*  //添加gps marker和label
          var markergg = new BMap.Marker(ggPoint);
          map.addOverlay(markergg); //添加GPS marker
          var labelgg = new BMap.Label("未转换的GPS坐标(错误)",{offset:new BMap.Size(20,-10)});
          markergg.setLabel(labelgg); //添加GPS label
  */
        //坐标转换完之后的回调函数
        translateCallback = function (data) {
            if (data.status === 0) {

                addAddressLabel(data.points[0], deviceNo);

            }
        }

        setTimeout(function () {
            var convertor = new BMap.Convertor();
            var pointArr = [];
            pointArr.push(ggPoint);
            convertor.translate(pointArr, 1, 5, translateCallback)
        }, 1000);
    } catch (e) {
        log.error("----设置位置错误---")
    }

}

/**
 * websocket stomp连接
 * @param host
 * @param topic
 * @param userName
 * @param token
 * @param tenantId
 * @param clientId
 */
function stompWsConn(host, topic, userName, token, tenantId, clientId) {
    var stompUrl = "http://" + host + "/stomp/websocketJS?token=" + userName + "&tenantId=" + tenantId + "&clientId=" + clientId + "&authorization=" + userName;
    var subsc = "/" + topic;
    if (userName != null && userName != "") {
        subsc += "/" + userName;
    }
    // 建立连接对象(还未发起连接)
    var socket = new SockJS(stompUrl);
    // 获取 STOMP 子协议的客户端对象
    var stompClient = Stomp.over(socket);
    stompClient.debug = function (str) {
        console.log("DEBUG---->" + str);
    };
    // 向服务器发起websocket连接并发送CONNECT帧
    stompClient.connect({name: userName, token: token},
        function connectCallback(frame) {
            // 连接成功时(服务器响应 CONNECTED 帧)的回调方法
            console.log("连接成功");

            console.log("---订阅:" + subsc);
            stompClient.subscribe(subsc, function (res) {

                console.log("----res:" + res);
                var re = JSON.parse(res.body);
                console.log(re);
                var wsObj = re.data;
                //alert(obj.msgStr)
                if (wsObj != null) {
                    //TODO
                    testSetAddres(wsObj);
                }
            });
        },
        function errorCallBack(error) {
            // 连接失败时(服务器响应 ERROR 帧)的回调方法
            console.log("stomp-->连接失败");
        }
    );
}

/**
 * 关闭stomp连接
 * @param stompClient
 */
function wsClose(stompClient) {
    try {
        stompClient.disconnect(function () {
            console.log("--stomp Client close--")
        });
    } catch (e) {
        console.log("--关闭stomp连接异常--");
    }
}

四、效果

       我这里是用postman发送信息到后端,后端通过stomp发送信息到页面,这个见我之前的博文,接口都是用的原先的。
接收位置信息前
postman发送位置信息后
可以看到:

  • 1、websocket stomp带心跳
  • 2、收到信息后利用百度地图API实现了打点
  • 3、label做了自定义设置

五、总结

       因为觉得没有特别大的意义,而且慌着下班回家,所以就直接说总结,随便写写了。

  1. H5获取位置不准确(我明明再软件园,但是跟我获取的位置是沿江大道,还是没有手机的GPS靠谱)
  2. 百度地图的这个获取位置有网络ip、手机基站等几层定位在Geolocation里(有兴趣可以官网看看)
  3. 百度地图个人开发就已经很丰富了,基本够用
  4. stomp带心跳,广播、单点推送都很香
  5. 好久没写前端、js了,有点手生(本尊好几年没写前端了,不得不说万事还是后端为王,前端搞不了的都是后端接手,比如很多前端不愿意做的Excel导入导出、word转PDF等等)

       下班了,走了走了,大家将就看,注释什么的都还是写了的,其实只是香跟大家分享下思路,多技术点的组合运用等等。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>