栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

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

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

文章目的

项目开发所需,所以结合百度地图提供的小车平滑轨迹移动,自己写的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 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]);
     }
   }
 }

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


  private ArrayList divideRouteLine(ArrayList routeLine, double distance) {
    // 截取后的路线点的结果集
    ArrayList 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 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();
  }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/154544.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号