小編給大家分享一下百度地圖如何實(shí)現(xiàn)小車規(guī)劃路線后平滑移動(dòng)功能,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
專業(yè)領(lǐng)域包括成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司、成都做商城網(wǎng)站、微信營銷、系統(tǒng)平臺開發(fā), 與其他網(wǎng)站設(shè)計(jì)及系統(tǒng)開發(fā)公司不同,創(chuàng)新互聯(lián)的整合解決方案結(jié)合了幫做網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗(yàn)和互聯(lián)網(wǎng)整合營銷的理念,并將策略和執(zhí)行緊密結(jié)合,為客戶提供全網(wǎng)互聯(lián)網(wǎng)整合方案。
實(shí)現(xiàn)效果
代碼下載
下載鏈接
下面是實(shí)現(xiàn)的關(guān)鍵步驟
集成百度地圖
怎么集成自然是看百度地圖開發(fā)平臺提供的文檔。
文檔連接
規(guī)劃線路
看百度地圖的文檔,寫一個(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("測試", 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í)路況索引保存,為后面畫圖需要
// 設(shè)置路段實(shí)時(shí)路況索引 ListallStep = 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 ArrayListdivideRouteLine(ArrayList routeLine, double distance) { // 截取后的路線點(diǎn)的結(jié)果集 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); // 是不是正向的標(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 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; }
最后是開啟子線程,對小車狀態(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; } // 擦除走過的路線 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)功能”有了一定的了解,如果想了解更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!