百度地图实现小车规划路线后平滑移动功能

文章目的

项目开发所需,所以结合百度地图提供的小车平滑轨迹移动,自己写的demo

实现效果

代码下载

下载链接

下面是实现的关键步骤

集成百度地图

怎么集成自然是看百度地图开发平台提供的文档。

文档连接

规划线路

看百度地图的文档,写一个规划线路的工具类(驾车的)

package com.wzhx.car_smooth_move_demo.utils;
import android.util.Log;
import com.baidu.mapapi.search.route.BikingRouteResult;
import com.baidu.mapapi.search.route.DrivingRoutePlanOption;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.baidu.mapapi.search.route.IndoorRouteResult;
import com.baidu.mapapi.search.route.MassTransitRouteResult;
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;
import com.baidu.mapapi.search.route.PlanNode;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.baidu.mapapi.search.route.TransitRouteResult;
import com.baidu.mapapi.search.route.WalkingRouteResult;
import com.wzhx.car_smooth_move_demo.listener.OnGetDrivingResultListener;
public class RoutePlanUtil {
  private RoutePlanSearch mRoutePlanSearch = RoutePlanSearch.newInstance();
  private OnGetDrivingResultListener getDrivingResultListener;
  private OnGetRoutePlanResultListener getRoutePlanResultListener = new OnGetRoutePlanResultListener() {
    @Override
    public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
    }
    @Override
    public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
    }
    @Override
    public void onGetMassTransitRouteResult(MassTransitRouteResult massTransitRouteResult) {
    }
    @Override
    public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
      Log.e("测试", drivingRouteResult.error + ":" + drivingRouteResult.status);
      getDrivingResultListener.onSuccess(drivingRouteResult);
    }
    @Override
    public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {
    }
    @Override
    public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {
    }
  };
  public RoutePlanUtil(OnGetDrivingResultListener getDrivingResultListener) {
    this.getDrivingResultListener = getDrivingResultListener;
    this.mRoutePlanSearch.setOnGetRoutePlanResultListener(this.getRoutePlanResultListener);
  }
  public void routePlan(PlanNode startNode, PlanNode endNode){
    mRoutePlanSearch.drivingSearch((new DrivingRoutePlanOption())
        .from(startNode).to(endNode)
        .policy(DrivingRoutePlanOption.DrivingPolicy.ECAR_TIME_FIRST)
        .trafficPolicy(DrivingRoutePlanOption.DrivingTrafficPolicy.ROUTE_PATH_AND_TRAFFIC));
  }
}

规划线路后需要将实时路况索引保存,为后面画图需要

// 设置路段实时路况索引
        List<DrivingRouteLine.DrivingStep> allStep = selectedRouteLine.getAllStep();
        mTrafficTextureIndexList.clear();
        for (int j = 0; j < allStep.size(); j++) {
          if (allStep.get(j).getTrafficList() != null && allStep.get(j).getTrafficList().length > 0) {
            for (int k = 0; k < allStep.get(j).getTrafficList().length; k++) {
              mTrafficTextureIndexList.add(allStep.get(j).getTrafficList()[k]);
            }
          }
        }

要将路线规划的路线上的路段再细分(切割),这样小车移动才会平滑

/**
   * 将规划好的路线点进行截取
   * 参考百度给的小车平滑轨迹移动demo实现。(循环的算法不太懂)
   * @param routeLine
   * @param distance
   * @return
   */
  private ArrayList<LatLng> divideRouteLine(ArrayList<LatLng> routeLine, double distance) {
    // 截取后的路线点的结果集
    ArrayList<LatLng> result = new ArrayList<>();
    mNewTrafficTextureIndexList.clear();
    for (int i = 0; i < routeLine.size() - 1; i++) {
      final LatLng startPoint = routeLine.get(i);
      final LatLng endPoint = routeLine.get(i + 1);
      double slope = getSlope(startPoint, endPoint);
      // 是不是正向的标示
      boolean isYReverse = (startPoint.latitude > endPoint.latitude);
      boolean isXReverse = (startPoint.longitude > endPoint.longitude);
      double intercept = getInterception(slope, startPoint);
      double xMoveDistance = isXReverse ? getXMoveDistance(slope, distance) :
          -1 * getXMoveDistance(slope, distance);
      double yMoveDistance = isYReverse ? getYMoveDistance(slope, distance) :
          -1 * getYMoveDistance(slope, distance);
      ArrayList<LatLng> temp1 = new ArrayList<>();
      for (double j = startPoint.latitude, k = startPoint.longitude;
         !((j > endPoint.latitude) ^ isYReverse) && !((k > endPoint.longitude) ^ isXReverse); ) {
        LatLng latLng = null;
        if (slope == Double.MAX_VALUE) {
          latLng = new LatLng(j, k);
          j = j - yMoveDistance;
        } else if (slope == 0.0) {
          latLng = new LatLng(j, k - xMoveDistance);
          k = k - xMoveDistance;
        } else {
          latLng = new LatLng(j, (j - intercept) / slope);
          j = j - yMoveDistance;
        }
        final LatLng finalLatLng = latLng;
        if (finalLatLng.latitude == 0 && finalLatLng.longitude == 0) {
          continue;
        }
        mNewTrafficTextureIndexList.add(mTrafficTextureIndexList.get(i));
        temp1.add(finalLatLng);
      }
      result.addAll(temp1);
      if (i == routeLine.size() - 2) {
        result.add(endPoint); // 终点
      }
    }
    return result;
  }

最后是开启子线程,对小车状态进行更新(车头方向和小车位置)

/**
   * 循环进行移动逻辑
   */
  public void moveLooper() {
    moveThread = new Thread() {
      public void run() {
        Thread thisThread = Thread.currentThread();
        while (!exit) {
          for (int i = 0; i < latLngs.size() - 1; ) {
            if (exit) {
              break;
            }
            for (int p = 0; p < latLngs.size() - 1; p++) {
              // 这是更新索引的条件,这里总是为true
              // 实际情况可以是:当前误差小于5米 DistanceUtil.getDistance(mCurrentLatLng, latLngs.get(p)) <= 5)
              // mCurrentLatLng 这个小车的当前位置得自行获取得到
              if (true) {
//               实际情况的索引更新 mIndex = p;
                mIndex++; // 模拟就是每次加1
                runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                    Toast.makeText(mContext, "当前索引:" + mIndex, Toast.LENGTH_SHORT).show();
                  }
                });
                break;
              }
            }

            // 改变循环条件
            i = mIndex + 1;

            if (mIndex >= latLngs.size() - 1) {
              exit = true;
              break;
            }

            // 擦除走过的路线
            int len = mNewTrafficTextureIndexList.subList(mIndex, mNewTrafficTextureIndexList.size()).size();
            Integer[] integers = mNewTrafficTextureIndexList.subList(mIndex, mNewTrafficTextureIndexList.size()).toArray(new Integer[len]);
            int[] index = new int[integers.length];
            for (int x = 0; x < integers.length; x++) {
              index[x] = integers[x];
            }
            if (index.length > 0) {
              mPolyline.setIndexs(index);
              mPolyline.setPoints(latLngs.subList(mIndex, latLngs.size()));
            }

            // 这里是小车的当前点和下一个点,用于确定车头方向
            final LatLng startPoint = latLngs.get(mIndex);
            final LatLng endPoint = latLngs.get(mIndex + 1);

            mHandler.post(new Runnable() {
              @Override
              public void run() {
                // 更新小车的位置和车头的角度
                if (mMapView == null) {
                  return;
                }
                mMoveMarker.setPosition(startPoint);
                mMoveMarker.setRotate((float) getAngle(startPoint,
                    endPoint));
              }
            });

            try {
              // 控制线程更新时间间隔
              thisThread.sleep(TIME_INTERVAL);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }
      }
    };
    // 启动线程
    moveThread.start();
  }
(0)

相关推荐

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

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

  • Android百度定位导航之基于百度地图移动获取位置和自动定位

    一.问题描述 使用百度地图实现如图所示应用,首先自动定位当前我起始位置(小圆点位置),并跟随移动不断自动定位我的当前位置 百度Api不同版本使用会有些差异,本例中加入lib如下: 二.编写MyApplication类 public class MyApplication extends Application { static MyApplication myApplication; BMapManager mBMapManager = null; String mStrKey = "7ZfuR

  • 百度地图实现小车规划路线后平滑移动功能

    文章目的 项目开发所需,所以结合百度地图提供的小车平滑轨迹移动,自己写的demo 实现效果 代码下载 下载链接 下面是实现的关键步骤 集成百度地图 怎么集成自然是看百度地图开发平台提供的文档. 文档连接 规划线路 看百度地图的文档,写一个规划线路的工具类(驾车的) package com.wzhx.car_smooth_move_demo.utils; import android.util.Log; import com.baidu.mapapi.search.route.BikingRout

  • JS开发中百度地图+城市联动实现实时触发查询地址功能

    缘由: 由于项目需要实现一个根据省市区+详细地址的路径进行查询地址的功能. 所用技术:百度地图API+jQuery 实现步骤: 1.省市区三级联动(ps:已经忘记这个小插件的出处的) 引入area.js /* * 全国三级城市联动 js版 */ function Dsy(){ this.Items = {}; } Dsy.prototype.add = function(id,iArray){ this.Items[id] = iArray; } Dsy.prototype.Exists = f

  • 利用百度地图Android sdk高仿微信发送位置功能及遇到的问题

    接触了百度地图开发平台半个月了,这2天试着模仿了微信给好友发送位置功能,对百度地图的操作能力又上了一个台阶 我在实现这个功能的时候,遇到一些困难,可能也是别人将会遇到的困难,特在此列出 1.在微信发送功能中,不管用户如何拖拽地图,总有个覆盖物固定了MapView中央,怎么实现? 其实这很容易实现,只要MapView的布局文件中,将一个ImageView覆盖在MapView的中央,就能够实现不管用户如何拖拽地图,覆盖物(ImageView)总固定总MapView中央 2.如何获取MapView中央

  • 基于百度地图实现产品销售的单位位置查看功能设计与实现

    1.描述 本人最近参与基于MVC5+EF6+ Bootstrap3的食品安全监管系统设计.开发.先前感觉百度地图很神秘的样子.高大上的样子,设计.开发过程遇到些问题,经查看园子高手指点.示例摸索实践,终将百度地图嵌入系统.为感谢各位朋友的帮助,今有空,将基于百度地图实现产品销售的单位位置查看功能,分享给大家.不当之处,欢迎指正. 2.产品生产批次查询 查看单位产品生产批次信息,根据产品生产批次查看,产品销售单位情况. 效果图如下: 3.产品销售地图 根据选择的产品生产批次信息,查询统计产品销售到

  • Android百度地图自定义公交路线导航

    一.问题描述 基于百度地图实现检索指定城市指定公交的交通路线图,效果如图所示 二.通用组件Application类,主要创建并初始化BMapManager public class App extends Application { static App mDemoApp; //百度MapAPI的管理类 public BMapManager mBMapMan = null; // 授权Key // 申请地址:http://dev.baidu.com/wiki/static/imap/key/ p

  • Android百度地图定位后获取周边位置的实现代码

    本文实例讲解Android百度地图定位后获取周边位置的实现代码,分享给大家供大家参考,具体内容如下 效果图: 具体代码: 1.布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical&q

  • iOS实现百度地图拖拽后更新位置以及反编码

    前言 最近在开发中遇到了百度地图的开发,功能类似于微信中的发送位置,拖拽从新定位,以及反编码,列表附近的位置.分析出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 效果图: 百度地图拖拽更新位置.gif 实现思路 思路就是将一个UIImageView固定在地图中间,每次更新位置,给UIImageView添加动画即可. 代码如下: #import "FTBasicController.h" typedef void (^SelectBlock) (NSString *addr

  • 详解Javascript百度地图接口开发文档中的类和方法

    JavaScript API v2.0介绍 百度地图JavaScript API是一套由JavaScript语言编写的应用程序接口,它能够帮助您在网站中构建功能丰富.交互性强的地图应用,包含了构建地图基本功能的各种接口,提供了诸如本地搜索.路线规划等数据服务. 该套API免费对外开放.自v1.5版本起,您需先申请密钥(ak)才可使用,接口(除发送短信功能外)无使用次数限制. JavaScript API首家支持Https,如需要申请Https服务,请您认证企业信息,成为企业认证用户后,https

  • Android 百度地图POI搜索功能实例代码

    在没介绍正文之前先给大家说下poi是什么意思. 由于工作的关系,经常在文件中会看到POI这三个字母的缩写,但是一直对POI的概念和含义没有很详细的去研究其背后代表的意思.今天下班之前,又看到了POI这三个字母,决定认认真真的搜索一些POI具体的含义. POI是英文的缩写,原来的单词是point of interest, 直译成中文就是兴趣点的意思.兴趣点这个词最早来自于导航地图厂商.地图厂商为了提供尽可能多的位置信息,花费了很大的精力去寻找诸如加油站,餐馆,酒店,景点等目的地,这些目的地其实都可

随机推荐