【百度地图开发之五】百度地图定位图层基本使用方法讲解

jerry 地图开发 2015年11月27日 收藏

  上一篇我们学习了【百度地图开发之四】百度地图基本操作功能实现讲解(),今天继续看一下百度地图的地位图层的显示使用方法

   (一):基本介绍:

         百度地图可以直接提供定位功能,并且把位置信息以图层的形式标注在地图上面(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弹窗

  (三)例子实现(主要来看以下百度sdk中的例子,注释已经重新添加了一下,很详细了)

      1:定位信息监听:BDLoactionListener:

  1. /**
  2.      * 定位SDK监听函数
  3.      */
  4.     public class MyLocationListenner implements BDLocationListener {
  5.     
  6.         @Override
  7.         public void onReceiveLocation(BDLocation location) {
  8.             if (location == null)
  9.                 return ;
  10.             locData.latitude = location.getLatitude();
  11.             locData.longitude = location.getLongitude();
  12.             //如果不显示定位精度圈,将accuracy赋值为0即可
  13.             locData.accuracy = location.getRadius();
  14.             // 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。
  15.             locData.direction = location.getDerect();
  16.             //更新定位数据
  17.             myLocationOverlay.setData(locData);
  18.             //更新图层数据执行刷新后生效
  19.             mMapView.refresh();
  20.             //是手动触发请求或首次定位时,移动到定位点
  21.             Log.d("zttjiangqq", "locData:latitude:"+locData.latitude+",longitude:"+locData.longitude);
  22.             if (isRequest || isFirstLoc){
  23.              //移动地图到定位点
  24.              Log.d("LocationOverlay", "receive location, animate to it");
  25.                 mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6)));
  26.                 isRequest = false;
  27.                 myLocationOverlay.setLocationMode(LocationMode.FOLLOWING);
  28. requestLocButton.setText("跟随");
  29.                 mCurBtnType = E_BUTTON_TYPE.FOLLOW;
  30.             }
  31.             //首次定位完成
  32.             isFirstLoc = false;
  33.         }
  34.         
  35.         public void onReceivePoi(BDLocation poiLocation) {
  36.             if (poiLocation == null){
  37.                 return ;
  38.             }
  39.         }
  40.     }

      2:创建Pop弹窗方法:


  1.  /**
  2.  * 创建弹出泡泡图层
  3.  */
  4. public void createPaopao(){
  5. viewCache = getLayoutInflater().inflate(R.layout.custom_text_view, null);
  6.         popupText =(TextView) viewCache.findViewById(R.id.textcache);
  7.         //泡泡点击响应回调
  8.         PopupClickListener popListener = new PopupClickListener(){
  9. @Override
  10. public void onClickedPopup(int index) {
  11. Log.v("click", "clickapoapo");
  12. }
  13.         };
  14.         //创建初始化显示的pop 图层
  15.         pop = new PopupOverlay(mMapView,popListener);
  16.         // 传入pop图层到自定义地图定位视图中
  17.         MyLocationMapView.pop = pop;
  18. }

      具体代码实现如下:


  1. package com.ztt.baidumap.ui;
  2.  
  3. import android.app.Activity;
  4. import android.content.Context;
  5. import android.graphics.drawable.Drawable;
  6. import android.os.Bundle;
  7. import android.util.AttributeSet;
  8. import android.util.Log;
  9. import android.view.Menu;
  10. import android.view.MotionEvent;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Button;
  14. import android.widget.RadioGroup;
  15. import android.widget.RadioGroup.OnCheckedChangeListener;
  16. import android.widget.TextView;
  17. import android.widget.Toast;
  18.  
  19. import com.baidu.location.BDLocation;
  20. import com.baidu.location.BDLocationListener;
  21. import com.baidu.location.LocationClient;
  22. import com.baidu.location.LocationClientOption;
  23. import com.baidu.mapapi.BMapManager;
  24. import com.baidu.mapapi.map.LocationData;
  25. import com.baidu.mapapi.map.MapController;
  26. import com.baidu.mapapi.map.MapView;
  27. import com.baidu.mapapi.map.MyLocationOverlay;
  28. import com.baidu.mapapi.map.MyLocationOverlay.LocationMode;
  29. import com.baidu.mapapi.map.PopupClickListener;
  30. import com.baidu.mapapi.map.PopupOverlay;
  31. import com.baidu.platform.comapi.basestruct.GeoPoint;
  32. /**
  33.  * 此demo用来展示如何结合定位SDK实现定位,并使用MyLocationOverlay绘制定位位置
  34.  * 同时展示如何使用自定义图标绘制并点击时弹出泡泡
  35.  *
  36.  */
  37. public class LocationOverlayDemo extends Activity {
  38. private enum E_BUTTON_TYPE {
  39. LOC,
  40. COMPASS,
  41. FOLLOW
  42. }
  43. private E_BUTTON_TYPE mCurBtnType;
  44.  
  45. // 定位相关
  46. LocationClient mLocClient;
  47. LocationData locData = null;
  48. public MyLocationListenner myListener = new MyLocationListenner();
  49. //定位图层
  50. locationOverlay myLocationOverlay = null;
  51. //弹出泡泡图层
  52. private PopupOverlay   pop  = null;//弹出泡泡图层,浏览节点时使用
  53. private TextView  popupText = null;//泡泡view
  54. private View viewCache = null;
  55. //地图相关,使用继承MapView的MyLocationMapView目的是重写touch事件实现泡泡处理
  56. //如果不处理touch事件,则无需继承,直接使用MapView即可
  57. MyLocationMapView mMapView = null; // 地图View
  58. private MapController mMapController = null;
  59.  
  60. //UI相关
  61. OnCheckedChangeListener radioButtonListener = null;
  62. Button requestLocButton = null;
  63. boolean isRequest = false;//是否手动触发请求定位
  64. boolean isFirstLoc = true;//是否首次定位
  65.     @Override
  66.     public void onCreate(Bundle savedInstanceState) {
  67.         super.onCreate(savedInstanceState);
  68.         /**
  69.          * 使用地图sdk前需先初始化BMapManager.
  70.          * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,
  71.          * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁
  72.          */
  73.         MyApplication app = (MyApplication)this.getApplication();
  74.         if (app.mBMapManager == null) {
  75.             app.mBMapManager = new BMapManager(getApplicationContext());
  76.             /**
  77.              * 如果BMapManager没有初始化则初始化BMapManager
  78.              */
  79.             app.mBMapManager.init(MyApplication.strKey,new MyApplication.MyGeneralListener());
  80.         }
  81.         setContentView(R.layout.activity_locationoverlay);
  82.         CharSequence titleLable="定位功能";
  83.         setTitle(titleLable);
  84.         requestLocButton = (Button)findViewById(R.id.button1);
  85.         mCurBtnType = E_BUTTON_TYPE.LOC;
  86.         OnClickListener btnClickListener = new OnClickListener() {
  87.          public void onClick(View v) {
  88. switch (mCurBtnType) {
  89. case LOC:
  90. //手动定位请求
  91. requestLocClick();
  92. break;
  93. case COMPASS:
  94. myLocationOverlay.setLocationMode(LocationMode.NORMAL);
  95. requestLocButton.setText("定位");
  96. mCurBtnType = E_BUTTON_TYPE.LOC;
  97. break;
  98. case FOLLOW:
  99. myLocationOverlay.setLocationMode(LocationMode.COMPASS);
  100. requestLocButton.setText("罗盘");
  101. mCurBtnType = E_BUTTON_TYPE.COMPASS;
  102. break;
  103. }
  104. }
  105. };
  106.     requestLocButton.setOnClickListener(btnClickListener);
  107.         RadioGroup group = (RadioGroup)this.findViewById(R.id.radioGroup);
  108.         radioButtonListener = new OnCheckedChangeListener() {
  109. @Override
  110. public void onCheckedChanged(RadioGroup group, int checkedId) {
  111. if (checkedId == R.id.defaulticon){
  112. //传入null则,恢复默认图标
  113. modifyLocationOverlayIcon(null);
  114. }
  115. if (checkedId == R.id.customicon){
  116. //修改为自定义marker  //使用自定义的图标 来设置图层位置图标
  117. modifyLocationOverlayIcon(getResources().getDrawable(R.drawable.icon_geo));
  118. }
  119. }
  120. };
  121. group.setOnCheckedChangeListener(radioButtonListener);
  122.         
  123. //地图初始化
  124.         mMapView = (MyLocationMapView)findViewById(R.id.bmapView);
  125.         mMapController = mMapView.getController();
  126.         mMapView.getController().setZoom(14);  //设置缩放等级
  127.         mMapView.getController().enableClick(true);   //支持点击
  128.         mMapView.setBuiltInZoomControls(true);  //支持缩放
  129.         //创建 弹出泡泡图层
  130.         createPaopao();
  131.         
  132.         //定位初始化
  133.         mLocClient = new LocationClient( this );
  134.         locData = new LocationData();
  135.         mLocClient.registerLocationListener( myListener );
  136.         LocationClientOption option = new LocationClientOption();
  137.         option.setOpenGps(true);//打开gps
  138.         option.setCoorType("bd09ll");     //设置坐标类型
  139.         option.setScanSpan(1000);
  140.         mLocClient.setLocOption(option);
  141.         mLocClient.start();
  142.        
  143.         //定位图层初始化
  144. myLocationOverlay = new locationOverlay(mMapView);
  145. //设置定位数据
  146.     myLocationOverlay.setData(locData);
  147.     //添加定位图层
  148. mMapView.getOverlays().add(myLocationOverlay);
  149. myLocationOverlay.enableCompass();
  150. //修改定位数据后刷新图层生效
  151. mMapView.refresh();
  152.     }
  153.     /**
  154.      * 手动触发一次定位请求
  155.      */
  156.     public void requestLocClick(){
  157.      isRequest = true;
  158.         mLocClient.requestLocation();
  159.         Toast.makeText(LocationOverlayDemo.this, "正在定位……", Toast.LENGTH_SHORT).show();
  160.     }
  161.     /**
  162.      * 修改位置图标
  163.      * @param marker
  164.      */
  165.     public void modifyLocationOverlayIcon(Drawable marker){
  166.      //当传入marker为null时,使用默认图标绘制
  167.      myLocationOverlay.setMarker(marker);
  168.      //修改图层,需要刷新MapView生效
  169.      mMapView.refresh();
  170.     }
  171.     /**
  172.  * 创建弹出泡泡图层
  173.  */
  174. public void createPaopao(){
  175. viewCache = getLayoutInflater().inflate(R.layout.custom_text_view, null);
  176.         popupText =(TextView) viewCache.findViewById(R.id.textcache);
  177.         //泡泡点击响应回调
  178.         PopupClickListener popListener = new PopupClickListener(){
  179. @Override
  180. public void onClickedPopup(int index) {
  181. Log.v("click", "clickapoapo");
  182. }
  183.         };
  184.         //创建初始化显示的pop 图层
  185.         pop = new PopupOverlay(mMapView,popListener);
  186.         // 传入pop图层到自定义地图定位视图中
  187.         MyLocationMapView.pop = pop;
  188. }
  189. /**
  190.      * 定位SDK监听函数
  191.      */
  192.     public class MyLocationListenner implements BDLocationListener {
  193.     
  194.         @Override
  195.         public void onReceiveLocation(BDLocation location) {
  196.             if (location == null)
  197.                 return ;
  198.             locData.latitude = location.getLatitude();
  199.             locData.longitude = location.getLongitude();
  200.             //如果不显示定位精度圈,将accuracy赋值为0即可
  201.             locData.accuracy = location.getRadius();
  202.             // 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。
  203.             locData.direction = location.getDerect();
  204.             //更新定位数据
  205.             myLocationOverlay.setData(locData);
  206.             //更新图层数据执行刷新后生效
  207.             mMapView.refresh();
  208.             //是手动触发请求或首次定位时,移动到定位点
  209.             Log.d("zttjiangqq", "locData:latitude:"+locData.latitude+",longitude:"+locData.longitude);
  210.             if (isRequest || isFirstLoc){
  211.              //移动地图到定位点
  212.              Log.d("LocationOverlay", "receive location, animate to it");
  213.                 mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6)));
  214.                 isRequest = false;
  215.                 myLocationOverlay.setLocationMode(LocationMode.FOLLOWING);
  216. requestLocButton.setText("跟随");
  217.                 mCurBtnType = E_BUTTON_TYPE.FOLLOW;
  218.             }
  219.             //首次定位完成
  220.             isFirstLoc = false;
  221.         }
  222.         
  223.         public void onReceivePoi(BDLocation poiLocation) {
  224.             if (poiLocation == null){
  225.                 return ;
  226.             }
  227.         }
  228.     }
  229.     
  230.     //继承MyLocationOverlay重写dispatchTap实现点击处理
  231.    public class locationOverlay extends MyLocationOverlay{
  232.  
  233.    public locationOverlay(MapView mapView) {
  234.    super(mapView);
  235.    }
  236.    @Override
  237.    protected boolean dispatchTap() {
  238.    //处理点击事件,弹出泡泡信息
  239.    popupText.setBackgroundResource(R.drawable.popup);
  240. popupText.setText("我的位置");
  241. //定位图层显示的位置(图标,经纬度信息,)
  242. pop.showPopup(BMapUtil.getBitmapFromView(popupText),
  243. new GeoPoint((int)(locData.latitude*1e6), (int)(locData.longitude*1e6)),
  244. 8);
  245.    return true;
  246.    }
  247.   
  248.    }
  249.  
  250.     @Override
  251.     protected void onPause() {
  252.         mMapView.onPause();
  253.         super.onPause();
  254.     }
  255.     
  256.     @Override
  257.     protected void onResume() {
  258.         mMapView.onResume();
  259.         super.onResume();
  260.     }
  261.     
  262.     @Override
  263.     protected void onDestroy() {
  264.      //退出时销毁定位
  265.         if (mLocClient != null)
  266.             mLocClient.stop();
  267.         mMapView.destroy();
  268.         super.onDestroy();
  269.     }
  270.     
  271.     @Override
  272.     protected void onSaveInstanceState(Bundle outState) {
  273.      super.onSaveInstanceState(outState);
  274.      mMapView.onSaveInstanceState(outState);
  275.     
  276.     }
  277.     
  278.     @Override
  279.     protected void onRestoreInstanceState(Bundle savedInstanceState) {
  280.      super.onRestoreInstanceState(savedInstanceState);
  281.      mMapView.onRestoreInstanceState(savedInstanceState);
  282.     }
  283.     
  284.     @Override
  285.     public boolean onCreateOptionsMenu(Menu menu) {
  286. //        getMenuInflater().inflate(R.menu.activity_main, menu);
  287.         return true;
  288.     }
  289.  
  290. }
  291. /**
  292.  * 继承MapView重写onTouchEvent实现泡泡处理操作
  293.  * @author hejin
  294.  *
  295.  */
  296. class MyLocationMapView extends MapView{
  297. static PopupOverlay   pop  = null;//弹出泡泡图层,点击图标使用
  298. public MyLocationMapView(Context context) {
  299. super(context);
  300. // TODO Auto-generated constructor stub
  301. }
  302. public MyLocationMapView(Context context, AttributeSet attrs){
  303. super(context,attrs);
  304. }
  305. public MyLocationMapView(Context context, AttributeSet attrs, int defStyle){
  306. super(context, attrs, defStyle);
  307. }
  308. @Override
  309.     public boolean onTouchEvent(MotionEvent event){
  310. if (!super.onTouchEvent(event)){
  311. //消隐泡泡
  312. if (pop != null && event.getAction() == MotionEvent.ACTION_UP)
  313. pop.hidePop();
  314. }
  315. return true;
  316. }
  317. }

  3:运行截图:




(四):特别提醒:


    上面所要用到的自定义的Application类和之前文章中写的一样,最后千万不要忘记要加入一个定位service:


  1.   <service
  2.             android:name="com.baidu.location.f"
  3.             android:enabled="true"
  4.             android:process=":remote" >
  5.         </service>