高德地图JS轨迹(gps坐标点转换并轨迹纠偏)

之前用的百度多,高德感觉差不多


最近又看的下 api , 像获取地图中心坐标, 层级 高德都直接有方法.代码得改改

坐标点转换

var pointsArr =  [
        [116.362209, 39.887487],
        [116.422897, 39.878002],
        [116.372105, 39.90651],
        [116.428945, 39.89663]
    ];
//每次请求做多40个点
AMap.convertFrom(pointsArr, 'gps', function(status, result){
         convertCallback(status, result);
     })
//回调函数
function convertCallback(status, result) {

        if (status=='error') {
            layer.msg("地图坐标转换错误!", {icon: 2});
            return;
        }

        if (result.info === 'ok') {
            var pointArr = result.locations;

            if (0 == pointIndex) { //转换后计算
                maxLng = pointArr[0].lng;
                minLat = pointArr[0].lat;
            }
          }
    }            

轨迹纠偏


/**
* 纠偏请求坐标格式 
* tm参数传入存在问题,第一个元素的tm值为从1970年开始的unix的时间戳, 精确到秒,
* 其余元素的tm值为当前采集点的时间减去第一个元素的采集时间的差值。(一开始直接取成时间戳,纠偏报异常,数据库
* 查询是根据tm排序直接用了rownum替换 
* 直接用rownum 发现了一个纠偏错误的地方, 但是我用实际时间戳减出来的值纠偏一直报错. 最后试2小时吧rownum
* 乘以10 反而纠偏的轨迹是对的了)
* 测试时有个订单的抓取的时间间隔太长, 纠偏无法规划路线
*/
var correctPointArry = [
{"x": 117.635982, "y": 36.696961, "sp": 0, "ag": 128, "tm": 1478031031}
, {"x": 117.635982, "y": 36.696961, "sp": 0, "ag": 128, "tm": 2}
,{"x": 117.635821, "y": 36.697116, "sp": 0, "ag": 15, "tm": 3}
,{"x": 117.635914, "y": 36.697266, "sp": 0, "ag": 15, "tm": 4}
,{"x": 117.635914, "y": 36.697266, "sp": 0, "ag": 15, "tm": 5}
,{"x": 117.611242, "y": 36.67224, "sp": 30, "ag": 284, "tm": 6}
,{"x": 117.606902, "y": 36.673317, "sp": 65, "ag": 287, "tm": 7}
,{"x": 117.601149, "y": 36.674796, "sp": 68, "ag": 288, "tm": 8}
,{"x": 117.595432, "y": 36.676315, "sp": 68, "ag": 287, "tm": 9}
,{"x": 117.589239, "y": 36.677907, "sp": 69, "ag": 287, "tm": 10}
, {"x": 117.5836, "y": 36.679367, "sp": 69, "ag": 287, "tm": 11}
, {"x": 117.578022, "y": 36.680809, "sp": 61, "ag": 287, "tm": 12}
, {"x": 117.573092, "y": 36.682101, "sp": 47, "ag": 287, "tm": 13}]

//一次最多400点求情
graspRoad.driving(correctPointArry,function(error,result) {
            correctCallback(error, result);
        });
 //回调函数
function correctCallback(error, result) {

        if (!error) { //成功时error为null 
            var path2 = [];
            var newPath = result.data.points;
          }
 }

画轨迹

var map = new AMap.Map('container');
var newLine = new AMap.Polyline({
                    path: correctPoints,
                    strokeWeight: 5,
                    strokeOpacity: 0.8,
                    strokeColor: '#009688',
                    showDir: true
                })
 map.add(newLine)

其他

1. 轨迹顺序

ajax获取的数据是带顺序的,转换或纠偏怕数据返回时间不一样,最好分组递归查询再统一画线

2. 线的事件

 newLine.show(); //显示
 newLine.hide(); //隐藏

3. 自定义控件

// 两条线的按钮  设置在最上边 z-index:
<div id='maptitle' style="float: left;padding: 30px;position: absolute;z-index: 998">
      <p class="mapp" onclick="dbonclick()">
           <button id="dbid" type="button" class="layui-btn layui-btn-danger mapbuttion" ></button>&nbsp;&nbsp;
           <strong>司机轨迹</strong>
       </p>
        <p class="mapp" onclick="cbonclick()">
        	<button id="cbid" type="button" class="layui-btn mapbuttion"></button>&nbsp;&nbsp;
        	<strong>车辆轨迹</strong>
         </p>
  </div>
  <div id="container" style="width: 100% ;height: 890px;"></div>

4. 设置中心点

  map.getZoom(); //获取当前地图级别
  map.getCenter(); //获取当前地图中心位置
/*var maxLng = 0; //最大经度
var minLng = 0; //最小经度
var maxLat = 0; //最大纬度
var minLat = 0; //最小纬度
//循环点时获取
if (v.lon > maxLng) maxLng = v.lon;
if (v.lon < minLng) minLng = v.lon;
if (v.lat > maxLat) maxLat = v.lat;
if (v.lat < minLat) minLat = v.lat;
*/

//  (从网上复制)
 /**
  * 设置中心点和层级
  * @param pointslength
  */
  /*
function setZoom(pointslength,poliyType) {
    if (pointslength > 0) {
        var cenLng = (parseFloat(maxLng) + parseFloat(minLng)) / 2;
        var cenLat = (parseFloat(maxLat) + parseFloat(minLat)) / 2;
        var zoom = getZoom(maxLng, minLng, maxLat, minLat);
        map.setCenter([cenLng, cenLat]);//设置中心点
        map.setZoom(zoom); //设置地图层级

        if ('car' == poliyType) {
            carCenterPoint = [cenLng, cenLat];
            carZoom = zoom;
        }else if ('driver' == poliyType) {
            driverCenterPoint = [cenLng, cenLat];
            driverZoom = zoom;
        }
    } else {
        //没有坐标,显示全中国
        map.setCenter([103.388611, 35.563611]);//设置中心点
        map.setZoom(zoom); //设置地图层级
    }
}

 //根据经纬极值计算绽放级别。 (从网上复制)
function getZoom(maxLng, minLng, maxLat, minLat) {
    var zoom = ["50", "100", "200", "500", "1000", "2000", "5000", "10000", "20000", "25000", "50000", "100000", "200000", "500000", "1000000", "2000000"]; // 级别18到3。
    var p1 = new AMap.LngLat(maxLng, maxLat)
    var p2 = new AMap.LngLat(minLng, minLat)
    //计算两个点的距离
    var distance = Math.round(p1.distance(p2)); 
    for (var i = 0, zoomLen = zoom.length; i < zoomLen; i++) {
        if (zoom[i] - distance > 0) {
            let j = 3;
            return 18 - i + j; //之所以会多3,是因为地图范围常常是比例尺距离的10倍以上。所以级别会增加3。
        }
    }
    return 6;
}*/

效果

990点画线截取 效果
在这里插入图片描述 在这里插入图片描述

所有代码

//初始页面中心
var jiananPoint = [117.000923,36.675807];
var map = new AMap.Map('container',{
	resizeEnable: true, //是否监控地图容器尺寸变化
    zoom: 12, //初始地图级别
    center: jiananPoint, //初始地图中心点
    showIndoorMap: false //关闭室内地图**
});
    AMap.plugin([
        'AMap.ToolBar',
    ], function(){
        // 在图面添加工具条控件,工具条控件集成了缩放、平移、定位等功能按钮在内的组合控件
        map.addControl(new AMap.ToolBar({
            // 简易缩放模式,默认为 false
            liteStyle: true
        }));
    });
    var pointsArry = [];
    var lwFlage = false;
    var carLine = null;
    var drvierLine = null;
    var carCenterPoint = null;
    var carZoom = null;
    var driverCenterPoint= null;
    var driverZoom= null;
    var graspRoad  = new AMap.GraspRoad();
    var carPathParam=[] ;
    var carPoints;
    var driverPoints;
    var sIndexs = null;
    //开始结束位置的图标 图片直接从高德下 [高德图标](http://a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png)
  var  startIcon = new AMap.Icon({
        // 图标尺寸
        size: new AMap.Size(25, 34),
        // 图标的取图地址
        image: baseUrl+ 'static/img/amap.png',
        // 图标所用图片大小
        imageSize: new AMap.Size(135, 40),
        // 图标取图偏移量
        imageOffset: new AMap.Pixel(-9, -3)
        }),
    endIcon = new AMap.Icon({
        size: new AMap.Size(25, 34),
        image: baseUrl+ 'static/img/amap.png',
        imageSize: new AMap.Size(135, 40),
        imageOffset: new AMap.Pixel(-95, -3)
        });
    //初始化百度地图
    function initBaiduMap() {
     sIndexs = layer.msg('地图轨迹生成中,请稍后...', {icon: 16, shade: [0.5, '#f5f5f5'], scrollbar: false, offset: 'auto', time: 0});
     
      $.ajax({
          url: baseUrl + "xxx/getMapOrderbyGtm",
          type: "post",
          dataType: "json",
          data: xxxJson,
          async: false,
          success: function (result) {
              var pointMap = result.data;
              carPoints = pointMap['car'];
 				 if (carPoints.length>0) {
                     console.log("车辆轨迹");
                     createCarPoints(carPoints,cardl.vcltn);
                  }else{
                   	 layer.close(sIndexs)
                  }
          },
          error: function (result) {
              $("#container").text("轨迹查询异常! ")
              layer.close(sIndexs)
          }
      });




    }
    //统计车辆坐标点
    function createCarPoints(points,loadWeight) {
        if (points.length > 0) {

            if (parseFloat(loadWeight) / 1000 >= 4.5) {
                lwFlage = true;
                var total = 0; //总记录数
                var groupCount = 0; //每次转十条
                if (points.length % 40 > 0) {
                    groupCount = parseInt(points.length / 40) + 1;
                } else {
                    groupCount = parseInt(points.length / 40);
                }

                for (var i = 0; i < groupCount; i++) { //外层循环,有多少组四十条
                    var pos = []
                    for (var j = 0; j < 40; j++) { //内层循环,每组四十条
                        let pointCount = 0;
                        if (i > 1) {
                            pointCount = (i * 40) + j - 1;
                        } else {
                            pointCount = (i * 40) + j;
                        }

                        if (total < points.length) { //不超过总记录数结束
                            pos.push([
                                points[pointCount].lon,
                                points[pointCount].lat
                            ]);
                        }
                        total++;
                    }
                    pointsArry[i] = pos;
                }

                convertCoordinates(pointsArry);
            } else {

                let pointArr = [];
                $.each(points, function (i, v) {
                    pointArr.push([
                        v.lon, v.lat
                    ]);

                    carPathParam.push({
                        'x':v.lon,
                        'y':v.lat,
                        "sp":v.spd,
                        "ag":v.agl,
                        "tm":v.gtm
                    })
                   
                });

                createAMap(pointArr,'#009688','car');
                map.setCenter(driverCenterPoint);
                map.setZoom(driverZoom);
                layer.close(sIndexs)

            }
        }else{
            layer.close(sIndexs)
        }
    }

    /**
     * 坐标转换
     * @param points
     */
    var converPointsArr = [];
    var pointIndex = 0;
    function convertCoordinates(pointsArr) {

        AMap.convertFrom(pointsArr[pointIndex], 'gps', function(status, result){
            convertCallback(status, result);
        })
    }
    //坐标转换回调函数
    function convertCallback(status, result) {

        if (status=='error') {
            layer.msg("地图坐标转换错误!", {icon: 2});
            return;
        }

        if (result.info === 'ok') {
            var pointArr = result.locations;

          

            $.each(pointArr, function (i, v) {
                converPointsArr.push([
                    v.lng, v.lat
                ]);
               
            });
        }
        pointIndex++;
        if (pointIndex < pointsArry.length) {
            convertCoordinates(pointsArry);
        } else {
            //转换完成
            //组装纠偏数据
            assembleCorrectionData(converPointsArr)
        }
    }
    //坐标轨迹纠偏数据整合
    function assembleCorrectionData(beforeList,) {

        for (let x in beforeList) {

            carPathParam.push({
                "x":beforeList[x][0],
                "y":beforeList[x][1],
                "sp":parseInt(carPoints[x].spd),
                "ag":parseInt(carPoints[x].agl),
                "tm":parseInt(carPoints[x].gtm)
            })

        }

        groupCorrectPoints(carPathParam);

    }

    var correctPointArry = [];
    //分组轨迹纠偏数据点 每次提交做多400个
    function groupCorrectPoints(pointss) {
        var flage=400;
        var groupCount = 0;
        if (pointss.length % flage > 0) {
            groupCount = parseInt(pointss.length / flage) + 1;
        } else {
            groupCount = parseInt(pointss.length / flage);
        }

        for (var i = 0; i < groupCount; i++) {
            let bIndex =i*flage;
            let eIndex =(i+1)*flage-1
            let pos = pointss.slice(bIndex, eIndex);
            pos[0].tm=1478031031;
            correctPointArry[i]=pos;
        }
        console.log(correctPointArry);
        correctLocus(correctPointArry);
    }
    var correctIndex=0 ;
    var correctPoints = [];
    //高德轨迹纠偏请求
    function correctLocus(pointArry) {

        graspRoad.driving(correctPointArry[correctIndex],function(error,result) {
            correctCallback(error, result);
        });
    }
    //轨迹纠偏回调函数
    function correctCallback(error, result) {

        if (error !=null && !error) {
            var path2 = [];
            var newPath = result.data.points;
            for (var i = 0; i < newPath.length; i += 1) {
                correctPoints.push([newPath[i].x, newPath[i].y]);
            }
            correctIndex++

            if (correctIndex < correctPointArry.length) {
                //递归
                correctLocus(correctPointArry);
            } else {
                //画车辆轨迹
            	createAMap(correctPoints,'#009688','car');
            }
        }else{
			console.log(error);
        // console.log('车辆轨迹转换'+error.errdetail+', 不进行纠偏');

        carLine = new AMap.BezierCurve({
            path: converPointsArr,
            isOutline: true,
            outlineColor: '#ffeeff',
            borderWeight: 3,
            strokeColor: "#3366FF",
            strokeOpacity: 1,
            strokeWeight: 6,
            // 线样式还支持 'dashed'
            strokeStyle: "solid",
            // strokeStyle是dashed时有效
            strokeDasharray: [10, 10],
            lineJoin: 'round',
            lineCap: 'round',
            zIndex: 50,
            showDir: true
        })

        carLine.setMap(map)
        // 缩放地图到合适的视野级别
        map.setFitView([carLine])

         cStartMarker = new AMap.Marker({
            position: new AMap.LngLat(converPointsArr[0].lng,converPointsArr[0].lat),
            icon: startIcon,
            offset: new AMap.Pixel(-13, -30),
        });

        // 将 icon 传入 marker
         cEndMarker = new AMap.Marker({
            position: new AMap.LngLat(converPointsArr[converPointsArr.length1].lng,converPointsArr[converPointsArr.length-1].lat),
            icon: endIcon,
            offset: new AMap.Pixel(-13, -30),
        });

        cStartMarker.setMap(map);
        cEndMarker.setMap(map);
        map.setFitView();
        carZoom = map.getZoom(); //获取当前地图级别
        carCenterPoint = map.getCenter(); //获取当前地图中心位置

        layer.close(sIndexs);
		}
    }

    /**
     * 渲染高德地图轨迹
     * @param pointArr
     * @param lineColor
     * @param poliyType
     */
    function createAMap(pointArr,lineColor,poliyType) {


      carLine = new AMap.BezierCurve({
            path: pointArr,
            isOutline: true,
            outlineColor: '#ffeeff',
            borderWeight: 3,
            strokeColor: "#3366FF",
            strokeOpacity: 1,
            strokeWeight: 6,
            // 线样式还支持 'dashed'
            strokeStyle: "solid",
            // strokeStyle是dashed时有效
            strokeDasharray: [10, 10],
            lineJoin: 'round',
            lineCap: 'round',
            zIndex: 50,
            showDir: true
        })

        carLine.setMap(map)
        // 缩放地图到合适的视野级别
        map.setFitView([carLine])

        cStartMarker = new AMap.Marker({
            position: new AMap.LngLat(pointArr[0].lng,pointArr[0].lat),
            icon: startIcon,
            offset: new AMap.Pixel(-13, -30),
        });

        // 将 icon 传入 marker
        cEndMarker = new AMap.Marker({
            position: new AMap.LngLat(pointArr[pointArr.length-1].lng,pointArr[pointArr.length-1].lat),
            icon: endIcon,
            offset: new AMap.Pixel(-13, -30),
        });

        cStartMarker.setMap(map);
        cEndMarker.setMap(map);
        map.setFitView();
        carZoom = map.getZoom(); //获取当前地图级别
        carCenterPoint = map.getCenter(); //获取当前地图中心位置
        layer.close(sIndexs);
    }
	//车辆轨迹图标点击事件
	function cbonclick() {
	
	    if (carLine != null) {
	        let css = $("#cbid").attr("class")
	        if(css.indexOf("layui-btn-primary") !=-1){
	            map.setCenter(carCenterPoint);//设置中心点
	            map.setZoom(carZoom);
	            carLine.show();
	            cStartMarker.show();
	            cEndMarker.show();
	            $("#cbid").attr("class","layui-btn carMapbuttion")
	        }else{
	            carLine.hide();
	            cStartMarker.hide();
	            cEndMarker.hide();
	            $("#cbid").attr("class","layui-btn layui-btn-primary carMapbuttion")
	        }
	    }else {
	        layer.alert('暂无轨迹坐标数据!', {icon: 5});
	    }
	
	}
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
在Vue.js中使用高德地图进行轨迹纠偏,您可以通过以下步骤来实现: 1. 首先,确保您已经引入了高德地图 JavaScript API的SDK文件,您可以在HTML文件中添加以下代码: ```html <script src="https://webapi.amap.com/maps?v=1.4.15&key=您的高德地图API密钥"></script> ``` 2. 创建一个Vue组件,用于显示地图和处理轨迹纠偏的逻辑。在该组件的Vue实例中,您可以使用高德地图的相关API进行操作。 ```javascript <template> <div id="mapContainer"></div> </template> <script> export default { mounted() { // 初始化地图 const map = new AMap.Map('mapContainer', { zoom: 13, center: [经度, 纬度] // 设置地图中心 }); // 获取原始轨迹数据 const originalTrackData = [ [经度1, 纬度1], [经度2, 纬度2], // ... ]; // 创建轨迹纠偏服务实例 const driving = new AMap.Driving({ map: map, panel: 'resultPanel' }); // 调用轨迹纠偏服务的纠偏方法 driving.search(originalTrackData, function(status, result) { if (status === 'complete') { const correctedTrackData = result.routes[0].path; // 获取纠偏后的轨迹数据 console.log('纠偏后的轨迹数据:', correctedTrackData); } else { console.log('轨迹纠偏失败'); } }); } } </script> <style> #mapContainer { width: 100%; height: 400px; } </style> ``` 在上面的代码中,您需要替换以下部分: - `您的高德地图API密钥`:您需要在高德地图开放平台申请API密钥。 - `[经度, 纬度]`:您可以设置地图的中心,用于显示轨迹。 - `originalTrackData`:您的原始轨迹数据,需要替换为实际的经纬度坐标。 这样,当该Vue组件挂载到页面上时,它会显示一个带有纠偏轨迹的地图,并在控制台输出纠偏后的轨迹数据。 希望以上信息对您有所帮助!如有其他问题,请随时提问。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值