百度地图实现小车规划路线后平滑移动功能
程序员文章站
2022-06-17 14:10:33
文章目的
项目开发所需,所以结合百度地图提供的小车平滑轨迹移动,自己写的demo
实现效果
代码下载
下面是实现的关键步骤
集成百度地图
怎么集成自然是...
文章目的
项目开发所需,所以结合百度地图提供的小车平滑轨迹移动,自己写的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(); }
上一篇: Ajax实现评论提交
下一篇: Qt实现字符串生成二维码功能