百度地图标记在两点间运动

最近做一个公司内部的班车项目,要求实时获取班车的位置,一开始想法就是每隔5s获取班车位置,然后更新班车marker的座标,做完之后发现,这个班车在地图上是跳动的,需求部门说班车在瞬移~~~^_^~~~,要做连续的运动,就需要让班车在这两点直接做运动效果。缩短请求的间隔时间,很明显不合理。那就去官方文档找相应的marker运动api。找了一通。目前貌似没有直接这样的方法,面向百度编程的思路,又怎能难倒一个程序员呢

废话不多数,就总结一下网上查到的解决方案。做一个简单的demo

1.获取地图上的两个点(开始位置,结束位置)

2.讲两个点转化成平面座标系的点(地图上的是球座标系点)

3.运用数学只是在两点间的直线上画若干个等距离小点,获取他们的点座标

4.转换成地图座标,隔100毫秒设置新的marker位置

以下就是我的一个测试demo,一步步来讲解一下

第一步,生成地图创建两点,一个代表起点,一个代表终点,为了只管直接两个点都在座标地图上标记出来

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
    </style>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=1PrtI9ftPfLUXbTNCFSL3hOQ6hHmV1R6"></script>
    <title>设置点的新图标</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
  // 百度地图API功能
  var map = new BMap.Map("allmap");
  var point = new BMap.Point(116.404, 39.915);
  map.centerAndZoom(point, 13);
  map.addControl(new BMap.NavigationControl());
  
  var pointstart = new BMap.Point(116.417, 39.909);
  var pointend = new BMap.Point(116.427, 39.919);
  var markerstart = new BMap.Marker(pointstart);  // 创建标注
  var markerend = new BMap.Marker(pointend);  // 创建标注
  map.addOverlay(markerstart);              // 将标注添加到地图中
  map.addOverlay(markerend);              // 将标注添加到地图中


</script>

直接复制实现以下效果

第二步:根据这两个点的的球座标获取平面座标

调用百度地图 map.getMapType().getProjection().lngLatToPoint(point) 方法

  _startPoint = map.getMapType().getProjection().lngLatToPoint(pointstart);
  _endPoint = map.getMapType().getProjection().lngLatToPoint(pointend);
  console.log(_startPoint);
  console.log(_endPoint);

打印两个点的平面座标如下

 第三部:获取平面上两个点之间的若干个点的座标

 以50个为例,间隔相等,咱们分别算一下x和y的位置就可以 用x1+((x2-x1)/50)m  m就是第几个点

 //xoy1  x1 或者y1,  xoy2 x2或者y2 ,num 分割多少个点,m 第几个点
  function getpointitem(xoy1,xoy2,num,m) {
      return (xoy2-xoy1)/num*m +xoy1
  }
  var num = 50;
  var points = [];
  for (var i=0;i<num;i++){
    var x = getpointitem(_startPoint.x,_endPoint.x,num,i);
    var y = getpointitem(_startPoint.y,_endPoint.y,num,i);
    points.push({x:x,y:y});
  }
  console.log(points);

 得到如下的点集合

第四部转换成地图座标 每100毫秒更新一个点位置; 

转换地理座标调用百度地图的map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));方法

更新marker位置调用marker.setPosition(point);方法

因为里面需要用的 间时函数,注意for循环声明的 var i 会指向循环的最后一个,还是用一个全局的flag来进行计数

  movepoint(_startPoint,_endPoint,markerstart,100,50);
  // statpoint,开始点
  // endpoint,结束点
  // marker, 移动的marker
  // timer, 间隔时间
  // count  计数点
  function movepoint(statpoint,endpoint,marker,timer,count) {
      var currentCount = 0;
      //两点之间匀速移动
      var intervalFlag = setInterval(function() {
        //两点之间当前帧数大于总帧数的时候,则说明已经完成移动
        if (currentCount >= count) {
          clearInterval(intervalFlag);
        } else {
          //动画移动
          currentCount++;//计数
          var x = getpointitem(statpoint.x, endpoint.x, count, currentCount);
          var y = getpointitem(statpoint.y, endpoint.y, count, currentCount);
          //根据平面座标转化为球面座标
          var pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));
          console.log(pos)
          //更新座标点
          marker.setPosition(pos);
        }
      }, timer);
    }

整体效果如下:

 

整体代码如下复制即可使用

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
    </style>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=1PrtI9ftPfLUXbTNCFSL3hOQ6hHmV1R6"></script>
    <title>设置点的新图标</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
  // 百度地图API功能
  var map = new BMap.Map("allmap");
  var point = new BMap.Point(116.404, 39.915);
  map.centerAndZoom(point, 13);
  map.addControl(new BMap.NavigationControl());

  var pointstart = new BMap.Point(116.417, 39.909);
  var pointend = new BMap.Point(116.427, 39.919);
  var markerstart = new BMap.Marker(pointstart);  // 创建标注
  var markerend = new BMap.Marker(pointend);  // 创建标注
  map.addOverlay(markerstart);              // 将标注添加到地图中
  map.addOverlay(markerend);              // 将标注添加到地图中

  _startPoint = map.getMapType().getProjection().lngLatToPoint(pointstart);
  _endPoint = map.getMapType().getProjection().lngLatToPoint(pointend);
  console.log(_startPoint);
  console.log(_endPoint);
  //xoy1  x1 或者y1,  xoy2 x2或者y2 ,num 分割多少个点,m 第几个点
  function getpointitem(xoy1,xoy2,num,m) {
      return (xoy2-xoy1)/num*m +xoy1
  }
  
  movepoint(_startPoint,_endPoint,markerstart,100,50);
  // statpoint,开始点
  // endpoint,结束点
  // marker, 移动的marker
  // timer, 间隔时间
  // count  计数点
  function movepoint(statpoint,endpoint,marker,timer,count) {
      var currentCount = 0;
      //两点之间匀速移动
      var intervalFlag = setInterval(function() {
        //两点之间当前帧数大于总帧数的时候,则说明已经完成移动
        if (currentCount >= count) {
          clearInterval(intervalFlag);
        } else {
          //动画移动
          currentCount++;//计数
          var x = getpointitem(statpoint.x, endpoint.x, count, currentCount);
          var y = getpointitem(statpoint.y, endpoint.y, count, currentCount);
          //根据平面座标转化为球面座标
          var pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));
          console.log(pos)
          //更新座标点
          marker.setPosition(pos);
        }
      }, timer);
    }

  

</script>

 

  

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章