上一篇我们学习了【百度地图开发之四】百度地图基本操作功能实现讲解(),今天继续看一下百度地图的地位图层的显示使用方法
百度地图可以直接提供定位功能,并且把位置信息以图层的形式标注在地图上面(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>