【百度地图开发之四】百度地图基本操作功能实现讲解

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

上一篇我们学习了【百度地图开发之三】百度地图UI控制功能讲解(点击跳转),今天继续看一下百度地图一些基本的操作功能的实现;

(一)基本介绍:

     百度地图的一些基本操作控制包括地图的缩放,旋转,俯视,单双击,长按等控制事件,实现前面的三个功能主要需要用到MapController类,单双击,长按事件需要用到MapView的监听事件处理接口MKMapTouchListener

(二)控制类,接口基本介绍

     1:MapController:地图操作控制器,今天我们主要用到了其中的以下方法:

        ①:public float setZoom(float zoomLevel):设置地图的缩放级别,这个值的取值范围为[3,19];

        ②:public void setRotation(int rotate):设置地图的旋转角度

        ③:public void setOverlooking(int voidlook):设置地图的俯视角度

    2:MKMapTouchListener:地图点击事件监听器接口,主要有以下方法:

        ①:void onMapClick(GeoPoint point):地图单击事件,回调回来回来点击的地图的坐标点位置.

        ②:void onMapDoubleClick(GeoPoint point):地图双击事件,回调双击的地图的坐标点位置.

        ③:void onMapLongClick(GeoPoint point):地图的长按事件,回调长按的地图的坐标点位置.

(三):事件监听器使用方法:

       我们只要在MapView对象中注册MKMapTouchListener监听器,并且实现其中的单击,双击,长按事件方法即可.具体实现方法如下:

  1. /**
  2.          * 设置地图点击事件监听 
  3.          */
  4.         mapTouchListener = new MKMapTouchListener(){
  5. @Override
  6. public void onMapClick(GeoPoint point) {
  7. touchType = "单击";
  8. currentPt = point;
  9. updateMapState();
  10. }
  11.  
  12. @Override
  13. public void onMapDoubleClick(GeoPoint point) {
  14. touchType = "双击";
  15. currentPt = point;
  16. updateMapState();
  17. }
  18.  
  19. @Override
  20. public void onMapLongClick(GeoPoint point) {
  21. touchType = "长按";
  22. currentPt = point;
  23. updateMapState();
  24. }
  25.         };
  26.         //给地图注册事件
  27.         mMapView.regMapTouchListner(mapTouchListener);

(四)下面我们来看下百度地图SDK中demo的例子(代码中的注释,在此基础上已经添加的很详细了)

     1:MyApplication.java:进行BMapManager全局变量的设置和密钥验证,代码如下: 

  1. package com.ztt.baidumap.ui;
  2.  
  3. import android.app.Application;
  4. import android.content.Context;
  5. import android.util.Log;
  6. import android.widget.Toast;
  7.  
  8. import com.baidu.mapapi.BMapManager;
  9. import com.baidu.mapapi.MKGeneralListener;
  10. import com.baidu.mapapi.map.MKEvent;
  11. /**
  12.  * 自定义Application,进行key识别验证 (使用单例)
  13.  * @author Jiangqq
  14.  * @time 2014/03/15 10:14
  15.  */
  16. public class MyApplication extends Application {
  17.     public static MyApplication instance=null;
  18. BMapManager mBMapManager = null;
  19. public boolean m_bKeyRight = true;
  20.     public static final String strKey = "vUAGbPwLpolIqiwWisnQPeIE";  //百度地图官网申请的密钥
  21. public static MyApplication getInstance(){
  22. return instance;
  23. }
  24. @Override
  25. public void onCreate() {
  26. super.onCreate();
  27. instance=this;
  28. //在APP应用启动的时候,进行初始化验证
  29. initEngineManager(this);
  30. }
  31. /**
  32.  * 进行验证key
  33.  * @param pContext
  34.  */
  35. private void initEngineManager(Context pContext)
  36. {
  37.  if (mBMapManager == null) {
  38.             mBMapManager = new BMapManager(pContext);
  39.         }
  40.  
  41.         if (!mBMapManager.init(strKey,new MyGeneralListener())) {
  42.             Toast.makeText(MyApplication.getInstance(), 
  43.                     "BMapManager  初始化错误!", Toast.LENGTH_LONG).show();
  44.         }
  45. }
  46. // 常用事件监听,用来处理通常的网络错误,授权验证错误等
  47.     static class MyGeneralListener implements MKGeneralListener {
  48.         
  49.         @Override
  50.         public void onGetNetworkState(int iError) {
  51.             if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
  52.                 Toast.makeText(MyApplication.getInstance(), "您的网络出错啦!",
  53.                     Toast.LENGTH_LONG).show();
  54.             }
  55.             else if (iError == MKEvent.ERROR_NETWORK_DATA) {
  56.                 Toast.makeText(MyApplication.getInstance(), "输入正确的检索条件!",
  57.                         Toast.LENGTH_LONG).show();
  58.             }else {
  59.  Log.d("zttjiangqq", "iError="+iError);
  60. }
  61.             // ...
  62.         }
  63.  
  64.         @Override
  65.         public void onGetPermissionState(int iError) {
  66.          //非零值表示key验证未通过
  67.             if (iError != 0) {
  68.                 //授权Key错误:
  69.                 Toast.makeText(MyApplication.getInstance(), 
  70.                         "请在 DemoApplication.java文件输入正确的授权Key,并检查您的网络连接是否正常!error: "+iError, Toast.LENGTH_LONG).show();
  71.                 MyApplication.getInstance().m_bKeyRight = false;
  72.             }
  73.             else{
  74.              MyApplication.getInstance().m_bKeyRight = true;
  75.              Toast.makeText(MyApplication.getInstance(), 
  76.                         "key认证成功", Toast.LENGTH_LONG).show();
  77.             }
  78.         }
  79.     }
  80. }

    2:布局文件:


  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3.     
  4.   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  5.     android:orientation="vertical"
  6.     android:layout_width="fill_parent"
  7.     android:layout_height="fill_parent">
  8.     
  9.     <LinearLayout 
  10.     android:orientation="horizontal"
  11.     android:layout_width="fill_parent"
  12.     android:layout_height="50dip">
  13.     
  14.     <Button
  15.         android:id="@+id/zoombutton"
  16.         android:layout_width="fill_parent"
  17.         android:layout_height="wrap_content"
  18.         android:layout_weight="1"
  19.         android:background="@drawable/button_style"
  20.         android:text="缩放" />
  21.  
  22.     <EditText
  23.         android:id="@+id/zoomlevel"
  24.         android:layout_width="fill_parent"
  25.         android:layout_height="wrap_content"
  26.         android:layout_weight="1"
  27.         android:text="10" />
  28.  
  29.     <Button
  30.         android:id="@+id/rotatebutton"
  31.         android:layout_width="fill_parent"
  32.         android:layout_height="wrap_content"
  33.         android:layout_weight="1"
  34.         android:background="@drawable/button_style"
  35.         android:text="旋转" />
  36.  
  37.     <EditText
  38.         android:id="@+id/rotateangle"
  39.      android:text="90"
  40.      android:layout_width="fill_parent"
  41.      android:layout_height="wrap_content"
  42.      android:layout_weight="1"
  43.         />
  44.  
  45.     <Button
  46.         android:id="@+id/overlookbutton"
  47.         android:layout_width="fill_parent"
  48.         android:layout_height="wrap_content"
  49.      android:layout_weight="1"
  50.         android:background="@drawable/button_style"
  51.         android:text="俯视" />
  52.  
  53.     <EditText
  54.         android:id="@+id/overlookangle"
  55.      android:text="-30"
  56.      android:layout_width="fill_parent"
  57.      android:layout_height="wrap_content"
  58.      android:layout_weight="1"
  59.         />
  60.     </LinearLayout>
  61.     <TextView
  62.         android:id="@+id/state"
  63.      android:text="点击、长按、双击地图以获取经纬度和地图状态"
  64.      android:layout_width="fill_parent"
  65.      android:layout_height="wrap_content"
  66.      android:lines="3"
  67.         />
  68.     <RelativeLayout 
  69.     android:orientation="vertical"
  70.     android:layout_width="fill_parent"
  71.     android:layout_height="fill_parent"
  72.     >
  73.   <com.baidu.mapapi.map.MapView android:id="@+id/bmapView"
  74.     android:layout_width="fill_parent" android:layout_height="fill_parent" 
  75.     android:clickable="true"     
  76. />
  77.     <Button
  78.         android:id="@+id/savescreen"
  79.         android:layout_width="wrap_content"
  80.         android:layout_height="wrap_content"
  81.         android:layout_alignParentTop="true"
  82.         android:layout_alignParentRight="true"
  83.         android:layout_marginTop="10dip"
  84.         android:background="@drawable/button_style"
  85.         android:text="截图" />
  86.  
  87. </RelativeLayout>
  88.  
  89.   </LinearLayout>

    3:功能实现Activity代码:


  1. package com.ztt.baidumap.ui;
  2.  
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7.  
  8. import android.app.Activity;
  9. import android.graphics.Bitmap;
  10. import android.os.Bundle;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Button;
  14. import android.widget.EditText;
  15. import android.widget.TextView;
  16. import android.widget.Toast;
  17.  
  18. import com.baidu.mapapi.BMapManager;
  19. import com.baidu.mapapi.map.MKMapTouchListener;
  20. import com.baidu.mapapi.map.MKMapViewListener;
  21. import com.baidu.mapapi.map.MapController;
  22. import com.baidu.mapapi.map.MapPoi;
  23. import com.baidu.mapapi.map.MapView;
  24. import com.baidu.platform.comapi.basestruct.GeoPoint;
  25.  
  26. /**
  27.  * 演示地图缩放,旋转,视角控制
  28.  */
  29. public class MapControlDemo extends Activity {
  30.  
  31. /**
  32.  *  MapView 是地图主控件
  33.  */
  34. private MapView mMapView = null;
  35. /**
  36.  *  用MapController完成地图控制 
  37.  */
  38. private MapController mMapController = null;
  39. /**
  40.  *  MKMapViewListener 用于处理地图事件回调
  41.  */
  42. MKMapViewListener mMapListener = null;
  43. /**
  44.  * 用于截获屏坐标
  45.  */
  46. MKMapTouchListener mapTouchListener = null; 
  47. /**
  48.  * 当前地点击点
  49.  */
  50. private GeoPoint currentPt = null; 
  51. /**
  52.  * 控制按钮
  53.  */
  54. private Button zoomButton = null;  //缩放
  55. private Button rotateButton = null; //旋转
  56. private Button overlookButton =null;  //俯视
  57. private Button saveScreenButton = null;  //截图
  58. /**
  59.  * 
  60.  */
  61. private String touchType = null;
  62. /**
  63.  * 用于显示地图状态的面板
  64.  */
  65. private TextView mStateBar = null;
  66.     @Override
  67.     public void onCreate(Bundle savedInstanceState) {
  68.         super.onCreate(savedInstanceState);
  69.         /**
  70.          * 使用地图sdk前需先初始化BMapManager.
  71.          * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,
  72.          * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁
  73.          */
  74.         MyApplication app = (MyApplication)this.getApplication();
  75.         if (app.mBMapManager == null) {
  76.             app.mBMapManager = new BMapManager(getApplicationContext());
  77.             /**
  78.              * 如果BMapManager没有初始化则初始化BMapManager
  79.              */
  80.             app.mBMapManager.init(MyApplication.strKey,new MyApplication.MyGeneralListener());
  81.         }
  82.         /**
  83.           * 由于MapView在setContentView()中初始化,所以它需要在BMapManager初始化之后
  84.           */
  85.         setContentView(R.layout.activity_mapcontrol);
  86.         mMapView = (MapView)findViewById(R.id.bmapView);
  87.         /**
  88.          * 获取地图控制器
  89.          */
  90.         mMapController = mMapView.getController();
  91.         /**
  92.          *  设置地图是否响应点击事件  .
  93.          */
  94.         mMapController.enableClick(true);
  95.         /**
  96.          * 设置地图缩放级别
  97.          */
  98.         mMapController.setZoom(12);
  99.         
  100.         mStateBar = (TextView) findViewById(R.id.state);
  101.         /**
  102.          * 初始化地图事件监听
  103.          */
  104.         initListener();
  105.        
  106.         /**
  107.          * 将地图移动至天安门
  108.          * 使用百度经纬度坐标,可以通过http://api.map.baidu.com/lbsapi/getpoint/index.html查询地理坐标
  109.          * 如果需要在百度地图上显示使用其他坐标系统的位置,请发邮件至mapapi@baidu.com申请坐标转换接口
  110.          */
  111.         double cLat = 39.945 ;
  112.         double cLon = 116.404 ;
  113.         GeoPoint p = new GeoPoint((int)(cLat * 1E6), (int)(cLon * 1E6));
  114.         mMapController.setCenter(p);
  115.         
  116.     }
  117.     
  118.     /**
  119.      * 添加监听事件
  120.      */
  121.     private void initListener() {
  122.      /**
  123.          * 设置地图点击事件监听 
  124.          */
  125.         mapTouchListener = new MKMapTouchListener(){
  126. @Override
  127. public void onMapClick(GeoPoint point) {
  128. touchType = "单击";
  129. currentPt = point;
  130. updateMapState();
  131. }
  132.  
  133. @Override
  134. public void onMapDoubleClick(GeoPoint point) {
  135. touchType = "双击";
  136. currentPt = point;
  137. updateMapState();
  138. }
  139.  
  140. @Override
  141. public void onMapLongClick(GeoPoint point) {
  142. touchType = "长按";
  143. currentPt = point;
  144. updateMapState();
  145. }
  146.         };
  147.         //给地图注册事件
  148.         mMapView.regMapTouchListner(mapTouchListener);
  149.         /**
  150.          * 设置地图事件监听
  151.          */
  152.         mMapListener = new MKMapViewListener() {
  153. @Override
  154. public void onMapMoveFinish() {
  155. /**
  156.  * 在此处理地图移动完成回调
  157.  * 缩放,平移等操作完成后,此回调被触发
  158.  */
  159. updateMapState();
  160. }
  161. @Override
  162. public void onClickMapPoi(MapPoi mapPoiInfo) {
  163. /**
  164.  * 在此处理底图poi点击事件
  165.  * 显示底图poi名称并移动至该点
  166.  * 设置过: mMapController.enableClick(true); 时,此回调才能被触发
  167.  * 
  168.  */
  169. }
  170.  
  171. @Override
  172. public void onGetCurrentMap(Bitmap b) {
  173. /**
  174.  *  当调用过 mMapView.getCurrentMap()后,此回调会被触发
  175.  *  可在此保存截图至存储设备
  176.  */
  177. File file = new File("/mnt/sdcard/test.png");
  178.                 FileOutputStream out;
  179.                 try{
  180.                     out = new FileOutputStream(file);
  181.                     if(b.compress(Bitmap.CompressFormat.PNG, 70, out)) 
  182.                     {
  183.                         out.flush();
  184.                         out.close();
  185.                     }
  186.                     Toast.makeText(MapControlDemo.this, 
  187.                          "屏幕截图成功,图片存在: "+file.toString(),
  188.                       Toast.LENGTH_SHORT)
  189.                          .show();
  190.                 } 
  191.                 catch (FileNotFoundException e) 
  192.                 {
  193.                     e.printStackTrace();
  194.                 } 
  195.                 catch (IOException e) 
  196.                 {
  197.                     e.printStackTrace(); 
  198.                 }
  199.                 
  200. }
  201.  
  202. @Override
  203. public void onMapAnimationFinish() {
  204. /**
  205.  *  地图完成带动画的操作(如: animationTo())后,此回调被触发
  206.  */
  207. updateMapState();
  208. }
  209.  
  210. @Override
  211. public void onMapLoadFinish() {
  212. // TODO Auto-generated method stub
  213. }
  214. };
  215. mMapView.regMapViewListener(MyApplication.getInstance().mBMapManager, mMapListener);
  216. /**
  217.  * 设置按键监听
  218.  */
  219. zoomButton        = (Button)findViewById(R.id.zoombutton);
  220. rotateButton      = (Button)findViewById(R.id.rotatebutton);
  221. overlookButton    = (Button)findViewById(R.id.overlookbutton);
  222. saveScreenButton  = (Button)findViewById(R.id.savescreen);
  223. OnClickListener onClickListener = new OnClickListener(){
  224. @Override
  225. public void onClick(View view) {
  226. if ( view.equals(zoomButton)){
  227. perfomZoom();
  228. }
  229. else if( view.equals(rotateButton)){
  230. perfomRotate();
  231. }
  232. else if( view.equals(overlookButton)){
  233. perfomOverlook();
  234. }
  235. else if ( view.equals(saveScreenButton)){
  236. //截图,在MKMapViewListener中保存图片
  237.      mMapView.getCurrentMap();
  238.      Toast.makeText(MapControlDemo.this, 
  239.       "正在截取屏幕图片...", 
  240.       Toast.LENGTH_SHORT ).show();
  241.           
  242. }
  243. updateMapState();
  244. }
  245. };
  246. zoomButton.setOnClickListener(onClickListener);
  247. rotateButton.setOnClickListener(onClickListener);
  248. overlookButton.setOnClickListener(onClickListener);
  249. saveScreenButton.setOnClickListener(onClickListener);
  250.     }
  251.     /**
  252.      * 处理缩放
  253.      * sdk 缩放级别范围: [3.0,19.0]
  254.      */
  255.     private void perfomZoom(){
  256.      EditText  t  = (EditText) findViewById(R.id.zoomlevel);
  257.      try{
  258.          float zoomLevel = Float.parseFloat(t.getText().toString());
  259.          //设置地图缩放级别
  260.          mMapController.setZoom(zoomLevel);
  261.      }catch(NumberFormatException e){
  262.      Toast.makeText(this, 
  263.               "请输入正确的缩放级别", Toast.LENGTH_SHORT)
  264.           .show();
  265.      }
  266.     }
  267.     /**
  268.      * 处理旋转 
  269.      * 旋转角范围: -180 ~ 180 , 单位:度   逆时针旋转  
  270.      */
  271.     private void perfomRotate(){
  272.      EditText  t  = (EditText) findViewById(R.id.rotateangle);
  273.      try{
  274.          int rotateAngle = Integer.parseInt(t.getText().toString());
  275.          //设置地图旋转角度
  276.          mMapController.setRotation(rotateAngle);
  277.      }catch(NumberFormatException e){
  278.      Toast.makeText(this, 
  279.               "请输入正确的旋转角度", Toast.LENGTH_SHORT)
  280.           .show();
  281.      }
  282.     }
  283.     /**
  284.      * 处理俯视
  285.      * 俯角范围:  -45 ~ 0 , 单位: 度
  286.      */
  287.     private void perfomOverlook(){
  288.      EditText  t  = (EditText) findViewById(R.id.overlookangle);
  289.      try{
  290.          int overlookAngle = Integer.parseInt(t.getText().toString());
  291.          //设置地图的俯视
  292.          mMapController.setOverlooking(overlookAngle);
  293.      }catch(NumberFormatException e){
  294.      Toast.makeText(this, 
  295.               "请输入正确的俯角", Toast.LENGTH_SHORT)
  296.           .show();
  297.      }
  298.     }
  299.     
  300.     /**
  301.      * 更新地图状态显示面板
  302.      */
  303.     private void updateMapState(){
  304.         if ( mStateBar == null){
  305.         return ;
  306.         }
  307.      String state  = "";
  308.      if ( currentPt == null ){
  309.      state = "点击、长按、双击地图以获取经纬度和地图状态";
  310.      }
  311.      else{
  312.      state = String.format(touchType+",当前经度 : %f 当前纬度:%f",currentPt.getLongitudeE6()*1E-6,currentPt.getLatitudeE6()*1E-6);
  313.      }
  314.      state += "\n";
  315.      state += String.format("zoom level= %.1f    rotate angle= %d   overlaylook angle=  %d",
  316.                 mMapView.getZoomLevel(), 
  317.                 mMapView.getMapRotation(),
  318.                 mMapView.getMapOverlooking() 
  319.          );
  320.      mStateBar.setText(state);
  321.     }
  322.     
  323.     @Override
  324.     protected void onPause() {
  325.      /**
  326.       *  MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
  327.       */
  328.         mMapView.onPause();
  329.         super.onPause();
  330.     }
  331.     
  332.     @Override
  333.     protected void onResume() {
  334.      /**
  335.       *  MapView的生命周期与Activity同步,当activity恢复时需调用MapView.onResume()
  336.       */
  337.         mMapView.onResume();
  338.         super.onResume();
  339.     }
  340.     
  341.     @Override
  342.     protected void onDestroy() {
  343.      /**
  344.       *  MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()
  345.       */
  346.         mMapView.destroy();
  347.         super.onDestroy();
  348.     }
  349.     
  350.     @Override
  351.     protected void onSaveInstanceState(Bundle outState) {
  352.      super.onSaveInstanceState(outState);
  353.      mMapView.onSaveInstanceState(outState);
  354.     
  355.     }
  356.     
  357.     @Override
  358.     protected void onRestoreInstanceState(Bundle savedInstanceState) {
  359.      super.onRestoreInstanceState(savedInstanceState);
  360.      mMapView.onRestoreInstanceState(savedInstanceState);
  361.     }
  362.     
  363. }

  4:运行截图:




[注明]AndroidManifest.xml的配置和之前的文章中一样.