百度地圖標記在兩點間運動

最近做一個公司內部的班車項目,要求實時獲取班車的位置,一開始想法就是每隔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>

 

  

 

 

 

 

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