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

文章目录

  • 坐标点转换
  • 轨迹纠偏
  • 画轨迹
  • 其他
    • 1. 轨迹顺序
    • 2. 线的事件
    • 3. 自定义控件
    • 4. 设置中心点
  • 效果
  • 所有代码

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

坐标点转换

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>  
           <strong>司机轨迹strong>
       p>
        <p class="mapp" onclick="cbonclick()">
        	<button id="cbid" type="button" class="layui-btn mapbuttion">button>  
        	<strong>车辆轨迹strong>
         p>
  div>
  <div id="container" style="width: 100% ;height: 890px;">div>

4. 设置中心点

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点画线截取 效果
高德地图JS轨迹(gps坐标点转换并轨迹纠偏)_第1张图片 高德地图JS轨迹(gps坐标点转换并轨迹纠偏)_第2张图片

所有代码

var map = new AMap.Map('container');
    AMap.plugin([
        'AMap.ToolBar',
    ], function(){
        // 在图面添加工具条控件,工具条控件集成了缩放、平移、定位等功能按钮在内的组合控件
        map.addControl(new AMap.ToolBar({
            // 简易缩放模式,默认为 false
            liteStyle: true
        }));
    });
    var pointsArry = [];
    var maxLng = 0;
    var minLng = 0;
    var maxLat = 0;
    var minLat = 0;
    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;
    //初始化百度地图
    function initBaiduMap() {
     sIndexs = layer.msg('地图轨迹生成中,请稍后...', {icon: 16, shade: [0.5, '#f5f5f5'], scrollbar: false, offset: 'auto', time: 0});
     
      $.ajax({
          url: baseUrl + "pmslocusinfo/getMapOrderbyGtm",
          type: "post",
          dataType: "json",
          data: {waybillNum: '${param.waybillNum}', carNum: '${pwi.carNum}'},
          async: false,
          success: function (result) {
              var pointMap = result.data;
              carPoints = pointMap['car'];
              driverPoints = pointMap['driver']; //司机是app端提交的高德系坐标不需要处理

              createDriverPoints(driverPoints);
              createCarPoints(carPoints,cardl.loadWeight);
          },
          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;

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

            $.each(pointArr, function (i, v) {
                converPointsArr.push([
                    v.lng, v.lat
                ]);
                if (v.lng >= maxLng) maxLng = v.lng;
                if (v.lng <= minLng) minLng = v.lng;
                if (v.lat >= maxLat) maxLat = v.lat;
                if (v.lat <= minLat) minLat = 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) {
            var path2 = [];
            var newPath = result.data.points;

            if (0 == correctIndex) { //转换后计算
                maxLng = newPath[0].x;
                minLng = newPath[0].x;
                maxLat = newPath[0].y;
                minLat = newPath[0].y;
            }



            for (var i = 0; i < newPath.length; i += 1) {
                correctPoints.push([newPath[i].x, newPath[i].y]);

                if (newPath[i].x > maxLng) maxLng = newPath[i].x;
                if (newPath[i].x < minLng) minLng = newPath[i].x;
                if (newPath[i].y > maxLat) maxLat = newPath[i].y;
                if (newPath[i].y < minLat) minLat = newPath[i].y;
            }
            correctIndex++

            if (correctIndex < correctPointArry.length) {
                //递归
                correctLocus(correctPointArry);
            } else {
                //画车辆轨迹
                var newLine = new AMap.Polyline({
                    path: correctPoints,
                    strokeWeight: 8,
                    strokeOpacity: 0.8,
                    strokeColor: '#009688',
                    showDir: true
                })
                map.add(newLine)
                map.setFitView()
                setZoom(correctPoints.length,'car');
                carLine=newLine;

                map.setCenter(driverCenterPoint);
                map.setZoom(driverZoom);
                layer.close(sIndexs)
            }
        }
    }

    /**
     * 渲染司机轨迹
     * @param points
     */
    function createDriverPoints(points) {

        if (points.length > 0) {
            maxLng = points[0].lon;
            minLng = points[0].lon;
            maxLat = points[0].lat;
            minLat = points[0].lat;

            let pointArr = [];
            $.each(points, function (i, v) {
                let point=[]
                pointArr.push([
                    v.lon, v.lat
                ]);
                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;
            });

            createAMap(pointArr,"#FF5722",'driver');

        }
    }

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


        setZoom(pointArr.length,poliyType);

        if ('car' == poliyType) {

            //carLine=polyline;
        }else if ('driver' == poliyType) {
            var polyline = new AMap.Polyline({
                path: pointArr,          //设置线覆盖物路径
                strokeColor: lineColor, //线颜色
                strokeWeight: 8,        //线宽
                strokeStyle: "solid",   //线样式
                showDir: true,
                strokeOpacity:0.8,
            });
            drvierLine = polyline;
            map.add(polyline);
        }

        layer.close(sIndexs)
    }

    //  (从网上复制)
    /**
     * 设置中心点和层级
     * @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;
    }

    //司机轨迹图标点击事件
    function dbonclick() {

        if (drvierLine != null) {
            let css = $("#dbid").attr("class");

            if (css.indexOf("layui-btn-primary") != -1) {
                map.setCenter(driverCenterPoint);//设置中心点
                map.setZoom(driverZoom);
                drvierLine.show();
                $("#dbid").attr("class", "layui-btn layui-btn-danger mapbuttion")
            } else {
                drvierLine.hide();
                $("#dbid").attr("class", "layui-btn layui-btn-primary mapbuttion")
            }
        } else {
            layer.alert('暂无轨迹坐标数据!', {icon: 5});
        }
    }
    //车辆轨迹图标点击事件
    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();
                $("#cbid").attr("class","layui-btn mapbuttion")
            }else{
                carLine.hide();
                $("#cbid").attr("class","layui-btn layui-btn-primary mapbuttion")
            }
        }else {
            layer.alert('暂无轨迹坐标数据!', {icon: 5});
        }

    }

你可能感兴趣的:(地图)