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
相关文章
相关标签/搜索