上一篇我们学习了【百度地图开发之四】百度地图基本操作功能实现讲解(),今天继续看一下百度地图的地位图层的显示使用方法
百度地图可以直接提供定位功能,并且把位置信息以图层的形式标注在地图上面(PopupView),同时还支持自定义设置图标,这样便于用户直接查看位置信息。要实现以上的方法,我们主要需要用到MyLocationOverlay(在地图上面显示当前位置的一个覆盖物(图层)),PopupOverlay弹出的pop信息类似于Popupwindow。还有以下一些有关定位的类:LocationClient(),LocationData(用户的位置信息)。
1:MyLocationOverlay:一个显示用户当前位置的Overlay。该相当于一个覆盖物图层,用来在地图上面绘制用户当前的位置,同时我们可以在子类进行覆盖dispatchTap()来处理点击事件。主要有以下一些方法。
①:protected boolean dispatcheTap():在位置图标上面处理点击事件,默认返回false
②:public LocationData getMyLocation(): 获取定位图层当前的定位数据
③:public void setData(LocationData locData): 设置位置参数 [注]设置数据之后必须刷新mapview来使得设置生效,
④:public void setMarker(Drawable marker):设置定位的图标,[注]设置图标之后必须刷新mapview来时的设置生效.
⑤:public vois setLocationMode(MyLocationOverlay.LocationMode mode):来进行设置图层显示的位模式
2:LocationData():表示用户的一些位置信息:例如:定位精度(accurac,GPS定位时方向角度(direction),纬度坐标(latitude),经度坐标(longtiude),GPS定位时卫星数量(satekkitesNum),GPS定位时速度(speed)。
3:PopupOverlay:该类可以用来生成一个位置信息的pop弹窗.主要有以下一些方法:
1:public void showPopup(Bitmap pop,GeoPoint,int yOffset):显示pop弹窗。
2:public void hidePop(): 收起pop弹窗
1:定位信息监听:BDLoactionListener:
- /**
- * 定位SDK监听函数
- */
- public class MyLocationListenner implements BDLocationListener {
- @Override
- public void onReceiveLocation(BDLocation location) {
- if (location == null)
- return ;
- locData.latitude = location.getLatitude();
- locData.longitude = location.getLongitude();
- //如果不显示定位精度圈,将accuracy赋值为0即可
- locData.accuracy = location.getRadius();
- // 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。
- locData.direction = location.getDerect();
- //更新定位数据
- myLocationOverlay.setData(locData);
- //更新图层数据执行刷新后生效
- mMapView.refresh();
- //是手动触发请求或首次定位时,移动到定位点
- Log.d("zttjiangqq", "locData:latitude:"+locData.latitude+",longitude:"+locData.longitude);
- if (isRequest || isFirstLoc){
- //移动地图到定位点
- Log.d("LocationOverlay", "receive location, animate to it");
- mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6)));
- isRequest = false;
- myLocationOverlay.setLocationMode(LocationMode.FOLLOWING);
- requestLocButton.setText("跟随");
- mCurBtnType = E_BUTTON_TYPE.FOLLOW;
- }
- //首次定位完成
- isFirstLoc = false;
- }
- public void onReceivePoi(BDLocation poiLocation) {
- if (poiLocation == null){
- return ;
- }
- }
- }
2:创建Pop弹窗方法:
- /**
- * 创建弹出泡泡图层
- */
- public void createPaopao(){
- viewCache = getLayoutInflater().inflate(R.layout.custom_text_view, null);
- popupText =(TextView) viewCache.findViewById(R.id.textcache);
- //泡泡点击响应回调
- PopupClickListener popListener = new PopupClickListener(){
- @Override
- public void onClickedPopup(int index) {
- Log.v("click", "clickapoapo");
- }
- };
- //创建初始化显示的pop 图层
- pop = new PopupOverlay(mMapView,popListener);
- // 传入pop图层到自定义地图定位视图中
- MyLocationMapView.pop = pop;
- }
具体代码实现如下:
- package com.ztt.baidumap.ui;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.Menu;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.RadioGroup;
- import android.widget.RadioGroup.OnCheckedChangeListener;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.baidu.location.BDLocation;
- import com.baidu.location.BDLocationListener;
- import com.baidu.location.LocationClient;
- import com.baidu.location.LocationClientOption;
- import com.baidu.mapapi.BMapManager;
- import com.baidu.mapapi.map.LocationData;
- import com.baidu.mapapi.map.MapController;
- import com.baidu.mapapi.map.MapView;
- import com.baidu.mapapi.map.MyLocationOverlay;
- import com.baidu.mapapi.map.MyLocationOverlay.LocationMode;
- import com.baidu.mapapi.map.PopupClickListener;
- import com.baidu.mapapi.map.PopupOverlay;
- import com.baidu.platform.comapi.basestruct.GeoPoint;
- /**
- * 此demo用来展示如何结合定位SDK实现定位,并使用MyLocationOverlay绘制定位位置
- * 同时展示如何使用自定义图标绘制并点击时弹出泡泡
- *
- */
- public class LocationOverlayDemo extends Activity {
- private enum E_BUTTON_TYPE {
- LOC,
- COMPASS,
- FOLLOW
- }
- private E_BUTTON_TYPE mCurBtnType;
- // 定位相关
- LocationClient mLocClient;
- LocationData locData = null;
- public MyLocationListenner myListener = new MyLocationListenner();
- //定位图层
- locationOverlay myLocationOverlay = null;
- //弹出泡泡图层
- private PopupOverlay pop = null;//弹出泡泡图层,浏览节点时使用
- private TextView popupText = null;//泡泡view
- private View viewCache = null;
- //地图相关,使用继承MapView的MyLocationMapView目的是重写touch事件实现泡泡处理
- //如果不处理touch事件,则无需继承,直接使用MapView即可
- MyLocationMapView mMapView = null; // 地图View
- private MapController mMapController = null;
- //UI相关
- OnCheckedChangeListener radioButtonListener = null;
- Button requestLocButton = null;
- boolean isRequest = false;//是否手动触发请求定位
- boolean isFirstLoc = true;//是否首次定位
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- /**
- * 使用地图sdk前需先初始化BMapManager.
- * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,
- * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁
- */
- MyApplication app = (MyApplication)this.getApplication();
- if (app.mBMapManager == null) {
- app.mBMapManager = new BMapManager(getApplicationContext());
- /**
- * 如果BMapManager没有初始化则初始化BMapManager
- */
- app.mBMapManager.init(MyApplication.strKey,new MyApplication.MyGeneralListener());
- }
- setContentView(R.layout.activity_locationoverlay);
- CharSequence titleLable="定位功能";
- setTitle(titleLable);
- requestLocButton = (Button)findViewById(R.id.button1);
- mCurBtnType = E_BUTTON_TYPE.LOC;
- OnClickListener btnClickListener = new OnClickListener() {
- public void onClick(View v) {
- switch (mCurBtnType) {
- case LOC:
- //手动定位请求
- requestLocClick();
- break;
- case COMPASS:
- myLocationOverlay.setLocationMode(LocationMode.NORMAL);
- requestLocButton.setText("定位");
- mCurBtnType = E_BUTTON_TYPE.LOC;
- break;
- case FOLLOW:
- myLocationOverlay.setLocationMode(LocationMode.COMPASS);
- requestLocButton.setText("罗盘");
- mCurBtnType = E_BUTTON_TYPE.COMPASS;
- break;
- }
- }
- };
- requestLocButton.setOnClickListener(btnClickListener);
- RadioGroup group = (RadioGroup)this.findViewById(R.id.radioGroup);
- radioButtonListener = new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- if (checkedId == R.id.defaulticon){
- //传入null则,恢复默认图标
- modifyLocationOverlayIcon(null);
- }
- if (checkedId == R.id.customicon){
- //修改为自定义marker //使用自定义的图标 来设置图层位置图标
- modifyLocationOverlayIcon(getResources().getDrawable(R.drawable.icon_geo));
- }
- }
- };
- group.setOnCheckedChangeListener(radioButtonListener);
- //地图初始化
- mMapView = (MyLocationMapView)findViewById(R.id.bmapView);
- mMapController = mMapView.getController();
- mMapView.getController().setZoom(14); //设置缩放等级
- mMapView.getController().enableClick(true); //支持点击
- mMapView.setBuiltInZoomControls(true); //支持缩放
- //创建 弹出泡泡图层
- createPaopao();
- //定位初始化
- mLocClient = new LocationClient( this );
- locData = new LocationData();
- mLocClient.registerLocationListener( myListener );
- LocationClientOption option = new LocationClientOption();
- option.setOpenGps(true);//打开gps
- option.setCoorType("bd09ll"); //设置坐标类型
- option.setScanSpan(1000);
- mLocClient.setLocOption(option);
- mLocClient.start();
- //定位图层初始化
- myLocationOverlay = new locationOverlay(mMapView);
- //设置定位数据
- myLocationOverlay.setData(locData);
- //添加定位图层
- mMapView.getOverlays().add(myLocationOverlay);
- myLocationOverlay.enableCompass();
- //修改定位数据后刷新图层生效
- mMapView.refresh();
- }
- /**
- * 手动触发一次定位请求
- */
- public void requestLocClick(){
- isRequest = true;
- mLocClient.requestLocation();
- Toast.makeText(LocationOverlayDemo.this, "正在定位……", Toast.LENGTH_SHORT).show();
- }
- /**
- * 修改位置图标
- * @param marker
- */
- public void modifyLocationOverlayIcon(Drawable marker){
- //当传入marker为null时,使用默认图标绘制
- myLocationOverlay.setMarker(marker);
- //修改图层,需要刷新MapView生效
- mMapView.refresh();
- }
- /**
- * 创建弹出泡泡图层
- */
- public void createPaopao(){
- viewCache = getLayoutInflater().inflate(R.layout.custom_text_view, null);
- popupText =(TextView) viewCache.findViewById(R.id.textcache);
- //泡泡点击响应回调
- PopupClickListener popListener = new PopupClickListener(){
- @Override
- public void onClickedPopup(int index) {
- Log.v("click", "clickapoapo");
- }
- };
- //创建初始化显示的pop 图层
- pop = new PopupOverlay(mMapView,popListener);
- // 传入pop图层到自定义地图定位视图中
- MyLocationMapView.pop = pop;
- }
- /**
- * 定位SDK监听函数
- */
- public class MyLocationListenner implements BDLocationListener {
- @Override
- public void onReceiveLocation(BDLocation location) {
- if (location == null)
- return ;
- locData.latitude = location.getLatitude();
- locData.longitude = location.getLongitude();
- //如果不显示定位精度圈,将accuracy赋值为0即可
- locData.accuracy = location.getRadius();
- // 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。
- locData.direction = location.getDerect();
- //更新定位数据
- myLocationOverlay.setData(locData);
- //更新图层数据执行刷新后生效
- mMapView.refresh();
- //是手动触发请求或首次定位时,移动到定位点
- Log.d("zttjiangqq", "locData:latitude:"+locData.latitude+",longitude:"+locData.longitude);
- if (isRequest || isFirstLoc){
- //移动地图到定位点
- Log.d("LocationOverlay", "receive location, animate to it");
- mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6)));
- isRequest = false;
- myLocationOverlay.setLocationMode(LocationMode.FOLLOWING);
- requestLocButton.setText("跟随");
- mCurBtnType = E_BUTTON_TYPE.FOLLOW;
- }
- //首次定位完成
- isFirstLoc = false;
- }
- public void onReceivePoi(BDLocation poiLocation) {
- if (poiLocation == null){
- return ;
- }
- }
- }
- //继承MyLocationOverlay重写dispatchTap实现点击处理
- public class locationOverlay extends MyLocationOverlay{
- public locationOverlay(MapView mapView) {
- super(mapView);
- }
- @Override
- protected boolean dispatchTap() {
- //处理点击事件,弹出泡泡信息
- popupText.setBackgroundResource(R.drawable.popup);
- popupText.setText("我的位置");
- //定位图层显示的位置(图标,经纬度信息,)
- pop.showPopup(BMapUtil.getBitmapFromView(popupText),
- new GeoPoint((int)(locData.latitude*1e6), (int)(locData.longitude*1e6)),
- 8);
- return true;
- }
- }
- @Override
- protected void onPause() {
- mMapView.onPause();
- super.onPause();
- }
- @Override
- protected void onResume() {
- mMapView.onResume();
- super.onResume();
- }
- @Override
- protected void onDestroy() {
- //退出时销毁定位
- if (mLocClient != null)
- mLocClient.stop();
- mMapView.destroy();
- super.onDestroy();
- }
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mMapView.onSaveInstanceState(outState);
- }
- @Override
- protected void onRestoreInstanceState(Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
- mMapView.onRestoreInstanceState(savedInstanceState);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // getMenuInflater().inflate(R.menu.activity_main, menu);
- return true;
- }
- }
- /**
- * 继承MapView重写onTouchEvent实现泡泡处理操作
- * @author hejin
- *
- */
- class MyLocationMapView extends MapView{
- static PopupOverlay pop = null;//弹出泡泡图层,点击图标使用
- public MyLocationMapView(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- }
- public MyLocationMapView(Context context, AttributeSet attrs){
- super(context,attrs);
- }
- public MyLocationMapView(Context context, AttributeSet attrs, int defStyle){
- super(context, attrs, defStyle);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event){
- if (!super.onTouchEvent(event)){
- //消隐泡泡
- if (pop != null && event.getAction() == MotionEvent.ACTION_UP)
- pop.hidePop();
- }
- return true;
- }
- }
3:运行截图:
上面所要用到的自定义的Application类和之前文章中写的一样,最后千万不要忘记要加入一个定位service:
- <service
- android:name="com.baidu.location.f"
- android:enabled="true"
- android:process=":remote" >
- </service>