Android学习 - 百度地图开发基础
什么是百度地圖API?
百度地圖移動版API(Android)是一套基于Android 1.5及以上設備的應用程序接口,通過該接口,您可以輕松訪問百度服務和數據,構建功能豐富、交互性強的地圖應用程序。百度地圖移動版API不僅包含構建地圖的基本接口,還提供了諸如地圖定位、本地搜索、路線規劃等數據服務,你可以根據自己的需要進行選擇。
面向的讀者
API是提供給那些具有一定Android編程經驗和了解面向對象概念的讀者使用。此外,讀者還應該對地圖產品有一定的了解。
您在使用中遇到任何問題,都可以通過API貼吧或交流群反饋給我們。
獲取API Key
用戶在使用API之前需要獲取百度地圖移動版APIKey,該Key與你的百度賬戶相關聯,您必須先有百度帳戶,才能獲得API KEY。并且,該KEY與您引用API的程序名稱有關,具體流程請參照獲取密鑰。
兼容性
支持Android 1.5及以上系統。
如何把API添加到我的Andoid工程中?
首先將API包括的兩個文件baidumapapi.jar和libBMapApiEngine.so拷貝到工程根目錄及libs\armeabi目錄下,并在工程屬性->Java BuildPath->Libraries中選擇“Add JARs”,選定baidumapapi.jar,確定后返回,這樣您就可以在您的程序中使用API了。
百度地圖的“Hello,World”
在Manifest中添加使用權限
<uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permissionandroid:name="android.permission.INTERNET"></uses-permission>
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>?
<uses-permissionandroid:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"></uses-permission>
在Manifest中添加Android版本支持
<supports-screensandroid:largeScreens="true"
??? android:normalScreens="true"android:smallScreens="true"
??? android:resizeable="true"android:anyDensity="true"/>
<uses-sdkandroid:minSdkVersion="3"></uses-sdk>
讓創建的地圖Activity繼承com.baidu.mapapi.MapActivity, 并import相關類
importjava.util.ArrayList;
importjava.util.List;
?
importandroid.content.Context;
importandroid.graphics.Canvas;
importandroid.graphics.Paint;
importandroid.graphics.Point;
importandroid.graphics.drawable.Drawable;
importandroid.location.Location;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.View;
importandroid.widget.Toast;
?
importcom.baidu.mapapi.BMapManager;
importcom.baidu.mapapi.GeoPoint;
importcom.baidu.mapapi.ItemizedOverlay;
importcom.baidu.mapapi.LocationListener;
importcom.baidu.mapapi.MKAddrInfo;
importcom.baidu.mapapi.MKDrivingRouteResult;
importcom.baidu.mapapi.MKGeneralListener;
importcom.baidu.mapapi.MKLocationManager;
importcom.baidu.mapapi.MKPlanNode;
import com.baidu.mapapi.MKPoiResult;
importcom.baidu.mapapi.MKSearch;
importcom.baidu.mapapi.MKSearchListener;
importcom.baidu.mapapi.MKTransitRouteResult;
importcom.baidu.mapapi.MKWalkingRouteResult;
importcom.baidu.mapapi.MapActivity;
importcom.baidu.mapapi.MapController;
importcom.baidu.mapapi.MapView;
importcom.baidu.mapapi.MyLocationOverlay;
importcom.baidu.mapapi.Overlay;
importcom.baidu.mapapi.OverlayItem;
importcom.baidu.mapapi.PoiOverlay;
importcom.baidu.mapapi.RouteOverlay;
import com.baidu.mapapi.TransitOverlay;
?
public classMyMapActivity extends MapActivity {
?????? @Override
?????? public void onCreate(BundlesavedInstanceState) {
????????????? super.onCreate(savedInstanceState);
????????????? setContentView(R.layout.main);
?????? }
?
?????? @Override
?????? protected boolean isRouteDisplayed() {
????????????? return false;
?????? }
}
在布局xml中添加地圖控件
<?xmlversion="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
?????? android:orientation="vertical"android:layout_width="fill_parent"
?????? android:layout_height="fill_parent">
?????? <TextView android:layout_width="fill_parent"
????????????? android:layout_height="wrap_content"android:text="@string/hello" />
?????? <com.baidu.mapapi.MapViewandroid:id="@+id/bmapsView"
????????????? android:layout_width="fill_parent"android:layout_height="fill_parent"
????????????? android:clickable="true"/>
</LinearLayout>
初始化地圖Activity
在地圖Activity中定義變量: BMapManager mBMapMan = null; 在onCreate方法中增加以下代碼,并將您申請的Key替換“我的Key”:
mBMapMan = newBMapManager(getApplication());
mBMapMan.init("我的Key",null);
super.initMapActivity(mBMapMan);
?
MapView mMapView =(MapView) findViewById(R.id.bmapsView);
mMapView.setBuiltInZoomControls(true);? //設置啟用內置的縮放控件
?
MapControllermMapController = mMapView.getController();?//得到mMapView的控制權,可以用它控制和驅動平移和縮放
GeoPoint point = newGeoPoint((int) (39.915 * 1E6),
??????? (int) (116.404 * 1E6));? //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6)
mMapController.setCenter(point);? //設置地圖中心點
mMapController.setZoom(12);??? //設置地圖zoom級別
Override以下方法,管理API:
@Override
protected voidonDestroy() {
??? if (mBMapMan != null) {
??????? mBMapMan.destroy();
??????? mBMapMan = null;
??? }
??? super.onDestroy();
}
@Override
protected voidonPause() {
??? if (mBMapMan != null) {
??????? mBMapMan.stop();
??? }
??? super.onPause();
}
@Override
protected voidonResume() {
??? if (mBMapMan != null) {
??????? mBMapMan.start();
??? }
??? super.onResume();
}
完成上述步驟后,運行程序,結果如下:
地圖圖層概念
地圖可以包含一個或多個圖層,每個圖層在每個級別都是由若干張圖塊組成的,它們覆蓋了地球的整個表面。例如您所看到包括街道、興趣點、學校、公園等內容的地圖展現就是一個圖層,另外交通流量的展現也是通過圖層來實現的。
底圖
基本的地圖圖層,包括若干個縮放級別,顯示基本的地圖信息,包括道路、街道、學校、公園等內容。
實時交通信息
在以下11個城市中,支持實時交通信息:北京,上海,廣州,深圳,南京,南昌,成都,重慶,武漢,大連,常州。在地圖中顯示實時交通信息示例如下:
mMapView.setTraffic(true);
運行程序,結果如下:
衛星圖
在此版本API中暫不支持。
mMapView.setSatellite(true);
實景圖
在此版本API中暫不支持。
mMapView.setStreetView(true);
地圖覆蓋物概述
所有疊加或覆蓋到地圖的內容,我們統稱為地圖覆蓋物。如標注、矢量圖形元素(包括:折線和多邊形和圓)、定位圖標等。覆蓋物擁有自己的地理坐標,當您拖動或縮放地圖時,它們會相應的移動。
地圖API提供了如下幾種覆蓋物:
Overlay:覆蓋物的抽象基類,所有的覆蓋物均繼承此類的方法,實現用戶自定義圖層顯示。
MyLocationOverlay:一個負責顯示用戶當前位置的Overlay。
ItemizedOverlay<Itemextends OverlayItem>:Overlay的一個基類,包含了一個OverlayItem列表,相當于一組分條的Overlay,通過繼承此類,將一組興趣點顯示在地圖上。
PoiOverlay:本地搜索圖層,提供某一特定地區的位置搜索服務,比如在北京市搜索“公園”,通過此圖層將公園顯示在地圖上。
RouteOverlay:步行、駕車導航線路圖層,將步行、駕車出行方案的路線及關鍵點顯示在地圖上。
TransitOverlay:公交換乘線路圖層,將某一特定地區的公交出行方案的路線及換乘位置顯示在地圖上。
覆蓋物的抽象基類:Overlay
一般來說,在MapView中添加一個Overlay需要經過以下步驟:
自定義類繼承Overlay,并Override其draw()方法,如果需要點擊、按鍵、觸摸等交互操作,還需Override onTap()等方法。
public classMyOverlay extends Overlay {
??? GeoPoint geoPoint = new GeoPoint((int)(39.915 * 1E6), (int) (116.404 * 1E6));
??? Paint paint = new Paint();
???? @Override
??? public void draw(Canvas canvas, MapViewmapView, boolean shadow) {
??????? //在天安門的位置繪制一個String
??????? Point point =mMapView.getProjection().toPixels(geoPoint, null);
??????? canvas.drawText("★這里是天安門", point.x, point.y, paint);
??? }
}
添加到MapView的覆蓋物中:
mMapView.getOverlays().add(newMyOverlay());
運行結果如下:
當前位置:MyLocationOverlay
將MyLocationOverlay添加到覆蓋物中,能夠實現在地圖上顯示當前位置的圖標以及指南針:
初始化Location模塊
// 初始化Location模塊
mLocationManager =mBMapMan.getLocationManager();
// 通過enableProvider和disableProvider方法,選擇定位的Provider
//mLocationManager.enableProvider(MKLocationManager.MK_NETWORK_PROVIDER);
//mLocationManager.disableProvider(MKLocationManager.MK_GPS_PROVIDER);
// 添加定位圖層
MyLocationOverlaymylocTest = new MyLocationOverlay(this, mMapView);
mylocTest.enableMyLocation();// 啟用定位
mylocTest.enableCompass();??? // 啟用指南針
mMapView.getOverlays().add(mylocTest);
運行結果如下:分條目覆蓋物:ItemizedOverlay
某個類型的覆蓋物,包含多個類型相同、顯示方式相同、處理方式相同的項時,使用此類:
自定義類繼承ItemizedOverlay<OverlayItem>,并Override其draw()方法,如果需要點擊、按鍵、觸摸等交互操作,還需Override onTap()等方法。
class OverItemTextends ItemizedOverlay<OverlayItem> {
??? private List<OverlayItem> GeoList =new ArrayList<OverlayItem>();
??? private Context mContext;
?
??? private double mLat1 = 39.90923;//39.9022;// point1緯度
??? private double mLon1 =116.397428;//116.3822; // point1經度
?
??? private double mLat2 = 39.9022;
??? private double mLon2 = 116.3922;
?
??? private double mLat3 = 39.917723;
??? private double mLon3 = 116.3722;
?
??? public OverItemT(Drawable marker, Context context) {
??????? super(boundCenterBottom(marker));
?
??????? this.mContext = context;
?
??????? // 用給定的經緯度構造GeoPoint,單位是微度 (度 * 1E6)
??????? GeoPoint p1 = new GeoPoint((int) (mLat1* 1E6), (int) (mLon1 * 1E6));
??????? GeoPoint p2 = new GeoPoint((int) (mLat2* 1E6), (int) (mLon2 * 1E6));
??????? GeoPoint p3 = new GeoPoint((int) (mLat3* 1E6), (int) (mLon3 * 1E6));
?
??????? GeoList.add(new OverlayItem(p1,"P1", "point1"));
??????? GeoList.add(new OverlayItem(p2,"P2", "point2"));
??????? GeoList.add(new OverlayItem(p3,"P3", "point3"));???????????
??????? populate();? //createItem(int)方法構造item。一旦有了數據,在調用其它方法前,首先調用這個方法
??? }
?
??? @Override
??? protected OverlayItem createItem(int i) {
??????? return GeoList.get(i);
??? }
?
??? @Override
??? public int size() {
??????? return GeoList.size();
??? }
?
??? @Override
??? // 處理當點擊事件
??? protected boolean onTap(int i) {
??????? Toast.makeText(this.mContext,GeoList.get(i).getSnippet(),
??????????????? Toast.LENGTH_SHORT).show();
??????? return true;
??? }
}
添加到MapView的覆蓋物中:
Drawable marker =getResources().getDrawable(R.drawable.iconmark);?
//得到需要標在地圖上的資源
mMapView.getOverlays().add(newOverItemT(marker, this));
//添加ItemizedOverlay實例到mMapView
點擊其中一個圖標,運行結果如下:
本地搜索覆蓋物:PoiOverlay
詳見詳見在POI搜索及PoiOverlay。
駕車路線覆蓋物:RouteOverlay
詳見詳見在駕車路線搜索及RouteOverlay和步行路線搜索及RouteOverlay。
換乘路線覆蓋物:TransitOverlay
詳見詳見在公交換乘路線搜索及TransitOverlay。
搜索服務
百度地圖移動版API集成搜索服務包括:位置檢索、周邊檢索、范圍檢索、公交檢索、駕乘檢索、步行檢索,通過初始化MKSearch類,注冊搜索結果的監聽對象MKSearchListener,實現異步搜索服務。首先自定義MySearchListener實現MKSearchListener接口,通過不同的回調方法,獲得搜索結果:
public classMySearchListener implements MKSearchListener {
??? @Override
??? public void onGetAddrResult(MKAddrInforesult, int iError) {??? }
???? @Override
??? public voidonGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {??? }
???? @Override
??? public void onGetPoiResult(MKPoiResultresult, int type, int iError) {???}?
??? @Override
??? public voidonGetTransitRouteResult(MKTransitRouteResult result, int iError) {??? }?
??? @Override
??? public voidonGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {??? }
}
然后初始化MKSearch類:
mMKSearch = newMKSearch();
mMKSearch.init(mBMapMan,new MySearchListener());
POI搜索及PoiOverlay
POI搜索有三種方式,根據范圍和檢索詞發起范圍檢索poiSearchInbounds,城市poi檢索poiSearchInCity,周邊檢索poiSearchNearBy,以下以周邊檢索為例介紹如何進行檢索并顯示覆蓋物PoiOverlay:
檢索天安門周邊5000米之內的KFC餐廳:
mMKSearch.poiSearchNearBy("KFC",new GeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6)), 5000);
實現MySearchListener的onGetPoiResult,并展示檢索結果:
@Override
public voidonGetPoiResult(MKPoiResult result, int type, int iError) {
??? if (result == null) {
??????? return;
??? }
??? PoiOverlay poioverlay = new PoiOverlay(MyMapActivity.this,mMapView);
??? poioverlay.setData(result.getAllPoi());
??? mMapView.getOverlays().add(poioverlay);
}
運行結果如下:
駕車路線搜索及RouteOverlay
檢索從天安門到百度大廈的駕車路線:
MKPlanNode start =new MKPlanNode();
start.pt = newGeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6));
MKPlanNode end = newMKPlanNode();
end.pt = newGeoPoint(40057031, 116307852);
// 設置駕車路線搜索策略,時間優先、費用最少或距離最短
mMKSearch.setDrivingPolicy(MKSearch.ECAR_TIME_FIRST);
mMKSearch.drivingSearch(null,start, null, end);
實現MySearchListener的onGetDrivingRouteResult,并展示檢索結果:
@Override
public voidonGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
??? if (result == null) {
?????? ?return;
??? }
??? RouteOverlay routeOverlay = newRouteOverlay(MyMapActivity.this, mMapView);
??? // 此處僅展示一個方案作為示例
???routeOverlay.setData(result.getPlan(0).getRoute(0));
??? mMapView.getOverlays().add(routeOverlay);
}
運行結果如下:步行路線搜索及RouteOverlay
方式與駕車路線搜索類似,只需將mMKSearch.drivingSearch(null, start, null, end)修改為mMKSearch.walkingSearch(null,start, null, end),實現的方法改為onGetWalkingRouteResult即可,不再贅述。
公交換乘路線搜索及TransitOverlay
檢索從天安門到百度大廈的公交換乘路線:
MKPlanNode start =new MKPlanNode();
start.pt = newGeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6));
MKPlanNode end = newMKPlanNode();
end.pt = newGeoPoint(40057031, 116307852);
// 設置乘車路線搜索策略,時間優先、最少換乘、最少步行距離或不含地鐵
mMKSearch.setTransitPolicy(MKSearch.EBUS_TRANSFER_FIRST);
mMKSearch.transitSearch("北京",start, end); //必須設置城市名
實現MySearchListener的onGetTransitRouteResult(MKTransitRouteResult, int),并展示檢索結果:
@Override
public voidonGetTransitRouteResult(MKTransitRouteResult result, int iError) {
??? if (result == null) {
??????? return;
??? }
??? TransitOverlay transitOverlay = newTransitOverlay(MyMapActivity.this, mMapView);
??? // 此處僅展示一個方案作為示例
??? transitOverlay.setData(result.getPlan(0));
??? mMapView.getOverlays().add(transitOverlay);
}
地址信息查詢
根據地理坐標查詢地址信息:
mMKSearch.reverseGeocode(newGeoPoint(40057031, 116307852));
實現MySearchListener的onGetAddrResult,得到查詢結果。
事件
定位監聽
實現方式與系統的定位監聽類似,通過MKLocationManager注冊或者移除定位監聽器:
mLocationManager =mBMapMan.getLocationManager();
LocationListenerlistener = new LocationListener() {
??? @Override
??? public void onLocationChanged(Locationlocation) {
??????? // TODO 在此處處理位置變化
??? }
};
// 注冊監聽
mLocationManager.requestLocationUpdates(listener);
// 不需要時移除監聽
mLocationManager.removeUpdates(listener);
一般事件監聽
在初始化地圖Activity時,注冊一般事件監聽,并實現MKGeneralListener的接口處理相應事件,將mBMapMan.init("我的Key", null)替換為下面的代碼:
mBMapMan.init("我的key",new MKGeneralListener() {
??? @Override
??? public void onGetPermissionState(intiError) {
??????? // TODO 返回授權驗證錯誤,通過錯誤代碼判斷原因,MKEvent中常量值。
??? }
??? @Override
??? public void onGetNetworkState(int iError) {
??????? // TODO 返回網絡錯誤,通過錯誤代碼判斷原因,MKEvent中常量值。
??? }
});
這是我在看了一天百度地圖開發以及別人的例子所理解的,都是最基礎的。不過我看的例子不是百度發布的最新的api,在新的api中這些有的已經過時,但是基本原理還是這些。幾天后我開發玩我的項目會來補全這些。
總結
以上是生活随笔為你收集整理的Android学习 - 百度地图开发基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试题整理 !=!=未看 *****面试
- 下一篇: MPAndroidChart使用记录