溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用百度地圖實(shí)現(xiàn)小車規(guī)劃路線后平滑移動(dòng)功能

發(fā)布時(shí)間:2021-09-28 11:38:50 來(lái)源:億速云 閱讀:167 作者:小新 欄目:編程語(yǔ)言

這篇文章主要介紹如何使用百度地圖實(shí)現(xiàn)小車規(guī)劃路線后平滑移動(dòng)功能,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

文章目的

項(xiàng)目開(kāi)發(fā)所需,所以結(jié)合百度地圖提供的小車平滑軌跡移動(dòng),自己寫(xiě)的demo

實(shí)現(xiàn)效果

如何使用百度地圖實(shí)現(xiàn)小車規(guī)劃路線后平滑移動(dòng)功能

下面是實(shí)現(xiàn)的關(guān)鍵步驟

集成百度地圖

怎么集成自然是看百度地圖開(kāi)發(fā)平臺(tái)提供的文檔。

文檔連接

規(guī)劃線路

看百度地圖的文檔,寫(xiě)一個(gè)規(guī)劃線路的工具類(駕車的)

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("測(cè)試", 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));
  }
}

規(guī)劃線路后需要將實(shí)時(shí)路況索引保存,為后面畫(huà)圖需要

// 設(shè)置路段實(shí)時(shí)路況索引        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]);
            }
          }
        }

要將路線規(guī)劃的路線上的路段再細(xì)分(切割),這樣小車移動(dòng)才會(huì)平滑

/**
   * 將規(guī)劃好的路線點(diǎn)進(jìn)行截取
   * 參考百度給的小車平滑軌跡移動(dòng)demo實(shí)現(xiàn)。(循環(huán)的算法不太懂)
   * @param routeLine
   * @param distance
   * @return   */  private ArrayList<LatLng> divideRouteLine(ArrayList<LatLng> routeLine, double distance) {
    // 截取后的路線點(diǎn)的結(jié)果集    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);
      // 是不是正向的標(biāo)示      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); // 終點(diǎn)      }
    }
    return result;
  }

最后是開(kāi)啟子線程,對(duì)小車狀態(tài)進(jìn)行更新(車頭方向和小車位置)

/**
   * 循環(huán)進(jìn)行移動(dòng)邏輯
   */  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              // 實(shí)際情況可以是:當(dāng)前誤差小于5米 DistanceUtil.getDistance(mCurrentLatLng, latLngs.get(p)) <= 5)              // mCurrentLatLng 這個(gè)小車的當(dāng)前位置得自行獲取得到              if (true) {//               實(shí)際情況的索引更新 mIndex = p;                mIndex++; // 模擬就是每次加1                runOnUiThread(new Runnable() {
                  @Override                  public void run() {
                    Toast.makeText(mContext, "當(dāng)前索引:" + mIndex, Toast.LENGTH_SHORT).show();
                  }
                });
                break;
              }
            }

            // 改變循環(huán)條件            i = mIndex + 1;

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

            // 擦除走過(guò)的路線            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()));
            }

            // 這里是小車的當(dāng)前點(diǎn)和下一個(gè)點(diǎn),用于確定車頭方向            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 {
              // 控制線程更新時(shí)間間隔              thisThread.sleep(TIME_INTERVAL);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }
      }
    };
    // 啟動(dòng)線程    moveThread.start();
  }

以上是“如何使用百度地圖實(shí)現(xiàn)小車規(guī)劃路線后平滑移動(dòng)功能”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI