全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

百度地图JavascriptApi Marker平滑移动及车头指向行径方向

相信只要是使用百度地图做实时定位服务的朋友都会遇到这个问题,在对坐标位置进行覆盖物展示的时候,会出现由于获取坐标数据时间或者两个坐标点相距过远,导致在视觉上看Marker移动就像“僵尸跳”一样,一蹦一蹦的给客户看分分钟鄙视你到不能自已。另外如果用的是有指向性图标ICON的时候,更会引来吐槽~诶诶诶,你这小车车怎么在这个立交桥转弯的时候车头向着后面呢?怎么搞得嘛你!会不会弄啊你!

所以今天参照百度大大提供的路书开源文件实现下自己的需求,记录一下以便提供参考。

一、覆盖物在获取坐标数据的同时,在坐标点之间平滑的移动

首先,之所以会出现僵尸跳的效果,是因为项目是根据实时坐标数据进行定位,所以存在一个等待新数据的过程,而对于覆盖物的坐标改变就是一个setPosition(BMap.Point)方法而已也就造成了停顿。所以目前暂且解决方案就是:让他这个覆盖物在这个等待的期间找点事情做,不要一下就直接从起点蹦到终点了,慢慢的移动过去。小碎步,平滑的的移动过去~~

怎么移动呢?此时这个事情就可以转化为已知起始点坐标,进行移动覆盖物的这么过程了,说白了就是让他覆盖物在两个点连成的这条线上多执行几次setPosition(BMap.Point),一次步子别迈那么大,只要保证在下次新坐标来之前到达就行了。

那么问题又来了,这两条线上的点我怎么知道呢? 因为获取到的经纬度坐标是球面坐标,所以要先转换为平面坐标

{BMap.Pixel}= map.getMapType().getProjection().lngLatToPoint(BMap.Point);

然后小运算下(参照路书开源文件)

/*
 *缓动效果
 *初始坐标,目标坐标,当前的步长,总的步长
 *@param{BMap.Pixel} initPos 初始平面坐标
 *@parm{BMap.Pixel} targetPos 目标平面坐标
 *@param{number} 当前帧数
 *@param {number} count 总帧数
 */
 this.linear = function (initPos, targetPos, currentCount, count) {
  var b = initPos, c = targetPos - initPos, t = currentCount,
  d = count;
  return c * t / d + b;
 }
   var x = effect(_prvePoint.x, _newPoint.x, currentCount, count),
  y = effect(_prvePoint.y, _newPoint.y, currentCount, count);

经过计算得到的是一个平面坐标pixel(x,y)。然后再将平面坐标转换为球面坐标给Marker进行定位即可。(这些方法在百度类库参考文档中都可以找得到的。魔法门: http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E5%9C%B0%E5%9B%BE%E7%B1%BB%E5%9E%8B%E7%B1%BB)

var pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));

修改覆盖物定位坐标值。当然这个地方要进行多次执行也就需要个setInterval咯  这里面的

me._em._newPointMark.setPosition(pos);

完整方法:

/**
 *小车移动
 *@param {Point} prvePoint 开始坐标(PrvePoint)
 *@param {Point} newPoint 目标点坐标
 *@param {Function} 动画效果
 *@return 无返回值
 */
 this.Move = function (prvePoint, newPoint, effect, setRotation) {
  var me = this,
    //当前帧数
    currentCount = 0,
    //初始坐标
    _prvePoint = me._projection.lngLatToPoint(prvePoint),//将球面坐标转换为平面坐标
    //获取结束点的(x,y)坐标
    _newPoint = me._projection.lngLatToPoint(newPoint),
    //两点之间要循环定位的次数
    count = me._runTime / me._intervalTimer;
    //两点之间匀速移动
    me._intervalFlag = setInterval(function () {
     //两点之间当前帧数大于总帧数的时候,则说明已经完成移动
     if (currentCount >= count) {
     clearInterval(me._intervalFlag);
     } else {
    //动画移动
    currentCount++;//计数
      var x = effect(_prvePoint.x, _newPoint.x, currentCount, count),
       y = effect(_prvePoint.y, _newPoint.y, currentCount, count);
      //根据平面坐标转化为球面坐标
    var pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));
    //设置marker角度(两点之间的距离车的角度保持一致)
     if (currentCount == 1) {
      //转换角度                     setRotation(prvePoint,newPoint, me._em);
     }
      //正在移动
    me._em._newPointMark.setPosition(pos);
   }
    }, me._intervalTimer);
    me._em._prvePoint = newPoint;
 }

值得注意的是,这里关键的就是这个count = me._runTime / me._intervalTimer; 决定了在这两个点之间要走多少个小碎步~~

这个count的由来也得根据自身项目需求计算。

1,通过控制覆盖物移动数据控制动画效果。这种方法就需要通过 速度与每次执行的时间计算得到每次执行前进的距离,然后在与两点之间的距离做商得到要执行的次数。(这种方法呢适合做历史轨迹回放这种,所有坐标信息都已经知道,一个点执行完就跳到下一个坐标,只是通过控制速度来控制动画的展示快慢)

2,通过控制平缓移动过程的总时间与每次执行间隔时间来控制动画效果。此方法就是文中的示例,直接二者做商即可得到要执行的次数。(这种方法适合做实时定位使用,因为下一次定位数据是间隔多少时间后接收,这个使我们可以控制的,所以这个平缓移动的动画过程的总时间也是可以由我们自己控制的) 

二、车头指向行径方向

这个功能其实就是改变覆盖物的旋转角度em._newPointMark.setRotation(number);

只是还是那个原因,因为得到的坐标点数据是球面坐标,所以还是要先进行转为平面坐标才好计算,然后通过三角函数tan#$%^&*( 计算后得到两个点之间的角度值。此部分没有太多个性化的逻辑操作,直接参照百度大大的就行了。

/**
 *在每个点的真实步骤中设置小车转动的角度
 *@param{BMap.Point} curPos 起点
  *@param{BMap.Point} targetPos 终点
 */
  this.setRotation = function (curPos, targetPos, em)
  {
   var me = this;
   var deg = 0;
   curPos = map.pointToPixel(curPos);
   targetPos = map.pointToPixel(targetPos);
   if (targetPos.x != curPos.x) {
    var tan = (targetPos.y - curPos.y) / (targetPos.x - curPos.x),
    atan = Math.atan(tan);
    deg = atan * 360 / (2 * Math.PI);
    if (targetPos.x < curPos.x) {
     deg = -deg + 90 + 90;
    } else {
     deg = -deg;
    }
    em._newPointMark.setRotation(-deg);
   } else {
    var disy = targetPos.y - curPos.y;
    var bias = 0;
    if (disy > 0)
     bias = -1
    else
     bias = 1
    em._newPointMark.setRotation(-bias * 90);
   }
   return;
  }

参考计算方法就得了~~~

值此两个功能的最基础的及计算方法等就这么多,其他的业务逻辑需要的逻辑代码包裹着就是自己的需求实现代码了!

效果图

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# 百度地图  # JavaScriptApI  # nodejs根据ip数组在百度地图中进行定位  # 在网页中插入百度地图的步骤详解  # AngularJS 与百度地图的结合实例  # 百度地图api应用标注地理位置信息(js版)  # android实现百度地图自定义弹出窗口功能  # js 调用百度地图api并在地图上进行打点添加标注  # 百度地图API应用之获取用户的具体位置  # Android下如何使用百度地图sdk  # 百度地图API之本地搜索与范围搜索  # Android百度地图定位后获取周边位置的实现代码  # 两点  # 帧数  # 自己的  # 的是  # 转换为  # 在这个  # 让他  # 也就  # 线上  # 要先  # 转化为  # 这种方法  # 开源  # 坐标点  # 计算方法  # 适合做  # 就行了  # 是因为  # 魔法门  # 就像 


相关文章: 建站之星免费模板:自助建站系统与智能响应式一键生成  在线流程图制作网站手机版,谁能推荐几个好的CG原画资源网站么?  如何在阿里云ECS服务器部署织梦CMS网站?  百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?  ,交易猫的商品怎么发布到网站上去?  建站之星Pro快速搭建教程:模板选择与功能配置指南  如何在香港服务器上快速搭建免备案网站?  建站主机是否等同于虚拟主机?  如何在阿里云部署织梦网站?  如何快速查询网址的建站时间与历史轨迹?  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  杭州银行网站设计制作流程,杭州银行怎么开通认证方式?  微信推文制作网站有哪些,怎么做微信推文,急?  c# 在高并发场景下,委托和接口调用的性能对比  宁波自助建站系统如何快速打造专业企业网站?  教学网站制作软件,学习*后期制作的网站有哪些?  如何高效利用200m空间完成建站?  网站微信制作软件,如何制作微信链接?  建站之星代理费用多少?最新价格详情介绍  如何选择可靠的免备案建站服务器?  西安大型网站制作公司,西安招聘网站最好的是哪个?  建站之星手机一键生成:多端自适应+小程序开发快速建站指南  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  南京网站制作费用,南京远驱官方网站?  C++时间戳转换成日期时间的步骤和示例代码  教程网站设计制作软件,怎么创建自己的一个网站?  建站主机选哪家性价比最高?  如何撰写建站申请书?关键要点有哪些?  平台云上自助建站如何快速打造专业网站?  建站之星多图banner生成与模板自定义指南  云南网站制作公司有哪些,云南最好的招聘网站是哪个?  如何做静态网页,sublimetext3.0制作静态网页?  如何通过服务器快速搭建网站?完整步骤解析  中山网站制作网页,中山新生登记系统登记流程?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  Bpmn 2.0的XML文件怎么画流程图  电商网站制作价格怎么算,网上拍卖流程以及规则?  实惠建站价格推荐:2025年高性价比自助建站套餐解析  如何续费美橙建站之星域名及服务?  c# Task.ConfigureAwait(true) 在什么场景下是必须的  如何通过虚拟主机空间快速建站?  如何在Windows虚拟主机上快速搭建网站?  网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  高性能网站服务器配置指南:安全稳定与高效建站核心方案  制作国外网站的软件,国外有哪些比较优质的网站推荐?  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  如何快速搭建安全的FTP站点?  如何在云虚拟主机上快速搭建个人网站?  如何配置支付宝与微信支付功能? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。