最近在做一个APP,其中一个功能要在地图上显示酒店位置以及显示酒店的最低价格,要用到百度地图中的Overlay。
overlay有以下几种:
1)Overlay:它是所有覆盖物的抽象基类,所有的覆盖物均继承此类的方法,实现用户自定义图层显示;
2)MyLocationOverlay:一个负责显示用户当前位置的Overlay;
3)ItemizedOverlay:它包含了一个OverlayItem列表,相当于一组分条的Overlay,通过继承此类,将一组兴趣点显示在地图上;
4)PoiOverlay:本地搜索图层,提供某一特定地区的位置搜索服务,比如在北京市搜索“公园”,通过此图层将公园显示在地图上;
5)RouteOverlay:步行、驾车导航线路图层,将步行、驾车出行方案的路线及关键点显示在地图上;
6)TransitOverlay:公交换乘线路图层,将某一特定地区的公交出行方案的路线及换乘位置显示在地图上。
在3.0以后版本中百度地图api中overlay改变比较大,我刚才所说的功能在3.0以前的版本是可以通过自定义的Overlay继承ItemizedOverlay来实现,在3.0以后的版本中已经找不到ItemizedOverlay了,已经用Marker代替。官方的android demo也没有关于marker
的事例,网上资料也较少,网页版较为简单,android只能自己摸索了。
我们先来看看最终做出的效果,如下图所示:
下面是具体实现:
1.页面activity_main.xml
1
2
3
4
5
6
7
8
9
10
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
>
<com.baidu.mapapi.map.MapView
android:id=
"@+id/bmapView"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
</LinearLayout>
|
2.自定义Marker
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
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
>
<LinearLayout
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:background=
"#fea531"
android:gravity=
"center"
android:orientation=
"horizontal"
>
<ImageView
android:id=
"@+id/img_hotel_image"
android:layout_width=
"25dp"
android:layout_height=
"25dp"
android:padding=
"2dip"
android:scaleType=
"fitXY"
android:src=
"@drawable/hotel_pic"
/>
<TextView
android:id=
"@+id/tv_hotel_price"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:padding=
"5dip"
android:textColor=
"#ffffff"
android:textSize=
"14dp"
/>
</LinearLayout>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:gravity=
"center"
android:orientation=
"horizontal"
>
<ImageView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:src=
"@drawable/custom_marker_triangle"
/>
</LinearLayout>
</LinearLayout>
|
3.下面这段代码是关键,我们需要把自定义的view转换成Bitmap,MarkerOptions中的icon参数是Bitmap,自定义marker是很常用的,不明白百度为啥不搞个明显点方法,废了很多时间。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
private
Bitmap getViewBitmap(View addViewContent) {
addViewContent.setDrawingCacheEnabled(
true
);
addViewContent.measure(View.MeasureSpec.makeMeasureSpec(
0
, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(
0
, View.MeasureSpec.UNSPECIFIED));
addViewContent.layout(
0
,
0
, addViewContent.getMeasuredWidth(), addViewContent.getMeasuredHeight());
addViewContent.buildDrawingCache();
Bitmap cacheBitmap = addViewContent.getDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
return
bitmap;
}
|
4.下面是Activity代码,
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
public
class
MainActivity
extends
Activity {
private
List<Hotel> mData;
private
SDKReceiver mReceiver;
private
MapView mMapView;
private
BaiduMap mBaiduMap;
LocationClient mLocClient;
private
LocationMode mCurrentMode;
public
MyLocationListenner myListener =
new
MyLocationListenner();
BitmapDescriptor mCurrentMarker;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
IntentFilter iFilter =
new
IntentFilter();
iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);
iFilter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);
mReceiver =
new
SDKReceiver();
registerReceiver(mReceiver, iFilter);
// 地图初始化
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
//initLocation();
mBaiduMap.setOnMarkerClickListener(
new
OnMarkerClickListener() {
public
boolean
onMarkerClick(
final
Marker marker) {
// TO DO
return
true
;
}
});
mData = getData();
generateMarker();
}
/**
* Inits the location.
*/
private
void
initLocation() {
// 开启定位图层
mBaiduMap.setMyLocationEnabled(
true
);
// 定位初始化
mLocClient =
new
LocationClient(
this
);
mLocClient.registerLocationListener(myListener);
LocationClientOption option =
new
LocationClientOption();
option.setOpenGps(
true
);
// 打开gps
option.setCoorType(
"bd09ll"
);
// 设置坐标类型
option.setScanSpan(
1000
);
mLocClient.setLocOption(option);
mLocClient.start();
}
/**
* 定位SDK监听函数
*/
public
class
MyLocationListenner
implements
BDLocationListener {
@Override
public
void
onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if
(location ==
null
|| mMapView ==
null
)
return
;
MyLocationData locData =
new
MyLocationData.Builder().accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(
100
).latitude(location.getLatitude()).longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
LatLng ll =
new
LatLng(location.getLatitude(), location.getLongitude());
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(u);
}
public
void
onReceivePoi(BDLocation poiLocation) {
}
}
/**
* The Class SDKReceiver.
*/
public
class
SDKReceiver
extends
BroadcastReceiver {
public
void
onReceive(Context context, Intent intent) {
String s = intent.getAction();
if
(s.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR)) {
Toast toast = Toast.makeText(context,
"key 验证出错! 请在 AndroidManifest.xml 文件中检查 key 设置"
, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER,
0
,
0
);
toast.show();
}
else
if
(s.equals(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR)) {
Toast toast = Toast.makeText(context,
"网络出错"
, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER,
0
,
0
);
toast.show();
}
}
}
/**
* Gets the view bitmap.
*
* @param addViewContent
* the add view content
* @return the view bitmap
*/
private
Bitmap getViewBitmap(View addViewContent) {
addViewContent.setDrawingCacheEnabled(
true
);
addViewContent.measure(View.MeasureSpec.makeMeasureSpec(
0
, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(
0
, View.MeasureSpec.UNSPECIFIED));
addViewContent.layout(
0
,
0
, addViewContent.getMeasuredWidth(), addViewContent.getMeasuredHeight());
addViewContent.buildDrawingCache();
Bitmap cacheBitmap = addViewContent.getDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
return
bitmap;
}
/**
* Gets the data.
*
* @return the data
*/
public
List<Hotel> getData() {
try
{
List<Hotel> resultList =
new
ArrayList<Hotel>();
AssetManager manager = getApplicationContext().getAssets();
InputStream file = manager.open(
"data.json"
);
byte
[] data =
new
byte
[file.available()];
file.read(data);
file.close();
String jsonStr =
new
String(data);
JSONObject json = JSON.parseObject(jsonStr);
String jsonText = json.getString(
"Output"
);
return
JSONArray.parseArray(jsonText.toString(), Hotel.
class
);
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return
null
;
}
}
public
void
generateMarker() {
for
(Iterator iterator = mData.iterator(); iterator.hasNext();) {
Hotel hotel = (Hotel) iterator.next();
LatLng ll =
new
LatLng(hotel.HotelLatitude, hotel.HotelLongitude);
View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.custom_marker,
null
);
// ImageView img_hotel_image=
// (ImageView)view.findViewById(R.id.img_hotel_image);
// new
// DownloadImageTask(img_hotel_image).execute(hotel.getHotelImageUrl());
TextView tv_hotel_price = (TextView) view.findViewById(R.id.tv_hotel_price);
tv_hotel_price.setText(
new
StringBuilder().append(hotel.getHotelPrice()).append(
"¥起"
));
BitmapDescriptor markerIcon = BitmapDescriptorFactory.fromBitmap(getViewBitmap(view));
Bundle bundle =
new
Bundle();
bundle.putSerializable(
"HOTEL"
, hotel);
OverlayOptions oo =
new
MarkerOptions().position(ll).icon(markerIcon).zIndex(
9
).draggable(
true
).extraInfo(bundle);
mBaiduMap.addOverlay(oo);
}
}
@Override
protected
void
onPause() {
mMapView.onPause();
super
.onPause();
}
@Override
protected
void
onResume() {
mMapView.onResume();
super
.onResume();
}
@Override
protected
void
onDestroy() {
// 退出时销毁定位
mLocClient.stop();
// 关闭定位图层
mBaiduMap.setMyLocationEnabled(
false
);
mMapView.onDestroy();
mMapView =
null
;
super
.onDestroy();
}
}
|
activity代码注释不多,有不明白的地方请自行下载官方Demo来研究。