Android集成百度地圖SDK

本Demo中所含功能
1:定位,顯示當前位置
2:地圖多覆蓋物(地圖描點。彈出該點的具體信息)
3:座標地址互相換算
4:POI興趣點檢索
5:線路查詢(步行,駕車,公交)
6:繪製線路(OpenGL和地圖SDK繪製)


百度地圖的api:http://lbsyun.baidu.com/

在上述所有的功能中,先完畢例如如下工做:
一、在百度地圖API控制檯建立AK, 請參考:http://lbsyun.baidu.com/index.php?

title=androidsdk/guide/keyphp

二、下載百度地圖的SDK。下載連接:http://lbsyun.baidu.com/sdk/download
      依據我的的需要下載相相應的sdk
三、將上面下載的sdk放到本身項目中的相應的Lib下 。可參考連接:http://lbsyun.baidu.com/index.php?

title=androidsdk/guide/buildprojecthtml

四、配置AndroidMainfest.xml文件:java

< uses-permission android:name ="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name ="android.permission.INTERNET" />
    <uses-permission android:name= "com.android.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name ="android.permission.WAKE_LOCK" />
    <uses-permission android:name ="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name ="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name ="android.permission.GET_TASKS" />
    <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name ="android.permission.WRITE_SETTINGS" />

    <!-- 這個權限用於進行網絡定位 -->
    <uses-permission android:name= "android.permission.ACCESS_COARSE_LOCATION" />
    <!-- 這個權限用於訪問GPS定位 -->
    <uses-permission android:name= "android.permission.ACCESS_FINE_LOCATION" />
    <!-- 用於讀取手機當前的狀態 -->
    <uses-permission android:name ="android.permission.READ_PHONE_STATE" />
    <!-- SD卡讀取權限,用戶寫入離線定位數據 -->
    <uses-permission android:name= "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name= "android.permission.BAIDU_LOCATION_SERVICE" />
    <uses-permission android:name= "android.permission.ACCES_MOCK_LOCATION" />
    <uses-permission android:name ="android.permission.ACCESS_GPS" />
    <uses-permission android:name ="android.permission.BROADCAST_STICKY" />
    <!-- 來電消音 -->
    <uses-permission android:name= "android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name= "android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name ="android.permission.RECORD_AUDIO" />
    <!-- 攝影機 -->
    <uses-permission android:name ="android.permission.CAMERA" />

注:上面的權限是個人項目中所有用到的權限。詳細可參考百度地圖和定位地圖所需要的權限。

還需要配置地圖的AK以及定位service:
        < meta-data
            android:name= "com.baidu.lbsapi.API_KEY"
            android:value= "API控制檯申請到的AK" />

     < service
            android:name= "com.baidu.location.f"
            android:enabled= "true"
            android:process= ":remote" >
        </service >

五、在Application中初始化地圖SDK
      SDKInitializer. initialize (getApplicationContext());



一、定位並且顯示當前位置
    步驟:一、初始化LocationClient 類 。並設置定位回調類(經過registerLocationListener()方法
              二、設置定位參數
              三、發起定位
              四、在回調接口中獲取定位的信息
代碼例如如下:

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.lb.baidumapdemo.db.DBConstants;
import com.lb.baidumapdemo.db.ShareDB;
import com.lb.baidumapdemo.face.LocationFace;

import android.content.Context;

/**
 * @ClassName: LocationFaceUtil
 * @Description: 定位幫助類。這個類僅僅用來作定位用
 * @author libiao
 * @date 2015 -8 -20 下午2:48:07
 *
 */
public class LocationFaceUtil implements BDLocationListener {
      private LocationFace locationFace; // 這個爲本身寫的一個接口,用來回調給外部處理
      public LocationClient mLocationClient = null;
      private Context context;

      public LocationFaceUtil(Context context, LocationFace locationFace) {
             super();
             this. locationFace = locationFace;
             this. context = context;
             mLocationClient = new LocationClient(context);
             mLocationClient.registerLocationListener(LocationFaceUtil. this);
            startLocation();
      }

      private void startLocation() {
            LocationClientOption option = new LocationClientOption();
            option.setLocationMode(LocationMode. Hight_Accuracy); // 可選,默認高精度,設置定位模式,高精度,低功耗。僅設備
            option.setCoorType( "bd09ll"); // 可選,默認gcj02,設置返回的定位結果座標系
            option.setScanSpan(0); // 可選,默認0,即僅定位一次,設置發起定位請求的間隔需要大於等於1000ms纔是有效的
            option.setIsNeedAddress( true); // 可選。設置是否需要地址信息,默認不需要
            option.setOpenGps( true); // 可選。默認false,設置是否使用 gps
            option.setLocationNotify( true); // 可選,默認false,設置是否當 gps有效時依照1S1次頻率輸出GPS結果
            option.setIsNeedLocationDescribe( true); // 可選,默認false,設置是否需要位置語義化結果。可以在BDLocation.getLocationDescribe裏獲得,結果類似於「在北京天安門附近」
            option.setIsNeedLocationPoiList( true); // 可選。默認false,設置是否需要POI結果。可以在BDLocation.getPoiList裏獲得
            option.setIgnoreKillProcess( false); // 可選。默認false,定位SDK內部是一個SERVICE。並放到了獨立進程。設置是否在stop的時候殺死這個進程,默認殺死
            option.SetIgnoreCacheException( false); // 可選,默認false,設置是否收集CRASH信息,默認收集
            option.setEnableSimulateGps( false); // 可選,默認false,設置是否需要過濾 gps仿真結果,默認需要
             mLocationClient.setLocOption(option);
             mLocationClient.start();
      }

      @Override
      public void onReceiveLocation(BDLocation arg0) {
             //注意這裏,必定要推斷BdLocation的返回值,僅僅有在getLocType()==61或者161的狀況下才表示定位成功,詳細返回的錯誤碼可參考http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/ermsg
             if (arg0.getLocType() == 61 || arg0.getLocType() == 161 && arg0.getLatitude() != 0.0) {
                   //將城市的名字存到SharedPreferences裏面
                   new ShareDB( context).save(DBConstants. CITY_NAME, arg0.getCity());
                   //將定位結果回調給locationFace的locationResult()方法
                   locationFace.locationResult(arg0);
            }
      }

}

在調用這個類的時候,咱們僅僅需要

      new LocationFaceUtil(getApplicationContext(), new LocationFace() {

                   @Override
                   public void locationResult(BDLocation location) {
                         bdLocation = location;
                        addMarker();
                  }
            });


而後回調的信息就全部在這個bdLocation裏面了,接着標註當前本身的位置。就是調用的  addMarker()方法
如下代碼中的:mBaiduMap= (MapView) findViewById(R.id.  basemap ) .getMap();
private void addMarker() {
             // 設置地圖類型 MAP_TYPE_NORMAL 普通圖。 MAP_TYPE_SATELLITE 衛星圖
             mBaiduMap.setMapType(BaiduMap. MAP_TYPE_NORMAL);
             // 開啓交通圖
             mBaiduMap.setTrafficEnabled( true);
             // 設置地圖當前級別
            MapStatusUpdate statusUpdate = MapStatusUpdateFactory.zoomTo(19);
             mBaiduMap.setMapStatus(statusUpdate);
             // 構建覆蓋物的經緯度
            LatLng latLng = new LatLng( bdLocation.getLatitude(), bdLocation.getLongitude());
             //覆蓋物顯示的圖標
            BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable. icon_gcoding);
            OverlayOptions option = new MarkerOptions().position(latLng).icon(descriptor).draggable(true);
             // 清除地圖上所有的覆蓋物
             mBaiduMap.clear();
             // 將覆蓋物加入到地圖上
             mBaiduMap.addOverlay(option);
             // 將覆蓋物設置爲地圖中心
            MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
             // 以動畫方式更新地圖狀態,動畫耗時 300 ms
             mBaiduMap.animateMapStatus(u);
             mBaiduMap.setOnMarkerClickListener(BaseMapActivity. this);
             mBaiduMap.setOnMarkerDragListener(BaseMapActivity. this);
      }

OK,到這裏定位顯示當前本身的位置的功能就已經完畢了


2:地圖多覆蓋物(地圖描點,彈出該點的具體信息
     首先。我構建了四個經緯度的點(實際中需要經過POI檢索獲得),而後循環將這些點加入到地圖界面上。並給這些點設置額外的數據。 最後給覆蓋物設置點擊事件,在點擊事件中彈出彈框
     代碼例如如下:
import android.graphics.Point;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.lb.baidumapdemo.R;
import com.lb.baidumapdemo.base.BaseActivity;

public class MarkerMapActivity extends BaseActivity implements OnMarkerClickListener,OnMapClickListener {
      private MapView mBaiduMapView; // 地圖界面
      private BaiduMap mBaiduMap; // 地圖的管理類
      private String[] titles = new String[] { "one", "two", "three", "four" };//這是是四個座標相應的四個信息
      //要放在地圖上的四個座標
      private LatLng[] latlngs = new LatLng[] { new LatLng(22.539895,114.058935), new LatLng(22.540729,114.066337),
                   new LatLng(22.543763,114.06458), new LatLng(22.538614,114.062811) };

      @Override
      protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
            setContentView(R.layout. activity_markermap);
             mBaiduMapView = (MapView) findViewById(R.id. markermap);
             mBaiduMap = mBaiduMapView.getMap();
             //設置地圖點擊事件
             mBaiduMap.setOnMapClickListener( this);
            initMarker();
      }

      private void initMarker() {
             mBaiduMap.clear(); 
            LatLng latLng = null;
            OverlayOptions overlayOptions = null;
             // 設置地圖類型 MAP_TYPE_NORMAL 普通圖。 MAP_TYPE_SATELLITE 衛星圖
             mBaiduMap.setMapType(BaiduMap. MAP_TYPE_NORMAL);
             // 開啓交通圖
             mBaiduMap.setTrafficEnabled( true);
            MapStatusUpdate statusUpdate = MapStatusUpdateFactory.zoomTo(17);
             mBaiduMap.setMapStatus(statusUpdate);
            BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable. icon_gcoding);
             //循環加入四個覆蓋物到地圖上
             for ( int i = 0; i < titles. length; i++) {
                  latLng= latlngs[i];
                  overlayOptions = new MarkerOptions().position(latLng).icon(descriptor);
                   // 將覆蓋物加入到地圖上
                  Marker marker=(Marker) mBaiduMap.addOverlay(overlayOptions);
                  Bundle bundle = new Bundle();
                  bundle.putString( "info", titles[i]+ "個");
                  marker.setExtraInfo(bundle);
            }
             // 將最後一個座標設置爲地圖中心
            MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
             mBaiduMap.setMapStatus(u);
             //設置地圖覆蓋物的點擊事件
             mBaiduMap.setOnMarkerClickListener(MarkerMapActivity. this);
            
      }

      /**
       * @Title: onMarkerClick
       * @Description: 覆蓋物點擊事件,每次點擊一個覆蓋物則會在相應的覆蓋物上顯示一個InfoWindow
       * @param marker
       * @return
       */
      @Override
      public boolean onMarkerClick(Marker marker) {
             final String msg = marker.getExtraInfo().getString( "info");
            InfoWindow mInfoWindow;
             // 生成一個TextView用戶在地圖中顯示InfoWindow
            TextView location = new TextView(getApplicationContext());
            location.setBackgroundResource(R.drawable. shape_popup);
            location.setPadding(30, 20, 30, 20);
            location.setText(msg);
             //構建彈框所在的經緯度。
             final LatLng ll = marker.getPosition();
            Point p = mBaiduMap.getProjection().toScreenLocation(ll);
            p. y -= 47; //讓彈框在Y軸偏移47
            LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);
             //依據上面配置好的參數信息,構造一個InfoWindow。
            mInfoWindow = new InfoWindow(location, llInfo, -47);
             //構建好以後,而後調用show的方法,讓彈框顯示出來
             mBaiduMap.showInfoWindow(mInfoWindow);
             //彈框點擊事件-
            location.setOnClickListener( new OnClickListener() {

                   @Override
                   public void onClick(View v) {
                        Toast. makeText(MarkerMapActivity.this, msg, Toast.LENGTH_SHORT).show();
                  }
            });
             return true;
      }
      
      /**
       * @Title: onMapClick
       * @Description: 地圖點擊事件。點擊地圖的時候要讓InfoWindow消失
       * @param arg0
       */
      @Override
      public void onMapClick(LatLng arg0) {
             mBaiduMap.hideInfoWindow();
            
      }
      
      /**
       * @Title: onMapPoiClick
       * @Description: 興趣點點擊事件
       * @param arg0
       * @return
       */
      @Override
      public boolean onMapPoiClick(MapPoi arg0) {
             return false;
      }

}


3:座標地址互相換算
     在很是多請求其中僅僅會返回經緯度的座標。並不會返回詳細的信息。這個時候需要用到座標換算成地址。
     座標反轉類:GeoCoder類,咱們可以看一下這個類的方法:


 依據上圖的方法說明,事實上咱們需要作的就明確了
  第一步:初始化GeoCoder類(調用newInstance())
  第二步:設置查詢結果監聽
  第三步:發起請求
 實際核心代碼:
         
 private GeoCoder geoCoder; // 經緯度地理位置座標反轉類
     geoCoder = GeoCoder. newInstance();
      geoCoder.setOnGetGeoCodeResultListener( this); // 設置反地理查詢監聽器
           geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(arg0.getPosition()));

  這裏是依據經緯度來獲取地址信息
   而後在如下的方法裏面回調:

      /**
       * @Title: onGetGeoCodeResult
       * @Description: 座標換算 依據地址獲得座標
       * @param arg0
       */
      @Override
      public void onGetGeoCodeResult(GeoCodeResult arg0) {

      }

      /**
       * @Title: onGetReverseGeoCodeResult
       * @Description: 座標換算,依據座標獲得地質
       * @param arg0
       */
      @Override
      public void onGetReverseGeoCodeResult(ReverseGeoCodeResult arg0) {
           //依據上面的請求以後,回調會進入到這種方法裏面來,而後在所有的地址信息在ReverseGeoCodeResult 其中
      }

4:POI興趣點檢索
    一、初始化PoiSearch類。構造檢索的參數
           檢索,可以分爲四種類型的檢索。依據咱們本身不一樣的需求,需要調用不一樣的方法。並傳入不一樣的參數


   這裏咱們先看一下範圍內檢索:  searchInBound ( PoiBoundSearchOption  option)
                                                PoiBoundSearchOption類。他有四個方法。入下圖所看到的,這裏的pageNum是從0開始的!

 

                                                 在設置pageCapacity的時候。我在測試的過程當中最大是50條。超過50默認就返回了10條(這個版本號的是50),其它的參數就很少說了。
              其它的三個檢索的方法,和這個大同小異,想要具體的瞭解可以參考:http://wiki.lbsyun.baidu.com/cms/androidsdk/doc/v3_7_0/


     二、設置Search回調接口
    三、發起搜索
             核心代碼例如如下:
             private PoiSearch mSearch ;// 搜索類
             private int pageNum = 0; // 搜索的頁數-
          private void startPointSearch () {
              mSearch = PoiSearch.newInstance();
             mSearch.setOnGetPoiSearchResultListener(this); // 檢索回調
            PoiNearbySearchOption option = new PoiNearbySearchOption();
            option.location( new LatLng( mLocation.getLatitude(), mLocation.getLongitude())); // 設置檢索的中心點
            option.pageCapacity(50); // 設置檢索的返回的每頁的內容的條數
            option.pageNum( pageNum);
            option.radius(30000); // 設置檢索的範圍,半徑。米爲單位
            option.sortType(PoiSortType. distance_from_near_to_far);// 設置排序由近到遠
            option.keyword( "美食");// 搜索關鍵字
             mSearch.searchNearby(option); // 開始檢索
             pageNum++;
      }

       @Override
      public void onGetPoiDetailResult(PoiDetailResult arg0) {

      }

      // Poi檢索的回調,所有回調的結果都在這個PoiResult裏面。咱們可以獲得很是多參數的信息
      @Override
      public void onGetPoiResult(PoiResult arg0) {
            

      }

上面的代碼中。onGetPoiResult(PoiResult arg0)方法中的PoiResult所攜帶的方法例如如下:因此可以依據咱們本身不一樣的需求來進行獲得信息進行處理。
比方:經過getAllPoi方法。可以獲得


5:線路查詢(步行,駕車,公交)
    依據4咱們可以獲得兩個POI興趣點。而後咱們就可以查詢這兩個點的線路
    線路查詢的關鍵類: RoutePlanSearch 


 從上述api中咱們可以看到。線路規劃分爲四條線路(曾經沒有發起騎行規劃線路) 。在上面的四個發起線路的方法中,都需要傳入一個參數,這裏我就僅僅解說一下 transitSearch ( TransitRoutePlanOption  option)
這裏面需要傳入一個TransitRouterPlanOption對象。咱們來看一下這個對象所有的方法:


而後咱們看到,最重要的就是這個類:PlanNode這個類,這個類不只在 TransitRouterPlanOption的方法中需要用到。在騎行線路、駕車線路、步行線路的方法中所需的對象中也都是需要設置PlanNode。
PlanNode解釋: 路徑規劃中的出行節點信息,出行節點包含:起點。終點。途經點, 出行節點信息可以經過兩種方式肯定: 1: 給定出行節點經緯度座標   2: 給定出行節點地名和城市名
so,咱們可以依據本身的詳細實際需求來設置這些參數:


看完API的解釋以後,調用方法:
一、初始化RouterPlanSearch類,並設置回調接口
二、設置線路參數信息,發起線路查詢

如下的代碼,是經過地點信息來進行線路查詢:

       private void startRouterResult( int type, String startAddr, String endAddr) {
            String cityName = new ShareDB(SearchInfoActivity.this ).getValue(DBConstants. CITY_NAME);
            PlanNode stNode = PlanNode.withCityNameAndPlaceName(cityName, startAddr);
            PlanNode enNode = PlanNode.withCityNameAndPlaceName(cityName, endAddr);
             if (type == 1) {
                   routeSearch .transitSearch(new TransitRoutePlanOption().from(stNode).to(enNode).city(cityName));
            } else if (type == 2) {
                   routeSearch .drivingSearch(new DrivingRoutePlanOption().from(stNode).to(enNode));
            } else if (type == 3) {
                   routeSearch .walkingSearch(new WalkingRoutePlanOption().from(stNode).to(enNode));
            }
      }

如下的代碼是用過經緯度來進行線路查詢的:

       private void startRouterResult( final int type, LatLng beLat, LatLng endLat) {
             /***
             * 此處應該推斷傳遞過來的經緯度是否是空的,因爲有可能不是在listInfo集合裏面取出來的數據,假設爲空,就要依據控件上的文字,進行座標反查
             * ,獲得座標。而後再調用這種方法 ||假設經緯度爲空,則用地址信息來進行線路的查詢,只是此時查詢出來的結果可能爲空
             **/
             if ( beLat != null && endLat != null) {
                  String cityName = new ShareDB(SearchInfoActivity.this ).getValue(DBConstants. CITY_NAME);
                  PlanNode stNode = PlanNode. withLocation(beLat );
                  PlanNode enNode = PlanNode. withLocation(endLat);
                   if (type == 1) {
                         routeSearch.transitSearch( new TransitRoutePlanOption().from(stNode).to(enNode).city(cityName));
                  } else if (type == 2) {
                         routeSearch.drivingSearch( new DrivingRoutePlanOption().from(stNode).to(enNode));
                  } else if (type == 3) {
                         routeSearch.walkingSearch( new WalkingRoutePlanOption().from(stNode).to(enNode));
                  }
            } 
      }

OK,如下就是獲取結果的代碼了:

       /******************** 線路查詢返回的結果 ***********************/
       // 因DrivingRouteResult、TransitRouteResult、WalkingRouteResult都是繼承SearchResult,沒有實現序列化。因此沒法經過bundle來進行傳遞到下一個頁面。

// 一、可以經過本身定義Model類來對數據進行封裝,實現序列化的接口來傳遞給下個界面 // 二、可以經過在Application類裏定義這三個類的對象,而後再此處賦值。在下一個界面的時候就直接獲得(本次就是用的這種方法) @Override public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) { closeDialog(); if (drivingRouteResult. error.toString().equals( "NO_ERROR")) { BaseApplication. drivingRouteResult = drivingRouteResult; startIntent(2); } else { Toast. makeText(SearchInfoActivity. this, "未找到路線。請又一次選擇起點或者終點" , Toast. LENGTH_SHORT).show(); } } @Override public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) { closeDialog(); if (transitRouteResult. error.toString().equals( "NO_ERROR")) { BaseApplication. transitRouteResult = transitRouteResult; startIntent(1); } else { Toast. makeText(SearchInfoActivity. this, "未找到路線。請又一次選擇起點或者終點" , Toast. LENGTH_SHORT).show(); } } @Override public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) { closeDialog(); if (walkingRouteResult. error.toString().equals( "NO_ERROR")) { BaseApplication. walkingRouteResult = walkingRouteResult; startIntent(3); } else { Toast. makeText(SearchInfoActivity. this, "未找到路線,請又一次選擇起點或者終點" , Toast. LENGTH_SHORT).show(); } } android

線路規劃就到這裏結束了,接着就是線路的繪製了。


6:繪製線路(OpenGL和地圖SDK繪製)
  步驟:一、獲得經緯度集合,從5中線路查詢中獲得的結果。比方 WalkingRouteResult. getRouteLines() 會返回一個 List<WalkingRouteLine>集合。將這個集合強行轉爲父類集合List<RouterLine>
              二、獲得List<RouterLine> 以後,獲得當中一個RouterLine對象(就是當中一條線路),調用RouterLine .getAllStep().get(i). getWayPoints();
                     當中i爲線路中的某一段線路,假設需要全部繪製完畢。則循環i取出全部的WayPoints()就能夠

             三、getWayPoint()返回的是 List <LatLng>集合,依據經緯度集合,咱們就可以開始繪製線路了
             四、繪製線路
            List<LatLng> listLat = (List<LatLng>) getIntent().getSerializableExtra( "latlng" );//獲得經緯度集合
                 // 設置地圖類型 MAP_TYPE_NORMAL 普通圖; MAP_TYPE_SATELLITE 衛星圖
             mBaiduMap.setMapType(BaiduMap. MAP_TYPE_NORMAL);
             // 開啓交通圖
             mBaiduMap.setTrafficEnabled( true);
            MapStatusUpdate statusUpdate = MapStatusUpdateFactory.zoomTo(19);
             mBaiduMap.setMapStatus(statusUpdate);
            MyLatLng myLatLng = listLat.get(0);
            MapStatusUpdate u = MapStatusUpdateFactory. newLatLng( new LatLng(myLatLng.getLatitude(), myLatLng.getLongitude()));
             mBaiduMap.setMapStatus(u);

 繪製線路的兩種辦法:
一、OpenGL繪製,代碼例如如下:
      mBaiduMap .setOnMapDrawFrameCallback(callback );
/******************** 使用OpenGl繪製,是出現Bug。座標的轉換和屏幕上的點的轉換,會隨着地圖大小的拉伸,OpenGl的線不拉伸的狀況,建議不要使用此方法 *********************/
       // 定義地圖繪製每一幀時 OpenGL 繪製的回調接口
      OnMapDrawFrameCallback callback = new OnMapDrawFrameCallback() {
             public void onMapDrawFrame(GL10 gl, MapStatus drawingMapStatus) {
                   if ( mBaiduMap.getProjection() != null) {
                         // 計算折線的 opengl 座標
                        calPolylinePoint(drawingMapStatus);
                         // 繪製折線
                        drawPolyline(gl, Color. argb(255, 255, 0, 0), vertexBuffer, 10, 3, drawingMapStatus);
                  }
            }
      };

       // 計算折線 OpenGL 座標
       public void calPolylinePoint(MapStatus mspStatus) {
            PointF[] polyPoints = new PointF[ listLat.size()];
             vertexs = new float[3 * listLat.size()];
             int i = 0;
             for (MyLatLng xy : listLat) {
                   // 將地理座標轉換成 openGL 座標
                  polyPoints[i] = mBaiduMap.getProjection().toOpenGLLocation( new LatLng(xy.getLatitude(), xy.getLongitude()), mspStatus);
                   vertexs[i * 3] = polyPoints[i]. x;
                   vertexs[i * 3 + 1] = polyPoints[i]. y;
                   vertexs[i * 3 + 2] = 0.0f;
                  i++;
            }
             vertexBuffer = makeFloatBuffer( vertexs);
      }

       // 建立OpenGL繪製時的頂點Buffer
       private FloatBuffer makeFloatBuffer( float[] fs) {
            ByteBuffer bb = ByteBuffer. allocateDirect(fs. length * 4);
            bb.order(ByteOrder. nativeOrder());
            FloatBuffer fb = bb.asFloatBuffer();
            fb.put(fs);
            fb.position(0);
             return fb;
      }

       // 繪製折線
       private void drawPolyline(GL10 gl, int color, FloatBuffer lineVertexBuffer, float lineWidth, int pointSize, MapStatus drawingMapStatus) {

            gl.glEnable(GL10. GL_BLEND);
            gl.glEnableClientState(GL10. GL_VERTEX_ARRAY);

            gl.glBlendFunc(GL10. GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );

             float colorA = Color. alpha(color) / 255f;
             float colorR = Color. red(color) / 255f;
             float colorG = Color. green(color) / 255f;
             float colorB = Color. blue(color) / 255f;

            gl.glVertexPointer(3, GL10. GL_FLOAT, 0, lineVertexBuffer);
            gl.glColor4f(colorR, colorG, colorB, colorA);
            gl.glLineWidth(lineWidth);
            gl.glDrawArrays(GL10. GL_LINE_STRIP, 0, pointSize);

            gl.glDisable(GL10. GL_BLEND);
            gl.glDisableClientState(GL10. GL_VERTEX_ARRAY);
      }


二、利用SDK繪製點、線、多邊形

/**
             * 地圖SDK提供多種結合圖形覆蓋物,利用這些圖形,可幫助您構建更加豐富多彩的地圖應用。

眼下提供的幾何圖形有:點(Dot)、折線( * Polyline)、弧線(Arc)、圓(Circle)、多邊形(Polygon)。 此處繪製折線 */ OverlayOptions polygonOption = new PolylineOptions().points(listLat ).color(Color.parseColor( "#FF0000")).width(7); // 在地圖上加入多邊形Option,用於顯示 mBaiduMap.addOverlay(polygonOption); git



這個百度地圖的集成的時間大概是2015年9月。因此SDK和最新的確定多多少少有點差別的。
GitHub下載地址(AndroidStudio):http://download.csdn.net/detail/q908555281/9472070
CSDN下載地址(Eclipse):    http://download.csdn.net/detail/q908555281/9472070

本Demo用的百度的Key爲私人的,假設要正常執行,得本身去百度地圖控制檯申請Key,來替換Mainfest中的key
相關文章
相關標籤/搜索