完美实现了单次坐标转换同时绘制轨迹

本文介绍了一种在百度地图上实现车辆行驶轨迹绘制的方法,包括GPS坐标转换、轨迹查询及小车图标动态显示。通过Thymeleaf模板引擎和JavaScript编程,实现了根据日期筛选轨迹数据并实时更新地图的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 实际运行图(1):

 实际运行图(2):

 Html代码:

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

<head>
    <th:block th:include="include :: header('行驶轨迹')" />
    <!--设置容器样式大小,使地图充满整个浏览器窗口:-->
    <style type="text/css">
        /*
        html{height:100%}
        body{height:100%;margin:0px;padding:0px}
        #mapContainer{height:100%}
        */
    </style>

    <!-- 引用百度地图API文件 -->
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=你的密钥">
    </script>
</head>

<body class="gray-bg">

     <div class="container-div">

        <div class="row">

            <div class="col-sm-12 search-collapse">
                <form id="formId">
                    <div class="select-list">
                        <ul>
                            <li class="select-time">
                                <label>行驶日期: </label>
                                <input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginTime]"/>
                            </li>

                            <li>
                                <a class="btn btn-primary btn-rounded btn-sm" onclick="searchTrack()"><i class="fa fa-search"></i>&nbsp;搜索</a>
                                <a class="btn btn-warning btn-rounded btn-sm" onclick="resetTrack()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
                            </li>
                        </ul>
                    </div>
                </form>
            </div>

            <div class="btn-group-sm" id="toolbar" role="group">
            </div>

            <div class="col-sm-12" style="margin-top: 15px; border: solid 1px #fff; border-radius: 6px; box-shadow: 1px 1px 3px rgba(0,0,0,.2);">
                <div id="mapContainer" style="height:500px"></div>
            </div>
        </div>

    </div>


    <th:block th:include="include :: footer" />
</body>
</html>

JS代码:

完美实现了单次坐标转换同时绘制轨迹, 以合理的角度显示小车行驶图标(可以根据日期进行轨迹查询)

<script th:inline="javascript">

        // GPS坐标
        var GpsArr = [[${runTrack}]];
        var GpsArrCp = GpsArr;
        // console.info("GpsArr1");
        // console.info(GpsArr);

        var startTimeInit = [[${startTimeInit}]];
        var endTimeInit = [[${endTimeInit}]];
        var mid = [[${mid}]];

        var map;
        var convertor;
        var carMk; // 小车的mark对象

        var runningFlag = true; // false-画线运行中,true-画线运行结束
        var interval;

        $(function() {
            $("#startTime").val(startTimeInit);
            $("#endTime").val(endTimeInit);
            map = new BMap.Map("mapContainer");
            map.centerAndZoom(new BMap.Point(103.388611, 35.563611), 5); // 中国
            map.enableScrollWheelZoom(); // 开启鼠标滚轮缩放
            convertor = new BMap.Convertor();
            justDoIt(GpsArr);
        });

        // 加入时间段逻辑
        // 搜索
        function  searchTrack() {
            // 如果有setInterval则取消
            if (!runningFlag) { clearInterval(interval); }
            var startTime = $("#startTime").val();
            var endTime = $("#endTime").val();
            // Request URL: http://localhost/clusters/bind/getRunTrack?mid=UWYZYYEU&start=2020-06-02&end=2020-06-02
            $.get(ctx+"clusters/bind/getRunTrack?mid="+mid+"&start="+startTime+"&end="+endTime, function(res){
                // console.info(res);
                if (res.code == 0) {
                    GpsArr = res.data;
                    // console.info("GpsArr2");
                    // console.info(GpsArr);
                    map.clearOverlays(); // 清除地图上的覆盖物
                    map.reset();         // 重新设置地图,恢复地图初始化时的中心点和级别
                    justDoIt(GpsArr);    // 展示行驶轨迹

                } else {
                    alert("暂无数据");
                }
            });
        }

        // 重置
        function  resetTrack() {
            if (!runningFlag) { clearInterval(interval); }
            $("#startTime").val(startTimeInit);
            map.clearOverlays(); // 清除地图上的覆盖物
            map.reset();         // 重新设置地图,恢复地图初始化时的中心点和级别
            justDoIt(GpsArrCp);  // 展示行驶轨迹
        }

        translateCallback = function (data) {
            // console.info(data);
            if(data.status === 0) {
                var bPointsArr = data.points;
                if (bPointsArr.length != 0) {
                    var polyLineArr = [];
                    for (var i = 0 ; i < bPointsArr.length; i++) {
                        polyLineArr.push(new BMap.Point(bPointsArr[i].lng, bPointsArr[i].lat));
                    }
                    var polyline = new BMap.Polyline(polyLineArr, {strokeColor:"red", strokeWeight:7, strokeOpacity:1});
                    // 折线
                    map.addOverlay(polyline);
                    // 小车
                    littleCar(new BMap.Point(bPointsArr[1].lng, bPointsArr[1].lat), map, bPointsArr[1], new BMap.Point(bPointsArr[0].lng, bPointsArr[0].lat))
                }
            }
        }

        translateCallback2 = function (data) {
            if(data.status === 0) {
                var viewPoints = data.points;
                addStartMarker(new BMap.Point(viewPoints[0].lng, viewPoints[0].lat), map);
                var view = map.getViewport(viewPoints);
                var zoom = view.zoom;
                var centerPoint = view.center;
                map.centerAndZoom(centerPoint, zoom);
            }
        }

        translateCallback4  = function (data) {
            if(data.status === 0) {
                var polyLineArr = [];
                var linePoints = data.points;
                for (var i = 0 ; i < linePoints.length; i++) {
                    polyLineArr.push(new BMap.Point(linePoints[i].lng, linePoints[i].lat));
                }
                var polyline = new BMap.Polyline(polyLineArr, {strokeColor:"red", strokeWeight:7, strokeOpacity:1});
                map.addOverlay(polyline);
            }
        }

        // 确定最佳视野范围,同时显示起点图标
        function getBestView(GpsArr) {
            var startPoint = GpsArr[0];
            var endPoint = GpsArr[GpsArr.length-1];
            var viewPointArr = [];
            var startViewPoint  =  new BMap.Point(startPoint.lng, startPoint.lat);
            var endViewPoint  =  new BMap.Point(endPoint.lng, endPoint.lat);
            viewPointArr.push(startViewPoint);
            viewPointArr.push(endViewPoint);
            // var convertor = new BMap.Convertor();
            convertor.translate(viewPointArr, 1, 5, translateCallback2);
        }

        // 画轨迹
        function drawTrack(GpsArr) { // GpsArr可用=371
            runningFlag = false; // 画线运行中
            var endNode = GpsArr.length % 2 == 0 ? GpsArr.length : GpsArr.length - 1 ;  // 判断奇偶(是否能整除2)
            var i = 0;
            // 每200毫秒(0.2秒)执行1次 drowLine画线
            interval = setInterval(function () {
                if (i  >=  endNode) {
                    map.removeOverlay(carMk);
                    showEndMarker(GpsArr);   // 显示终点图标
                    clearInterval(interval); // clearInterval()方法 可取消由setInterval() 设置的timeout
                    runningFlag = true;      // 画线运行结束
                    return;
                }
                // 画线调用 (参数:坐标点1、坐标点2)
                drowLine(GpsArr[i], GpsArr[i+1]);
                i = i + 1;
                // console.info("i="+i); // i=370
            }, 100);
        }

        // 画线
        function drowLine(gpsPointObj, gpsPointObjNext) {
            var gpsPointArr = new BMap.Point(gpsPointObj.lng ,gpsPointObj.lat);
            var gpsPointArrNext = new BMap.Point(gpsPointObjNext.lng ,gpsPointObjNext.lat);
            var pointArr = [];
            pointArr.push(gpsPointArr);
            pointArr.push(gpsPointArrNext);
            convertor.translate(pointArr, 1, 5, translateCallback);
        }

        // 添加起点图标
        function addStartMarker(point, mapInit) {
            var myIcon = new BMap.Icon("/img/startMap.png", new BMap.Size(45,45),{
                anchor: new BMap.Size(20, 45),
                imageSize:new BMap.Size(40, 45)
            });
            window.marker = new BMap.Marker(point,{icon:myIcon});
            mapInit.addOverlay(marker);
        }

        translateCallback3 = function (data) {
            if(data.status === 0) {
                var viewPoints = data.points;
                addEndMarker(new BMap.Point(viewPoints[0].lng, viewPoints[0].lat), map);
            }
        }

        // 显示终点图标
        function showEndMarker(GpsArr) {
            var endPoint = GpsArr[GpsArr.length-1];
            var endViewPoint  =  new BMap.Point(endPoint.lng, endPoint.lat);
            var endViewPointArr = [];
            endViewPointArr.push(endViewPoint);
            convertor.translate(endViewPointArr, 1, 5, translateCallback3);
        }

        // 添加终点图标
        function addEndMarker(point, mapInit) {
            var myIcon = new BMap.Icon("/img/endMap.png", new BMap.Size(45,45),{
                anchor: new BMap.Size(20, 45),
                imageSize:new BMap.Size(40, 45)
            });
            window.marker = new BMap.Marker(point,{icon:myIcon});
            mapInit.addOverlay(marker);
        }

        // 小车图标
        var drivingPoint = new BMap.Icon('/img/carMap.png', new BMap.Size(50,24), {
            anchor : new BMap.Size(27, 13),
            imageSize:new BMap.Size(52,26)
        });

        // 小车行驶
        function  littleCar(point, mapInit, trackUnit, prePoint) {
            // 先判断第一次进来的时候这个值有没有定义,有的话就清除掉上一次的。
            // 然后在进行画图标。第一次进来时候没有定义也就不走这块,直接进行画图标
            if(carMk){
                mapInit.removeOverlay(carMk);
            }
            carMk = new BMap.Marker(point,{icon:drivingPoint}); // 创建标注
            carMk.setRotation(trackUnit.route);                 // trackUnit.route
            carMk.setRotation(getAngle(point,prePoint)+90);     // 旋转的角度
            mapInit.addOverlay(carMk);                          // 把标注添加到地图中
        }

        // 获得角度的方法
        function getAngle(n, next){
            var ret;
            var w1 = n.lat/180 * Math.PI;
            var j1 = n.lng/180 * Math.PI;

            var w2 = next.lat/180 * Math.PI;
            var j2 = next.lng/180 * Math.PI;

            ret = 4 * Math.pow(Math.sin((w1 - w2) / 2), 2) - Math.pow(Math.sin((j1 - j2) / 2) * (Math.cos(w1) - Math.cos(w2)), 2);
            ret = Math.sqrt(ret);

            // var temp = Math.sin(Math.abs(j1 - j2) / 2) * (Math.cos(w1) + Math.cos(w2));
            var temp = Math.sin((j1 - j2) / 2) * (Math.cos(w1) + Math.cos(w2));
            // console.log(temp);
            ret = ret/temp;

            ret = Math.atan(ret) / Math.PI * 180 ;
            ret += 90;

            // 这里用如此臃肿的if..else是为了判定追踪单个点的具体情况,从而调整ret的值
            if(j1-j2 < 0){
                // console.log('j1<j2')
                if(w1-w2 < 0){
                    // console.log('w1<w2')
                    ret;
                }else{
                    // console.log('w1>w2')
                    ret = -ret+180;
                }
            }else{
                // console.log('j1>j2')
                if(w1-w2 < 0){
                    // console.log('w1<w2')
                    ret = 180+ret;
                }else{
                    // console.log('w1>w2')
                    ret = -ret;
                }
            }
            return ret ;
        }

        // 展示行驶轨迹
        function  justDoIt(GpsArr) {
            if(GpsArr == undefined || GpsArr == null || GpsArr.length == 0) { alert("暂无数据"); return ;}
            getBestView(GpsArr);    // 视野范围,显示起点图标
            drawTrack(GpsArr);      // 转换坐标同时绘制行驶轨迹
        }
</script>

百度map,百度map API,百度地图 实现百度地图动态搜索、静态地图动态插入 mygw@163.com js 内容如下: /** 加载地图的主控类 */ var MapControl={ staticWith : 512,//链接静态图宽度 staticHeight : 320,//链接静态图的高度 container : 'mapcontainer',//显示map的节点id defzoom:12,//默认缩放比例 map : '', marker : '', city : '深圳', infoWinContent : '请移动此标记到您的婚礼地点位置!', /** 提示信息窗内容 */ infoOpts : { width : 100, // 信息窗口宽度 height: 50, // 信息窗口高度 title : "提示:" // 信息窗口标题 }, /** *默认显示窗口 */ defWindow : function(){ this.map = new BMap.Map(this.container); this.map.centerAndZoom(this.city,this.defzoom); // 通过城市名初始化地图 this.map.addEventListener("load", function(){ // 初始化方法执行完成后即可获取地图中心点信息 MapControl.marker = new BMap.Marker( this.getCenter()); // 创建标注 this.addOverlay(MapControl.marker ); // 将标注添加到地图中 MapControl.marker.enableDragging(); var infoWindow = new BMap.InfoWindow(MapControl.infoWinContent, MapControl.infoOpts); // 创建信息窗口对象 MapControl.marker.addEventListener("mouseover", function(){ this.openInfoWindow(infoWindow); // 打开信息窗口 }) MapControl.marker.addEventListener("mouseout", function(){ this.closeInfoWindow(); // 打开信息窗口 }) }) //map 增加操作 this.map.addControl(new BMap.NavigationControl()); this.map.addControl(new BMap.ScaleControl()); this.map.addControl(new BMap.OverviewMapControl()); this.map.addControl(new BMap.MapTypeControl()); }, /** * 搜索地址 */ search : function(address){ if(this.map=='' || this.map == 'undefined' || address=='' ){ return ; } this.city=address; this.defWindow(); }, /** * 获取静态图片地址 */ getStaticMap : function(){ if(this.map=='' || this.map == 'undefined' || this.marker=='' ){ return ; } var center=this.map.getCenter().lng+','+this.map.getCenter().lat; var markers= this.marker.getPosition().lng+','+this.marker.get
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值