一.定位服务
在地图开发中我们都会用到地图服务。首先是要获取位置 ,我们可以把定位这一块 写到服务里 在想用的时候直接获取。
public class LocationService extends Service implements BDLocationListener {
private LocationClient mLocationClient;
public static BDLocation mBdLocation;
private LocationClientOption.LocationMode tempMode = LocationClientOption.LocationMode.Hight_Accuracy;
private String tempcoor = "bd09ll"; //"gcj02";
public BDLocation getLastKnownLocation() {
return this.mLocationClient.getLastKnownLocation();
}
public boolean isStarted() {
return this.mLocationClient.isStarted();
}
public void registerLocationListener(BDLocationListener locationListener) {
this.mLocationClient.registerLocationListener(locationListener);
}
public void unRegisterLocationListener(BDLocationListener locationListener) {
this.mLocationClient.unRegisterLocationListener(locationListener);
}
public void disconnectLocationClient() {
if (mLocationClient != null && !mLocationClient.isStarted()) {
unRegisterLocationListener(this);
this.stop();
}
}
public void setLocOption(LocationClientOption clientOption) {
this.mLocationClient.setLocOption(clientOption);
}
public void start() {
this.mLocationClient.start();
}
public void stop() {
this.mLocationClient.stop();
}
@Override
public void onCreate() {
super.onCreate();
mLocationClient = new LocationClient(this);
LocationClientOption option = new LocationClientOption();
option.setLocationMode(tempMode);
option.setCoorType(tempcoor);
option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setOpenGps(true);//可选,默认false,设置是否使用gps
option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
option.setIgnoreKillProcess(true);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
option.setIsNeedAddress(true);
setLocOption(option);
registerLocationListener(this);
start();
mBdLocation = mLocationClient.getLastKnownLocation();
}
public void onDestroy() {
super.onDestroy();
disconnectLocationClient();
}
@Override
public void onReceiveLocation(BDLocation location) {
mBdLocation = location;
}
}
二.反地理编码
反地理编码就是通过百度的坐标定位引擎,插叙出坐标对应的物体所在的行政区划、街道等信息在地图上点击的时候,或者拖动marker的时候得到的LatLng对象,就可以通过反地理编码得到具体的地址了。
效果如下
开发步骤(不再介绍地图定位)
1.布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.baidu.mapapi.map.MapView
android:id="@+id/main_bdmap"
android:layout_width="match_parent"
android:layout_height="250dp"
android:onClick="true"></com.baidu.mapapi.map.MapView>
<ListView
android:id="@+id/main_pois"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"></ListView>
</LinearLayout>
2.获取地理编码检索(有两种方法)
(1)通过创建 GeoCoder 回调获取
/**
* 定位监听
*
* @param bdLocation
*/
@Override
public void onReceiveLocation(BDLocation bdLocation) {
//如果bdLocation为空或mapView销毁后不再处理新数据接收的位置
if (bdLocation == null || mBaiduMap == null) {
return;
}
//定位数据
MyLocationData data = new MyLocationData.Builder()
//定位精度bdLocation.getRadius()
.accuracy(bdLocation.getRadius())
//此处设置开发者获取到的方向信息,顺时针0-360
.direction(bdLocation.getDirection())
//经度
.latitude(bdLocation.getLatitude())
//纬度
.longitude(bdLocation.getLongitude())
//构建
.build();
//设置定位数据
mBaiduMap.setMyLocationData(data);
//是否是第一次定位
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(ll, 18);
mBaiduMap.animateMapStatus(msu);
}
//创建GeoCoder实例对象
geoCoder = GeoCoder.newInstance();
//发起反地理编码请求(经纬度->地址信息)
ReverseGeoCodeOption reverseGeoCodeOption = new ReverseGeoCodeOption();
//设置反地理编码位置坐标
reverseGeoCodeOption.location(new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude()));
geoCoder.reverseGeoCode(reverseGeoCodeOption);
//设置查询结果监听者
geoCoder.setOnGetGeoCodeResultListener(this);
}
//地理编码查询结果回调函数
@Override
public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
}
//反地理编码查询结果回调函数
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
List<PoiInfo> poiInfos = reverseGeoCodeResult.getPoiList();
PoiAdapter poiAdapter = new PoiAdapter(MainActivity.this, poiInfos);
poisLL.setAdapter(poiAdapter);
}
(2)通过Web服务API获取
首先要创建一个 服务端类型 的 百度地图应用
设置 ip白名单 设置为0.0.0.0/0 即可
只有IP白名单内的服务器才能成功发起调用
格式: 202.198.16.3,202.198.0.0/16 填写IP地址或IP前缀网段,英文半角逗号分隔
如果不想对IP做任何限制,请设置为0.0.0.0/0 (谨慎使用,AK如果泄露配额会被其用户
消费,上线前可以用作Debug,线上正式ak请设置合理的IP白名单)
请求 接口
http://api.map.baidu.com/geocoder/v2/?callback=renderReverse&location=39.983424,116.322987&output=json&pois=1&ak=您的ak
三。移动选址
移动选址 通过setOnMapStatusChangeListener 方法 获取 地图拖动 动作 结束 时 地图图层中心 点 的坐标
效果如下
开发步骤(不再介绍地图定位)
1.布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/main_top_RL"
android:layout_width="match_parent"
android:layout_height="250dp">
<com.baidu.mapapi.map.MapView
android:id="@+id/main_bdmap"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="true"></com.baidu.mapapi.map.MapView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@android:color/transparent"
android:src="@mipmap/baidumap_ico_poi_on" />
</RelativeLayout>
<ListView
android:id="@+id/main_pois"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"></ListView>
</LinearLayout>
2.移动选址
首先要设置
//地图状态改变相关监听
mBaiduMap.setOnMapStatusChangeListener(this);
/**
* 定位监听
*
* @param bdLocation
*/
@Override
public void onReceiveLocation(BDLocation bdLocation) {
//如果bdLocation为空或mapView销毁后不再处理新数据接收的位置
if (bdLocation == null || mBaiduMap == null) {
return;
}
//定位数据
MyLocationData data = new MyLocationData.Builder()
//定位精度bdLocation.getRadius()
.accuracy(bdLocation.getRadius())
//此处设置开发者获取到的方向信息,顺时针0-360
.direction(bdLocation.getDirection())
//经度
.latitude(bdLocation.getLatitude())
//纬度
.longitude(bdLocation.getLongitude())
//构建
.build();
//设置定位数据
mBaiduMap.setMyLocationData(data);
//是否是第一次定位
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(ll, 18);
mBaiduMap.animateMapStatus(msu);
}
//创建GeoCoder实例对象
geoCoder = GeoCoder.newInstance();
//发起反地理编码请求(经纬度->地址信息)
ReverseGeoCodeOption reverseGeoCodeOption = new ReverseGeoCodeOption();
//设置反地理编码位置坐标
reverseGeoCodeOption.location(new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude()));
geoCoder.reverseGeoCode(reverseGeoCodeOption);
//设置查询结果监听者
geoCoder.setOnGetGeoCodeResultListener(this);
}
//地理编码查询结果回调函数
@Override
public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
}
//反地理编码查询结果回调函数
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
List<PoiInfo> poiInfos = reverseGeoCodeResult.getPoiList();
PoiAdapter poiAdapter = new PoiAdapter(MainActivity.this, poiInfos);
poisLL.setAdapter(poiAdapter);
}
/**
* 手势操作地图,设置地图状态等操作导致地图状态开始改变
*
* @param mapStatus 地图状态改变开始时的地图状态
*/
@Override
public void onMapStatusChangeStart(MapStatus mapStatus) {
}
/**
* 地图状态变化中
*
* @param mapStatus 当前地图状态
*/
@Override
public void onMapStatusChange(MapStatus mapStatus) {
}
/**
* 地图状态改变结束
*
* @param mapStatus 地图状态改变结束后的地图状态
*/
@Override
public void onMapStatusChangeFinish(MapStatus mapStatus) {
//地图操作的中心点
LatLng cenpt = mapStatus.target;
geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(cenpt));
}