Baidu Map 自动定位

来源:互联网 发布:万代淘宝独角兽 编辑:程序博客网 时间:2024/05/01 02:29

上一篇博文(Hello Baidu Map)记录了如何融合Baidu Map SDK。
可以看到,地图的基本界面,放大和缩小等功能已经呈现。
本文将着重记录自动定位的实现,并简单介绍Optional定位配置和BDLocation对象。

(一)自动定位的实现

定位当前位置,需要五个步骤。

(1)创建LocationClient对象来初始化定位服务。

private LocationClient m_LocationClient = null;Context context=getApplicationContext();m_LocationClient = new LocationClient(context);

(2)使用BDLocationLisenter来接收服务端发来的定位信息。

m_LocationClient.registerLocationListener(this);
public class AroundActivity extends AppCompatActivity implements BDLocationListener
@Overridepublic void onReceiveLocation(BDLocation bdLocation) {//Todo}@Overridepublic void onConnectHotSpotMessage(String s, int i) {//Todo}

注:仅需实现“onReceiveLocation”方法就好
“onConnectHotSpotMessage”方法,用于判断连接的wifi是否为移动热点。该方法对于定位功能,意义不大。感兴趣的同学,可以参照SDK Document(文档中也是一点而过),BDLocationListener官方文档。

(3)启动定位服务。

m_LocationClient.start();

注:只有在启动定位服务后,Listener才能得到定位信息。

(4)添加marker来标识当前位置。

到步骤(3)为止,程序已可以获取到当前的位置信息(BDLocation对象)。但尚不能在界面上显示。
百度地图为多层图片层叠合成显示(瓦片图层),若要显示位置信息,需要开启定位图层,或者添加新图层。

private BaiduMap m_Map;
m_Map= mc_Around.getMap();//mc_Around为BaiduMap控件m_Map.setMyLocationEnabled(true);//若关闭定位图层,则设置为False

封装marker显示方法,并在onReceiveLocation()中调用。
方法1:开启定位图层

private void showCurrentMarker(BDLocation bdLocation){        // 构造定位数据        MyLocationData locData = new MyLocationData.Builder()                .accuracy(bdLocation.getRadius())                .direction(bdLocation.getDirection())                .latitude(bdLocation.getLatitude())                .longitude(bdLocation.getLongitude())                .build(); // 设置定位数据        m_Map.setMyLocationData(locData);        // 设置定位图层的配置(定位模式,是否允许方向信息,用户自定义定位图标)        m_CurrentMarker = BitmapDescriptorFactory                .fromResource(R.mipmap.ic_marker_red);        MyLocationConfiguration config = new MyLocationConfiguration(null, false, m_CurrentMarker);        m_Map.setMyLocationConfiguration(config);    }

注:这里需要对MyLocationConfiguration构造函数的第二个参数进行说明。若为true,marker将显示被定位者的方向,这将影响marker的显示效果(marker可能横着,或者斜着)。

方法2:添加新图层(无需开启定位图层)

private void showCurrentMarker(BDLocation bdLocation){        //定义Maker坐标点,无需开启定位图层        LatLng point = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());        //构建Marker图标        BitmapDescriptor bitmap = BitmapDescriptorFactory                .fromResource(R.mipmap.ic_marker_red);        //构建MarkerOption,用于在地图上添加Marker        OverlayOptions option = new MarkerOptions()                .position(point)                .icon(bitmap);        //在地图上添加Marker,并显示        m_Map.addOverlay(option);    }

自动定位效果如下:
这里写图片描述

注:定位功能所须权限,已在上一篇博文(Hello Baidu Map)进行了描述,此处不再重复。

(5)设置中心点
从上图效果可以看出,地图画面出现时,当前位置并非在屏幕中心。这对处女座是致命的。

    private void setMapCenter(BDLocation bdLocation){        LatLng cenpt = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());        //定义地图状态        MapStatus mMapStatus = new MapStatus.Builder().target(cenpt).zoom(18).build();        //定义MapStatusUpdate对象,以便描述地图状态将要发生的变化        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);        //改变地图状态        m_Map .setMapStatus(mMapStatusUpdate);    }

注:zoom()方法,将设置Map的缩放级别。百度地图共有23级缩放。数值越大,定位约详细。实际可用缩放级别为3至21级。

m_Map.setMaxAndMinZoomLevel(MAX_ZOOM,MIN_ZOOM);

至此,自动定位功能实现,但尚未实现实时更新。实时更新部分的实现,可参照本文第二部分,“定位的Optional配置”的相关说明。

最终实现效果如图。
这里写图片描述

(二)定位的Optional配置

定位功能还有很多配置选项,可以通过LocationClientOption对象来设置。

LocationClientOption option = new LocationClientOption();option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系int span=1000;option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要option.setOpenGps(true);//可选,默认false,设置是否使用gpsoption.setLocationNotify(true);//可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在XXX附近”option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤GPS仿真结果,默认需要m_LocationClient.setLocOption(option);

注:对于坐标系,有三种选择:bd09ll,bd09,和gcj02(默认)。有时会因为坐标系选择问题,引起定位不准确,导致marker图标无法显示。

注:setScanSpan()方法需要特殊说明。该方法定义了刷新地理位置的间隔时间,该参数以毫秒为单位,须大于等于1000ms才生效。若为0,则只刷新一次。此外,仅当AndroidManifest.xml的Application中进行了如下配置后,方法才能生效。这是一个巨坑!官方文档未找到相关的说明。

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

(三)BDLocation对象

BDLocation对象中还可以获取很多有用的信息。
例如,可以通过调用getLocType()方法,得知信息来源,或者定位异常原因。

BDLocation.TypeGpsLocation //GPS定位BDLocation.TypeNetWorkLocation//网络定位BDLocation.TypeOffLineLocation//离线定位BDLocation.TypeServerError//服务器异常BDLocation.TypeNetWorkException//网络异常BDLocation.TypeCriteriaException//手机端异常

还可以获取精度,经纬度等信息。

BDLocation.getTime();//获取定位时间BDLocation.getLocType();//获取类型类型BDLocation.getLatitude();//获取纬度信息BDLocation.getLongitude();//获取经度信息BDLocation.getRadius();//获取定位精准度BDLocation.getSpeed();// 单位:公里每小时BDLocation.getSatelliteNumber();//获取卫星数BDLocation.BDLocation.getAltitude();//获取海拔高度信息,单位米BDLocation.BDLocation.getDirection();//获取方向信息,单位度BDLocation.BDLocation.getAddrStr();//获取地址信息BDLocation.BDLocation.getOperators();//获取运营商信息

以及POI(Point of Interest)信息,即周边可游玩的去处信息。

List<Poi> list = bdLocation.getPoiList();    // POI数据if (list != null) {    for (Poi p : list) {        Log.i(Tags, p.getId() + " " + p.getName() + " " + p.getRank());    }}

至此,自动定位的功能记录完毕。之后将会总结3D Map模式,及实时通讯功能

原创粉丝点击