如何实现类似百度地图路况效果

2,320 阅读2分钟
分段时速颜色区分

车辆的轨迹回放,实现不同的速度用不同的颜色区分。

数据要求,车辆行驶的轨迹坐标点和记录的时速

{
...
    lat: 29.61643585009648, lng: 106.7462187981366, speed: 25,
    lat: 29.6176659729642, lng: 106.7518686209595, speed: 28,
    lat: 29.62246745254786, lng: 106.7508114037414, speed: 48,
    lat: 29.62246745254786, lng: 106.7508114037414, speed: 41,
...
}
<!DOCTYPE html> 
    <html> 
    <head> 
    <meta content="text/html; charset=utf-8" /> 
    <style type="text/css"> 
        body, html, #allmap {
            width:  100%;
            height:  100%;
            overflow: hidden;
            margin: 0;
        } 
    </style> 
    <script type="text/javascript"  src="http://api.map.baidu.com/api?v=1.4"></script> 
    <title>线路轨迹 </title> 
    </head> 
<body> 
    <div id="allmap"></div> 
</body> 
</html> 
<script type="text/javascript">
    // 获取线路轨迹信息,并且绘制轨迹线路
    function fetchLineTrack(){
        fetch(url).then((data) => {
            if (!data) {
                drawPolyline(data);
            }
        }).catch(ex => ex);
    }
    fetchLineTrack(); 
</script>

根据时速返回不同的颜色值。

function getColor(speed) {
    if (speed > 0 && speed <= 30) {
        return '#3E3EFF';
    } else if (speed > 30 && speed <= 60) {
        return '#00EE00';
    } else if (speed > 60 && speed <= 80) {
        return '#108ee9';
    } else if (speed > 80) {
        return '#FF3626';
    } else {
        return '#3E3EFF';
    }
}

使用BMap的Polyline方法绘制轨迹线路, Polyline是两个点绘制一条线段。我们不断循环这个数组,两个点绘制一条折线,然后去第二个点的速度来标示颜色;

function drawPolyline(data) {
    const arr =[];
    for (let i = 0; i < data.length; i++) {
      const point = new BMap.Point(data[i].lng, data[i].lat);
      arr.push(point);
      if (arr.length > 1) {
        const polyline = new BMap.Polyline([arr[i - 1],        arr[i]],{
        strokeColor: getColor(data[i].speed),
         });
         map.addOverlay(polyline);
       }
    }
}

查看效果

可以看出,折线上有很多小节点,这是为什么呢?我们希望相同的时速颜色是平滑的折线,

因为我们的这个方法是两个坐标一条折线,没有做到如果说是时速相同的相邻节点绘制成一条折线,

改变上面的代码,进行时速相同的相邻节点分段绘制,设置一个开始位,将开始位后面的每一位和开始位比较,如果时速相同,比较下一位,知道遇到不同的时,绘制前面的这一段折线,并且改变开始位;

function drawPolyline(data){
  let startIndex = 1;
  arr.push(new BMap.Point(data[0].lng, data[0].lat));
  for (let i = 1; i < data.length; i++) {
  const point = new BMap.Point(data[i].lng, data[i].lat);
       arr.push(point);
       if (getColor(data[startIndex].speed) !== getColor(data[i].speed)) {
         const polyline = 
        new BMap.Polyline(arr.slice(startIndex - 1, i),{
        strokeColor:getColor(data[startIndex].speed),
        });
        startIndex = i;
        window.omap.addOverlay(polyline);
      } else if ((i + 1) === data.length) {
       const polyline = 
       new BMap.Polyline(arr.slice(startIndex - 1, i + 1), {
    strokeColor: getColor(data[startIndex].speed),
    });
     map.addOverlay(polyline);
     }
  }
}

现在可以看出,没有了小节点。

如果你有更好的处理方式可以留言, 关注微信公众号可查看更多内容。