android 百度地图走动轨迹,百度地图实现小车规划路线后平滑移动功能

文章目的

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

实现效果

641af11ac7d6cfd2d197975e1ab131d5.gif

代码下载

下面是实现的关键步骤

集成百度地图

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

规划线路

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

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]);

}

}

}

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

/**

* 将规划好的路线点进行截取

* 参考百度给的小车平滑轨迹移动demo实现。(循环的算法不太懂)

* @param routeline

* @param distance

* @return

*/

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();

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值