Baidu Map 自动定位

上一篇博文(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
@Override
public void onReceiveLocation(BDLocation bdLocation) {
//Todo
}
@Override
public 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配置”的相关说明。

最终实现效果如图。
Baidu Map 自动定位_第1张图片

(二)定位的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,设置是否使用gps
option.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 list = bdLocation.getPoiList();    // POI数据
if (list != null) {
    for (Poi p : list) {
        Log.i(Tags, p.getId() + " " + p.getName() + " " + p.getRank());
    }
}

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

你可能感兴趣的:(android-studio,定位)