最近学习了android 基于百度地图的开发, 以下是个人的总结和笔记。
百度地图API:
百度地图 API是一套基于Android 2.3及以上版本设备的应用程序接口。 您可以使用该套 SDK开发适用于Android系统移动设备的地图应用,通过调用地图SDK接口,您可以轻松访问百度地图服务和数据,构建功能丰富、交互性强的地图类应用程序。
要想进行百度地图开发, 首先要注册百度的开发者账号, 并申请秘钥。
申请秘钥的地址:http://lbsyun.baidu.com/index.php?title=androidsdk, 按照其流程操作即可。
每一个秘钥对应一个应用。
然后需要下载相关开发需要的库,下载地址为:http://lbsyun.baidu.com/sdk/download?selected=mapsdk_basicmap,mapsdk_searchfunction,mapsdk_lbscloudsearch,mapsdk_calculationtool,mapsdk_radar
同时,也可以下载到示例代码和类参考。(百度也在线提供了库函数的介绍)。
百度地图开发:
一 秘钥和地图权限的配置。
1. 秘钥配置:在application节点添加meta-data。
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="???" />
问号位置填写你申请的秘钥。
2. 增加“com.baidu.location.f" service , 这个service 用于地图的定位, 导航等功能。
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" > </service>3. 添加权限<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <!-- 访问一个帐户列表在Accounts Service中--> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <!-- 允许程序请求验证从AccountManager--> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <!-- 允许程序管理AccountManager中的账户列表--> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> <!--允许一个程序通过账户验证方式访问账户管理ACCOUNT_MANAGER相关信息 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 允许程序访问有关GSM网络信息--> <uses-permission android:name="android.permission.INTERNET" /> <!--允许程序打开网络套接字 --> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 允许程序改变Wi-Fi连接状态--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 允许程序访问Wi-Fi网络状态信息--> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!--访问phone状态 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!--允许程序写入外部存储,如SD卡上写文件--> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <!--允许一个程序广播常用intents--> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <!--允许读写系统设置项-->
二 MapView 和BaiduMap以下百度API对于MapView 和BaiduMap 的介绍。MapView 是一个显示地图的视图(View)。它负责从服务端获取地图数据。它将会捕捉屏幕触控手势事件。 使用这个类必须按照它的生命周期进行操控,你必须参照以下方法onCreate(Bundle)、 onResume()、onPause()、onDestroy()。等声明周期函数。在使用地图组件之前请确保已经调用了 SDKInitializer.initialize(Context) 函数以提供全局 Context 信息。BaiduMap定义 地图对象的操作方法与接口。
也就是说,MapView 是显示地图的View, BaiduMap 提供接口对于地图进行控制和显示。
1. 向layout 添加 MapView<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="example.jni.com.jili.MainActivity"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.baidu.mapapi.map.MapView android:id="@+id/bmapview" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" />......
三 定位
定位功能的接口在包:com.baidu.mapapi.map
BDLocation 回调的百度坐标类,内部封装了如经纬度、半径等属性信息
BDLocationListener 定位请求回调接口
LocationClient 定位服务的客户端。宿主程序在客户端声明此类,并调用,目前只支持在主线程中启动.LocationClientOption 配置定位SDK各配置参数,比如定位模式、定位时间间隔、坐标系类型等
示例代码如下:protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SDKInitializer.initialize(getApplicationContext()); requestWindowFeature(Window.FEATURE_NO_TITLE); /* getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);*/ setContentView(R.layout.activity_main); init(); } private void init( ){ mTypebtn=(Button)findViewById(R.id.mType) ; mapView=(MapView) findViewById(R.id.bmapview); search=(Button)findViewById(R.id.search); addr=(EditText)findViewById(R.id.addr); arrive=(Button)findViewById(R.id.arrive); MapStatusUpdate mStatusUpdate = MapStatusUpdateFactory.zoomTo(15.0f); baiduMap=mapView.getMap(); baiduMap.setMapStatus(mStatusUpdate); baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL); //定位设置 baiduMap.setMyLocationEnabled(true); //打开定位 locClient=new LocationClient(this); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);// 打开gps option.setCoorType("bd09ll");// 设置baidu经纬坐标类型 option.setIsNeedAddress(true); //返回地址信息 option.setScanSpan(1000);//设置扫描间隔。 必须大于等于1000, 否则无效 locClient.setLocOption(option); locClient.registerLocationListener(locListener); locClient.start(); } /** * 定位监听器 */ BDLocationListener locListener = new BDLocationListener() { @Override public void onConnectHotSpotMessage(String paramString, int paramInt){ //回调连接wifi是否是移动热点 } @Override public void onReceiveLocation(BDLocation location) { if (location == null || baiduMap == null) { return; } // 构造定位数据 MyLocationData locData = new MyLocationData.Builder() .accuracy(location.getRadius())// 定位精度 .direction(100)// 方向 .latitude(location.getLatitude())// 纬度 .longitude(location.getLongitude())//经度 .build(); // 设置定位数据 baiduMap.setMyLocationData(locData); latitude = location.getLatitude(); longitude = location.getLongitude(); // 第一次定位的时候,那地图中心显示为定位到的位置 if (isFirstLoc) { isFirstLoc = false; LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); // MapStatusUpdate描述地图将要发生的变化 // MapStatusUpdateFactory生成地图将要反生的变化 MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(ll); baiduMap.animateMapStatus(msu); Toast.makeText(getApplicationContext(), location.getAddrStr(), Toast.LENGTH_SHORT).show(); } } };
定位结果如下所示。
四 周边搜索
搜索POI 的接口主要在包com.baidu.mapapi.search.poi 内。
PoiSearch :POI检索接口
Poi 检索主要有附近检索,范围检索,城市检索三种。
PoiNearbySearchOption : 附近检索参数
OnGetPoiSearchResultListener :poi 检索结果回调
public PoiSearch pSearch; private void search(final String obj){ pSearch=PoiSearch.newInstance(); PoiNearbySearchOption searchOption=new PoiNearbySearchOption(); searchOption.location(new LatLng(latitude,longitude)); //将当前位置设置为搜索区域的中心点 searchOption.radius(2000); //搜索半径2公里 searchOption.keyword(obj); pSearch.searchNearby(searchOption); pSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() { @Override public void onGetPoiResult(PoiResult poiResult) { if(poiResult == null || poiResult.error== SearchResult.ERRORNO.RESULT_NOT_FOUND){ Toast.makeText(getApplicationContext(), "附近没有"+obj, Toast.LENGTH_SHORT).show(); return; } baiduMap.clear(); PoiOverlay overlay = new MyPoiOverlay(baiduMap);// 搜索poi的覆盖物 baiduMap.setOnMarkerClickListener(overlay);// 把事件分发给overlay,overlay才能处理点击事件 overlay.setData(poiResult);// 设置结果 overlay.addToMap();// 把搜索的结果添加到地图中 overlay.zoomToSpan();// 缩放地图,使所有Overlay都在合适的视野内 注: 该方法只对Marker类型的overlay有效 } @Override public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) { if(poiDetailResult==null||SearchResult.ERRORNO.RESULT_NOT_FOUND==poiDetailResult.error){ Toast.makeText(getApplicationContext(), "附近没有", Toast.LENGTH_SHORT).show(); return; } arr_lat=poiDetailResult.location.latitude; arr_lon=poiDetailResult.location.longitude; String text = poiDetailResult.getAddress()+ "::" + poiDetailResult.name; addTextOptions(text,poiDetailResult); if(arrive.getVisibility()==View.GONE) { arrive.setVisibility(View.VISIBLE); } //Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show(); } @Override public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) { } }); }
private void addTextOptions(String obj,PoiDetailResult result) { //baiduMap.clear(); LatLng latLng = result.getLocation(); TextOptions textOptions = new TextOptions(); textOptions.bgColor(0xAAFFFF00) // 設置文字覆蓋物背景顏色 .fontSize(28) // 设置字体大小 .fontColor(0xFFFF00FF)// 设置字体颜色 .text(obj) // 文字内容 // .rotate(-30) // 设置文字的旋转角度 .position(latLng);// 设置位置 baiduMap.addOverlay(textOptions); }
class MyPoiOverlay extends PoiOverlay{ public MyPoiOverlay(BaiduMap baiduMap){ super(baiduMap); } public boolean onPoiClick(int i){ PoiResult poiResult=getPoiResult(); PoiInfo poiInfo=poiResult.getAllPoi().get(i); String info=poiInfo.name +", "+poiInfo.address; Toast.makeText(getApplicationContext(), info, Toast.LENGTH_SHORT).show(); PoiDetailSearchOption detailSearchOption = new PoiDetailSearchOption(); detailSearchOption.poiUid(poiInfo.uid);//设置poi的uid pSearch.searchPoiDetail(detailSearchOption); return super.onPoiClick(i); } }
这里需要加点说明
1. 显示搜索结果需要用到PoiOverlay, 但是现在百度地图 SDK 已经将com.baidu.mapapi.overlayutil 包开源,所以不再提供com.baidu.mapapi.overlayutil 库。需要自己下载开源代码, 将其加入到你的项目中。
下载检索功能的示例代码, 位于BaiduLBS_AndroidSDK_Sample\BaiduMap_AndroidSDK_v4.2.1_Sample\BaiduMapsApiDemo\src\com\baidu\mapapi\overlayutil
2. 这里将在你点击每个搜索结果时,添加文本覆盖物(addTextOptions)百度API 提供如下几种本地覆盖物
- 圆形覆盖物: CircleOptions
- 文字覆盖物: TextOptions
- marker覆盖物: MarkerOptions
- 圆点覆盖物:DotOptions
- ground 覆盖物:GroundOverlayOptions
- 圆点覆盖物:DotOptions
- 多边形覆盖物:PolygonOptions
- 折线覆盖物:PolylineOptions
弧线覆盖物:ArcOptions
搜索结果如下图所示
五 驾车路线规划
路线规划的包是:com.baidu.mapapi.search.route
RoutePlanSearch是路径规划搜索接口,主要包括以下的方法
boolean | bikingSearch(BikingRoutePlanOption option)
发起骑行路线规划
|
void | destroy()
释放对象资源
|
boolean | drivingSearch(DrivingRoutePlanOption option)
发起驾车路线规划
|
boolean | masstransitSearch(MassTransitRoutePlanOption option)
发起跨城公共路线检索
|
static RoutePlanSearch | newInstance()
获取RoutePlan检索实例
|
void | setOnGetRoutePlanResultListener(OnGetRoutePlanResultListener listener)
设置路线检索监听者
|
boolean | transitSearch(TransitRoutePlanOption option)
发起换乘路线规划
|
boolean | walkingIndoorSearch(IndoorRoutePlanOption option)
发起室内路线规划
|
boolean | walkingSearch(WalkingRoutePlanOption option)
发起步行路线规划
|
这里只使用了驾车路线规划.
public RoutePlanSearch routePlanSearch;
private void rountSearch(double lat,double lon, double arrLat, double arrLon){
routePlanSearch = RoutePlanSearch.newInstance();
DrivingRoutePlanOption planOption=new DrivingRoutePlanOption();
PlanNode from =PlanNode.withLocation(new LatLng(lat,lon));
PlanNode to =PlanNode.withLocation(new LatLng(arrLat,arrLon));
planOption.from(from); //设置起点
planOption.to(to); // 设置终点
if(arrive.getVisibility()==View.VISIBLE) {
arrive.setVisibility(View.GONE);
}
routePlanSearch.drivingSearch(planOption);
routePlanSearch.setOnGetRoutePlanResultListener(new OnGetRoutePlanResultListener() {
@Override
public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
}
@Override
public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
}
@Override
public void onGetMassTransitRouteResult(MassTransitRouteResult massTransitRouteResult) {
}
@Override
public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
if (drivingRouteResult == null
|| SearchResult.ERRORNO.RESULT_NOT_FOUND == drivingRouteResult.error) {
Toast.makeText(getApplicationContext(), "未搜索到结果", Toast.LENGTH_SHORT).show();
return;
}
DrivingRouteOverlay drivingOverlay = new DrivingRouteOverlay(baiduMap);
baiduMap.setOnMarkerClickListener(drivingOverlay);
drivingOverlay.setData(drivingRouteResult.getRouteLines().get(0));//设置线路为搜索结果的第一条
drivingOverlay.addToMap();
drivingOverlay.zoomToSpan();
}
@Override
public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {
}
@Override
public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {
}
});
}
路线规划完成后, 用DrivingRouteOverlay添加到到地图上。 DrivingRouteOverlay 同样位于com.baidu.mapapi.overlayutil,是开源的。
规划结果如下:
源码下载地址:http://download.youkuaiyun.com/detail/shizhonghuo19870328/9789197