Android百度地图自定义公交路线导航

时间:2021-08-23 07:03:47

一、问题描述

基于百度地图实现检索指定城市指定公交的交通路线图,效果如图所示

Android百度地图自定义公交路线导航

二、通用组件application类,主要创建并初始化bmapmanager

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class app extends application {
static app mdemoapp;
//百度mapapi的管理类
public bmapmanager mbmapman = null;
// 授权key
// 申请地址:http://dev.baidu.com/wiki/static/imap/key/
public string mstrkey = "your appkey";
boolean m_bkeyright = true; // 授权key正确,验证通过
// 常用事件监听,用来处理通常的网络错误,授权验证错误等
public static class mygenerallistener implements mkgenerallistener {
@override
public void ongetnetworkstate(int ierror) {
log.d("mygenerallistener", "ongetnetworkstate error is "+ ierror);
toast.maketext(app.mdemoapp.getapplicationcontext(), "您的网络出错啦!",
toast.length_long).show();
}
@override
public void ongetpermissionstate(int ierror) {
log.d("mygenerallistener", "ongetpermissionstate error is "+ ierror);
if (ierror == mkevent.error_permission_denied) {
// 授权key错误:
toast.maketext(app.mdemoapp.getapplicationcontext(),
"文件输入正确的授权key!",
toast.length_long).show();
app.mdemoapp.m_bkeyright = false;
}
}
}
@override
public void oncreate() {
log.v("bmapapidemoapp", "oncreate");
mdemoapp = this;
mbmapman = new bmapmanager(this);
mbmapman.init(this.mstrkey, new mygenerallistener());
mbmapman.getlocationmanager().setnotifyinternal(10, 5);
super.oncreate();
}
@override
//app的退出之前调用mapadpi的destroy()函数,避免重复初始化带来的时间消耗
public void onterminate() {
if (mbmapman != null) {
mbmapman.destroy();
mbmapman = null;
}
super.onterminate();
}
}

三、编写公交的路线图层(customrouteoverlay)和图标标识(customoverlayitem)

customrouteoverlay组件扩展routeoverlay:

主要公交、步行和驾车线路图层,将公交、步行和驾车出行方案的路线及关键点显示在地图上,根据车辆路线的起点和终点进行驾车路线的检索;

customoverlayitem扩展itemizedoverlay<overlayitem>:

覆盖物的集合类,使用这个类可以将地图上具有相同属性或者特性的坐标使用图标标识出来,overlayitem 这个类对象则是itemizedoverlay中一个一个的item对象 也就是每个坐标对应的覆盖物

customrouteoverlay类代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
public class customrouteoverlay extends routeoverlay {
public activity ac;
private mapview mapview;
static arraylist<view> overlayviews = new arraylist<view>();
public customrouteoverlay(activity arg0, mapview arg1) {
super(arg0, arg1);
ac = arg0;
mapview = arg1;
// todo auto-generated constructor stub
}
@override
protected boolean ontap(int arg0) {
// todo auto-generated method stub
// return super.ontap(arg0);
return true;
}
@override
public void setdata(mkroute arg0) {
// todo auto-generated method stub
super.setdata(arg0);
addhint(arg0);
}
public void addhints(mkroute routes) {
for (int i = 0; i < routes.getnumsteps(); i++) {
drawable marker = ac.getresources().getdrawable(r.drawable.pop); // 得到需要标在地图上的资源
marker.setbounds(0, 0, marker.getintrinsicwidth(),
marker.getintrinsicheight()); // 为maker定义位置和边界
overitemt overitem = new overitemt(marker,ac, routes.getstep(i).getcontent(),routes.getstep(i).getpoint());
// overlayitem over=new overlayitem(routes.get, null, null);
mapview.getoverlays().add(overitem); // 添加itemizedoverlay实例到mmapview
}
mapview.invalidate();
}
/**
* 增加 指示路线
* @param routes
*/
public void addhint(mkroute routes) {
mapview.getoverlays().clear();// 先清空
// mapview.removeallviewsinlayout();
view mpopview = ac.getlayoutinflater().inflate(r.layout.popview,
null);
for(int i=0;i< overlayviews.size();i++){
system.out.println("remove &"+i);
mapview.removeviewinlayout(overlayviews.get(i));
overlayviews.remove(i);
}
mapview.invalidate();
// 添加itemizedoverlay
for (int i = 0; i < routes.getnumsteps(); i++) {
drawable marker = ac.getresources().getdrawable(r.drawable.pop); // 得到需要标在地图上的资源
marker.setbounds(0, 0, marker.getintrinsicwidth(),
marker.getintrinsicheight()); // 为maker定义位置和边界
geopoint pt = routes.getstep(i).getpoint();// =
// routes.get(i).getpoint();
if (i != 0 && i != routes.getnumsteps() - 1) {
mpopview = ac.getlayoutinflater().inflate(r.layout.popview,
null);
mapview.addview(mpopview, new mapview.layoutparams(
layoutparams.wrap_content, layoutparams.wrap_content, null,
mapview.layoutparams.top_left));
mpopview.setvisibility(view.gone);
mapview.updateviewlayout(mpopview, new mapview.layoutparams(
layoutparams.wrap_content, layoutparams.wrap_content, pt,
mapview.layoutparams.bottom_center));
mpopview.setvisibility(view.visible);
button button = (button) mpopview.findviewbyid(r.id.overlay_pop);
button.settext(routes.getstep(i).getcontent());
overlayviews.add(mpopview);
overlayviews.add(button);
} else {
//修改起始点和终点样式-自定义
mpopview = ac.getlayoutinflater().inflate(r.layout.popview,
null);
mapview.addview(mpopview, new mapview.layoutparams(
layoutparams.wrap_content, layoutparams.wrap_content, null,
mapview.layoutparams.top_left));
mpopview.setvisibility(view.gone);
mapview.updateviewlayout(mpopview, new mapview.layoutparams(
layoutparams.wrap_content, layoutparams.wrap_content, pt,
mapview.layoutparams.bottom_center));
mpopview.setvisibility(view.visible);
button button = (button) mpopview.findviewbyid(r.id.overlay_pop);
button.offsettopandbottom(100);
button.settextcolor(color.blue);
button.setbackgroundcolor(color.transparent);
button.settext(routes.getstep(i).getcontent());
overlayviews.add(mpopview);
overlayviews.add(button);
}
}
}
class overitemt extends itemizedoverlay<overlayitem> {
private drawable marker;
private context mcontext;
private geopoint p;
private overlayitem o;
public overitemt(drawable marker, context context, string title,geopoint p) {
super(boundcenterbottom(marker));
this.marker = marker;
this.mcontext = context;
this.p = p;
// 构造overlayitem的三个参数依次为:item的位置,标题文本,文字片段
o = new overlayitem(p, title, title);
populate(); // createitem(int)方法构造item。一旦有了数据,在调用其它方法前,首先调用这个方法
}
public void updateoverlay() {
populate();
}
@override
public void draw(canvas canvas, mapview mapview, boolean shadow) {
// projection接口用于屏幕像素坐标和经纬度坐标之间的变换
projection projection = mapview.getprojection();
for (int index = size() - 1; index >= 0; index--) { // 遍历mgeolist
overlayitem overlayitem = getitem(index); // 得到给定索引的item
string java" id="highlighter_735888">
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class customoverlayitem extends itemizedoverlay<overlayitem> {
// private list<overlayitem> geolist = new arraylist<overlayitem>();
private context mcontext;
private overlayitem overlay;
boolean showtext;
// private string title;
private drawable marker;
public customoverlayitem(drawable marker, context context, geopoint p,
string title,string sinppet, boolean showtext) {
super(boundcenterbottom(marker));
this.mcontext = context;
// 用给定的经纬度构造geopoint,单位是微度 (度 * 1e6)
// point = p;
this.showtext = showtext;
// this.title = title;
this.marker = marker;
overlay = new overlayitem(p, title, sinppet);
populate(); // createitem(int)方法构造item。一旦有了数据,在调用其它方法前,首先调用这个方法
}
@override
protected overlayitem createitem(int i) {
return overlay;
}
@override
public int size() {
return 1;
}
@override
public void draw(canvas canvas, mapview mapview, boolean arg2) {
// todo auto-generated method stub
super.draw(canvas, mapview, arg2);
// projection接口用于屏幕像素坐标和经纬度坐标之间的变换
projection projection = mapview.getprojection();
string java" id="highlighter_686069">
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
public class buslinesearch extends mapactivity {
button mbtnsearch = null; // 搜索按钮
mapview mmapview = null; // 地图view
mksearch msearch = null; // 搜索模块,也可去掉地图模块独立使用
string mcityname = null;
locationlistener loc_listener;
app app = null;
static boolean flag = false;
static thread thread;
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.buslinesearch);
app = (app) this.getapplication();
if (app.mbmapman == null) {
app.mbmapman = new bmapmanager(getapplication());
app.mbmapman.init(app.mstrkey, new app.mygenerallistener());
}
app.mbmapman.start();
// 如果使用地图sdk,请初始化地图activity
super.initmapactivity(app.mbmapman);
mmapview = (mapview) findviewbyid(r.id.bmapview);
mmapview.setbuiltinzoomcontrols(true);
// 设置在缩放动画过程中也显示overlay,默认为不绘制
mmapview.setdrawoverlaywhenzooming(true);
mmapview.setbuiltinzoomcontrols(true);
// 初始化搜索模块,注册事件监听
mapcontroller mmapcontroller = mmapview.getcontroller(); // 得到mmapview的控制权,可以用它控制和驱动平移和缩放
geopoint point = new geopoint((int) (39.915 * 1e6),
(int) (116.404 * 1e6)); // 用给定的经纬度构造一个geopoint,单位是微度 (度 * 1e6)
mmapcontroller.setcenter(point); // 设置地图中心点
mmapcontroller.setzoom(15); // 设置地图zoom级别
msearch = new mksearch();
msearch.init(app.mbmapman, new mksearchlistener() {
public void ongetpoiresult(mkpoiresult res, int type, int error) {
// 错误号可参考mkevent中的定义
if (error != 0 || res == null) {
toast.maketext(buslinesearch.this, "抱歉,未找到结果",
toast.length_long).show();
return;
}
// system.out.println(res.tostring());
// 找到公交路线poi node
mkpoiinfo curpoi = null;
int totalpoinum = res.getnumpois();
for (int idx = 0; idx < totalpoinum; idx++) {
log.d("busline", "the busline is " + idx);
curpoi = res.getpoi(idx);
if (2 == curpoi.epoitype) {
break;
}
}
msearch.buslinesearch(mcityname, curpoi.uid);
}
public void ongetdrivingrouteresult(mkdrivingrouteresult res,
int error) {
}
public void ongettransitrouteresult(mktransitrouteresult res,
int error) {
res.getplan(0).getdistance();
}
public void ongetwalkingrouteresult(mkwalkingrouteresult res,
int error) {
}
public void ongetaddrresult(mkaddrinfo res, int error) {
}
public void ongetbusdetailresult(mkbuslineresult result, int ierror) {
if (ierror != 0 || result == null) {
toast.maketext(buslinesearch.this, "抱歉,未找到结果",
toast.length_long).show();
return;
}
// result.getbusroute().get
// result.getbusroute().getstart().tostring();
customrouteoverlay routeoverlay = new customrouteoverlay(
buslinesearch.this, mmapview);
routeoverlay.setdata(result.getbusroute());
mmapview.getoverlays().clear();
system.out.println(mmapview.getoverlays().size());
mmapview.getoverlays().add(routeoverlay);
mmapview.invalidate();
mmapview.getcontroller().animateto(
result.getbusroute().getstart());
}
@override
public void ongetsuggestionresult(mksuggestionresult res, int arg1) {
// todo auto-generated method stub
}
});
// mlocationmanager.requestlocationupdates(listener);
// 注册定位事件
loc_listener = new locationlistener() {
@override
public void onlocationchanged(location location) {
if (location != null) {
string strlog = string.format("您当前的位置:\r\n" + "纬度:%f\r\n"
+ "经度:%f", location.getlongitude(),
location.getlatitude());
flag = true;
drawable marker = getresources()
.getdrawable(r.drawable.ic_launcher);
final geopoint p = new geopoint(
(int) (location.getlatitude() * 1e6),
(int) (location.getlongitude() * 1e6));
customoverlayitem item = new customoverlayitem(marker,
buslinesearch.this, p, "我的位置", "", false);
mmapview.getoverlays().add(item);
mmapview.getcontroller().animateto(p);
}
}
};
// 设定搜索按钮的响应
mbtnsearch = (button) findviewbyid(r.id.search);
onclicklistener clicklistener = new onclicklistener() {
public void onclick(view v) {
searchbuttonprocess(v);
}
};
mbtnsearch.setonclicklistener(clicklistener);
}
void searchbuttonprocess(view v) {
if (mbtnsearch.equals(v)) {
mmapview.getoverlays().clear();
mmapview.getoverlays().removeall(mmapview.getoverlays());
mmapview.invalidate();
edittext editcity = (edittext) findviewbyid(r.id.city);
edittext editsearchkey = (edittext) findviewbyid(r.id.searchkey);
mcityname = editcity.gettext().tostring();
msearch.poisearchincity(mcityname, editsearchkey.gettext()
.tostring());
}
}
@override
protected void onpause() {
if (null == app)
app = (app) this.getapplication();
app.mbmapman.getlocationmanager().removeupdates(loc_listener);
app.mbmapman.stop();
super.onpause();
}
@override
protected void onresume() {
if (null == app)
app = (app) this.getapplication();
app.mbmapman.start();
super.onresume();
app.mbmapman.getlocationmanager().requestlocationupdates(loc_listener);// 定位
}
@override
protected boolean isroutedisplayed() {
// todo auto-generated method stub
return false;
}
@override
protected void ondestroy() {
// todo auto-generated method stub
super.ondestroy();
}
}

以上代码内容是针对android百度地图自定义公交路线导航的相关知识,希望对大家有所帮助。

延伸 · 阅读

精彩推荐