寫在前面的話:
【百度地圖開發之四】百度地圖基本操作功能實現講解(部落格地址:http://blog.csdn.net/developer_jiangqq),轉載請註明。
Author:hmjiangqq
Email:jiangqqlmj@163.com
上一篇我們學習了【百度地圖開發之三】百度地圖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監聽器,並且實現其中的單擊,雙擊,長按事件方法即可.具體實現方法如下:
/** * 設定地圖點擊事件監聽 */ mapTouchListener = new MKMapTouchListener(){@Overridepublic void onMapClick(GeoPoint point) {touchType = "單擊";currentPt = point;updateMapState();}@Overridepublic void onMapDoubleClick(GeoPoint point) {touchType = "雙擊";currentPt = point;updateMapState();}@Overridepublic void onMapLongClick(GeoPoint point) {touchType = "長按";currentPt = point;updateMapState();} }; //給地圖註冊事件 mMapView.regMapTouchListner(mapTouchListener);(四)下面我們來看下百度地圖SDK中demo的例子(代碼中的注釋,在此基礎上已經添加的很詳細了)
1:MyApplication.java:進行BMapManager全域變數的設定和密鑰驗證,代碼如下:
package com.ztt.baidumap.ui;import android.app.Application;import android.content.Context;import android.util.Log;import android.widget.Toast;import com.baidu.mapapi.BMapManager;import com.baidu.mapapi.MKGeneralListener;import com.baidu.mapapi.map.MKEvent;/** * 自訂Application,進行key識別驗證 (使用單例) * @author Jiangqq * @time 2014/03/15 10:14 */public class MyApplication extends Application { public static MyApplication instance=null;BMapManager mBMapManager = null;public boolean m_bKeyRight = true; public static final String strKey = "vUAGbPwLpolIqiwWisnQPeIE"; //百度地圖官網申請的密鑰public static MyApplication getInstance(){return instance;}@Overridepublic void onCreate() {super.onCreate();instance=this;//在APP應用啟動的時候,進行初始化驗證initEngineManager(this);}/** * 進行驗證key * @param pContext */private void initEngineManager(Context pContext){ if (mBMapManager == null) { mBMapManager = new BMapManager(pContext); } if (!mBMapManager.init(strKey,new MyGeneralListener())) { Toast.makeText(MyApplication.getInstance(), "BMapManager 初始化錯誤!", Toast.LENGTH_LONG).show(); }}// 常用事件監聽,用來處理通常的網路錯誤,授權驗證錯誤等 static class MyGeneralListener implements MKGeneralListener { @Override public void onGetNetworkState(int iError) { if (iError == MKEvent.ERROR_NETWORK_CONNECT) { Toast.makeText(MyApplication.getInstance(), "您的網路出錯啦!", Toast.LENGTH_LONG).show(); } else if (iError == MKEvent.ERROR_NETWORK_DATA) { Toast.makeText(MyApplication.getInstance(), "輸入正確的檢索條件!", Toast.LENGTH_LONG).show(); }else { Log.d("zttjiangqq", "iError="+iError);} // ... } @Override public void onGetPermissionState(int iError) { //非零值表示key驗證未通過 if (iError != 0) { //授權Key錯誤: Toast.makeText(MyApplication.getInstance(), "請在 DemoApplication.java檔案輸入正確的授權Key,並檢查您的網路連接是否正常!error: "+iError, Toast.LENGTH_LONG).show(); MyApplication.getInstance().m_bKeyRight = false; } else{ MyApplication.getInstance().m_bKeyRight = true; Toast.makeText(MyApplication.getInstance(), "key認證成功", Toast.LENGTH_LONG).show(); } } }} 2:布局檔案:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="50dip"> <Button android:id="@+id/zoombutton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:text="縮放" /> <EditText android:id="@+id/zoomlevel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="10" /> <Button android:id="@+id/rotatebutton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:text="旋轉" /> <EditText android:id="@+id/rotateangle" android:text="90" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" /> <Button android:id="@+id/overlookbutton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/button_style" android:text="俯視" /> <EditText android:id="@+id/overlookangle" android:text="-30" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout> <TextView android:id="@+id/state" android:text="點擊、長按、雙擊地圖以擷取經緯度和地圖狀態" android:layout_width="fill_parent" android:layout_height="wrap_content" android:lines="3" /> <RelativeLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" /> <Button android:id="@+id/savescreen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:layout_marginTop="10dip" android:background="@drawable/button_style" android:text="" /></RelativeLayout> </LinearLayout>
3:功能實現Activity代碼:
package com.ztt.baidumap.ui;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import android.app.Activity;import android.graphics.Bitmap;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import com.baidu.mapapi.BMapManager;import com.baidu.mapapi.map.MKMapTouchListener;import com.baidu.mapapi.map.MKMapViewListener;import com.baidu.mapapi.map.MapController;import com.baidu.mapapi.map.MapPoi;import com.baidu.mapapi.map.MapView;import com.baidu.platform.comapi.basestruct.GeoPoint;/** * 示範地圖縮放,旋轉,視角控制 */public class MapControlDemo extends Activity {/** * MapView 是地圖主控制項 */private MapView mMapView = null;/** * 用MapController完成地圖控制 */private MapController mMapController = null;/** * MKMapViewListener 用於處理地圖事件回調 */MKMapViewListener mMapListener = null;/** * 用於截獲屏座標 */MKMapTouchListener mapTouchListener = null; /** * 當前地點擊點 */private GeoPoint currentPt = null; /** * 控制按鈕 */private Button zoomButton = null; //縮放private Button rotateButton = null; //旋轉private Button overlookButton =null; //俯視private Button saveScreenButton = null; ///** * */private String touchType = null;/** * 用於顯示地圖狀態的面板 */private TextView mStateBar = null; @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()); } /** * 由於MapView在setContentView()中初始化,所以它需要在BMapManager初始化之後 */ setContentView(R.layout.activity_mapcontrol); mMapView = (MapView)findViewById(R.id.bmapView); /** * 擷取地圖控制器 */ mMapController = mMapView.getController(); /** * 設定地圖是否響應點擊事件 . */ mMapController.enableClick(true); /** * 設定地圖縮放層級 */ mMapController.setZoom(12); mStateBar = (TextView) findViewById(R.id.state); /** * 初始化地圖事件監聽 */ initListener(); /** * 將地圖移動至天安門 * 使用百度經緯度座標,可以通過http://api.map.baidu.com/lbsapi/getpoint/index.html查詢地理座標 * 如果需要在百度地圖上顯示使用其他座標系統的位置,請發郵件至mapapi@baidu.com申請座標轉換介面 */ double cLat = 39.945 ; double cLon = 116.404 ; GeoPoint p = new GeoPoint((int)(cLat * 1E6), (int)(cLon * 1E6)); mMapController.setCenter(p); } /** * 添加監聽事件 */ private void initListener() { /** * 設定地圖點擊事件監聽 */ mapTouchListener = new MKMapTouchListener(){@Overridepublic void onMapClick(GeoPoint point) {touchType = "單擊";currentPt = point;updateMapState();}@Overridepublic void onMapDoubleClick(GeoPoint point) {touchType = "雙擊";currentPt = point;updateMapState();}@Overridepublic void onMapLongClick(GeoPoint point) {touchType = "長按";currentPt = point;updateMapState();} }; //給地圖註冊事件 mMapView.regMapTouchListner(mapTouchListener); /** * 設定地圖事件監聽 */ mMapListener = new MKMapViewListener() {@Overridepublic void onMapMoveFinish() {/** * 在此處理地圖移動完成回調 * 縮放,平移等操作完成後,此回調被觸發 */updateMapState();}@Overridepublic void onClickMapPoi(MapPoi mapPoiInfo) {/** * 在此處理底圖poi點擊事件 * 顯示底圖poi名稱並移動至該點 * 設定過: mMapController.enableClick(true); 時,此回調才能被觸發 * */}@Overridepublic void onGetCurrentMap(Bitmap b) {/** * 當調用過 mMapView.getCurrentMap()後,此回調會被觸發 * 可在此儲存至存放裝置 */File file = new File("/mnt/sdcard/test.png"); FileOutputStream out; try{ out = new FileOutputStream(file); if(b.compress(Bitmap.CompressFormat.PNG, 70, out)) { out.flush(); out.close(); } Toast.makeText(MapControlDemo.this, "螢幕成功,圖片存在: "+file.toString(), Toast.LENGTH_SHORT) .show(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }@Overridepublic void onMapAnimationFinish() {/** * 地圖完成帶動畫的操作(如: animationTo())後,此回調被觸發 */updateMapState();}@Overridepublic void onMapLoadFinish() {// TODO Auto-generated method stub}};mMapView.regMapViewListener(MyApplication.getInstance().mBMapManager, mMapListener);/** * 設定按鍵監聽 */zoomButton = (Button)findViewById(R.id.zoombutton);rotateButton = (Button)findViewById(R.id.rotatebutton);overlookButton = (Button)findViewById(R.id.overlookbutton);saveScreenButton = (Button)findViewById(R.id.savescreen);OnClickListener onClickListener = new OnClickListener(){@Overridepublic void onClick(View view) {if ( view.equals(zoomButton)){perfomZoom();}else if( view.equals(rotateButton)){perfomRotate();}else if( view.equals(overlookButton)){perfomOverlook();}else if ( view.equals(saveScreenButton)){//,在MKMapViewListener中儲存圖片 mMapView.getCurrentMap(); Toast.makeText(MapControlDemo.this, "正在截取螢幕圖片...", Toast.LENGTH_SHORT ).show(); }updateMapState();}};zoomButton.setOnClickListener(onClickListener);rotateButton.setOnClickListener(onClickListener);overlookButton.setOnClickListener(onClickListener);saveScreenButton.setOnClickListener(onClickListener); } /** * 處理縮放 * sdk 縮放層級範圍: [3.0,19.0] */ private void perfomZoom(){ EditText t = (EditText) findViewById(R.id.zoomlevel); try{ float zoomLevel = Float.parseFloat(t.getText().toString()); //設定地圖縮放層級 mMapController.setZoom(zoomLevel); }catch(NumberFormatException e){ Toast.makeText(this, "請輸入正確的縮放層級", Toast.LENGTH_SHORT) .show(); } } /** * 處理旋轉 * 旋轉角範圍: -180 ~ 180 , 單位:度 逆時針旋轉 */ private void perfomRotate(){ EditText t = (EditText) findViewById(R.id.rotateangle); try{ int rotateAngle = Integer.parseInt(t.getText().toString()); //設定地圖旋轉角度 mMapController.setRotation(rotateAngle); }catch(NumberFormatException e){ Toast.makeText(this, "請輸入正確的旋轉角度", Toast.LENGTH_SHORT) .show(); } } /** * 處理俯視 * 俯角範圍: -45 ~ 0 , 單位: 度 */ private void perfomOverlook(){ EditText t = (EditText) findViewById(R.id.overlookangle); try{ int overlookAngle = Integer.parseInt(t.getText().toString()); //設定地圖的俯視 mMapController.setOverlooking(overlookAngle); }catch(NumberFormatException e){ Toast.makeText(this, "請輸入正確的俯角", Toast.LENGTH_SHORT) .show(); } } /** * 更新地圖狀態顯示面板 */ private void updateMapState(){ if ( mStateBar == null){ return ; } String state = ""; if ( currentPt == null ){ state = "點擊、長按、雙擊地圖以擷取經緯度和地圖狀態"; } else{ state = String.format(touchType+",當前經度 : %f 當前緯度:%f",currentPt.getLongitudeE6()*1E-6,currentPt.getLatitudeE6()*1E-6); } state += "\n"; state += String.format("zoom level= %.1f rotate angle= %d overlaylook angle= %d", mMapView.getZoomLevel(), mMapView.getMapRotation(), mMapView.getMapOverlooking() ); mStateBar.setText(state); } @Override protected void onPause() { /** * MapView的生命週期與Activity同步,當activity掛起時需調用MapView.onPause() */ mMapView.onPause(); super.onPause(); } @Override protected void onResume() { /** * MapView的生命週期與Activity同步,當activity恢複時需調用MapView.onResume() */ mMapView.onResume(); super.onResume(); } @Override protected void onDestroy() { /** * MapView的生命週期與Activity同步,當activity銷毀時需調用MapView.destroy() */ 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); } } 4:運行:
[註明]AndroidManifest.xml的配置和之前的文章中一樣.