百度地图用过几次,往往用过即忘,疏于总结,这次归纳一下
api-key, jar导入,Menifest.xml配置参考官方文档,
基于jar包 3.6.1版,地图sdk版本不同,方法会有差异
效果图:
先上效果图:
演示操作视频:
步骤
1.初始化:
在Application中添加初始化
/**
* 初始化百度地图
*/
private void initBaiudMap() {
// 在使用 SDK 各组间之前初始化 context 信息,传入 ApplicationContext
SDKInitializer.initialize(this);
}
2.地图定位,可单独拿出来使用
定义属性:
public LocationClient mLocationClient;
public MyLocationListener mMyLocationListener;
private LocationMode tempMode = LocationMode.Battery_Saving;
private String tempcoor = "gcj02";
BDLocation location;
private EditText addressEdit
初始化定位
/**
* 初始化定位
*
* @param context
*/
public void initLocation(Context context) {
mLocationClient = new LocationClient(context);
mMyLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(mMyLocationListener);
initLocation();
mLocationClient.start();// 定位SDK
// start之后会默认发起一次定位请求,开发者无须判断isstart并主动调用request
mLocationClient.requestLocation();
}
private void initLocation() {
LocationClientOption option = new LocationClientOption();
option.setLocationMode(tempMode);// 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
// option.setCoorType(tempcoor);//可选,默认gcj02,设置返回的定位结果坐标系,
// option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);// 可选,设置是否需要地址信息,默认不需要
// option.setOpenGps(true);// 可选,默认false,设置是否使用gps
// option.setLocationNotify(true);//
// 可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
option.setIgnoreKillProcess(true);// 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
option.setOpenGps(true);// 打开gps
//设置坐标类型,不设置的话,默认类型会有偏移,误差700m
option.setCoorType("bd09ll"); // 设置坐标类型,百度地图SDK采用的是百度自有的地理坐标系(bdll09)
mLocationClient.setLocOption(option);
}
- bd09mc表示百度墨卡托坐标
- bd09ll表示百度经纬度坐标,
- gcj02表示经过国测局加密的坐标。会有1000m左右的偏移
gcj02偏移
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
System.out.println("纬度:" + String.valueOf(location.getLatitude())
+ "\n 经度:" + String.valueOf(location.getLongitude())
+ "\n地址 = " + location.getAddrStr());
if (null != addressEdit) {
addressEdit.setText(location.getAddrStr());
}
BaiduLocation.this.location = location;
}
}
初始化地图view,显示位置
MapView是用来显示地图的view,BaiduMap是MapView的操作类
/**
* 初始化地图
*/
protected void initMapView() {
// 地图初始化
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
// 定位到上海
// mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(GEO_SHANGHAI));
// 设置地图比例尺,18级。比例尺为200m
mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(16));
// 开启定位图层
mBaiduMap.setMyLocationEnabled(true);
}
效果图:
3.地理编码和反编码
com.baidu.mapapi.search.geocode.GeoCoder;是经纬度和地址信息的转化类
3.1由经纬度获取地址信息
/**
* 经纬度转地址
*
* @param arg0
*/
protected void transLatLngToAddress(LatLng latlong) {
// 初始化搜索模块,注册事件监听
mSearch = GeoCoder.newInstance();
mSearch.setOnGetGeoCodeResultListener(onResultListener);
// 反Geo搜索
mSearch.reverseGeoCode(new ReverseGeoCodeOption().location(latlong));
}
private OnGetGeoCoderResultListener onResultListener = new OnGetGeoCoderResultListener() {
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(context, "抱歉,未能找到结果", Toast.LENGTH_LONG).show();
return;
}
mBaiduMap.clear();
mBaiduMap.addOverlay(new MarkerOptions().position(
result.getLocation()).icon(
BitmapDescriptorFactory
.fromResource(R.drawable.icon_gcoding)));
// 地图移到中间
// mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(result
// .getLocation()));
// AddressComponent comp = result.getAddressDetail();
// 区。比如:闵行区
// String sss = comp.district;
Toast.makeText(context, result.getAddress(), Toast.LENGTH_LONG)
.show();
}
@Override
public void onGetGeoCodeResult(GeoCodeResult arg0) {
// TODO Auto-generated method stub
}
};
效果图:
3.2由地址信息获取经纬度
mSearch.geocode(new GeoCodeOption().city("").address(location.getAddrStr()));
4. 点击地图,显示位置信息
mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
@Override
public boolean onMapPoiClick(MapPoi arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onMapClick(LatLng arg0) {
// System.out.println("projection = "+mBaiduMap.getProjection());
//mBaiduMap.clear();
// mBaiduMap.addOverlay(new
// MarkerOptions().position(arg0).icon( BitmapDescriptorFactory.fromResource(R.drawable.icon_marka)));
// mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(arg0));
Toast.makeText(context, arg0.toString(),Toast.LENGTH_SHORT).show();
transLatLngToAddress(arg0);
}
});
效果图:
5.拖动地图显示地图中心位置信息:
/**
* 拖拽监听
*/
private void dragListener() {
// 拖拽监听
mBaiduMap
.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
@Override
public void onMapStatusChangeStart(MapStatus arg0) {
// TODO Auto-generated method stub
System.out.println("开始拖拽");
}
@Override
public void onMapStatusChangeFinish(MapStatus arg0) {
// TODO Auto-generated method stub
System.out.println("拖拽结束");
getLatlon();
}
@Override
public void onMapStatusChange(MapStatus arg0) {
// TODO Auto-generated method stub
System.out.println("拖拽中");
}
});
}
protected void getLatlon() {
MapStatus status = mBaiduMap.getMapStatus();
// 得到中心经纬度
LatLng latlon = status.target;
super.transLatLngToAddress(latlon);
}
效果图:
6.获取当前屏幕的经纬度范围,LatLngBounds类
在地图加载完成时获取
// 地图view加载完成的回调,mBaiduMap.getProjection()写在这里面,不然报null
mBaiduMap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
getLatLon();
}
});
示意图:
6.1第一种方法,由屏幕坐标得到对应的经纬度
/**
* 由屏幕坐标转换为对应的经纬度,计算屏幕的经纬度范围
*/
protected void getLatLon() {
// 屏幕左上角的坐标点
Point pointLeftTOP = new Point(0, 0);
Projection project = mBaiduMap.getProjection();
LatLng latlongLeftTOP = project.fromScreenLocation(pointLeftTOP);
int width = ScreenUtil.getScreenWidth(context);
int height = ScreenUtil.getScreenHeight(context);
System.out.println("latlong = " + latlongLeftTOP.toString()
+ ", width = " + width + ", heigth = " + height);
// 输出:latlong = latitude: 40.16998127733429, longitude:
// 116.19303294874754, width = 540, heigth = 960
// 屏幕右下角的坐标点
Point pointRightBottom = new Point(width, height);
// 由坐标点得到经纬度
LatLng latlongRightBottom = mBaiduMap.getProjection()
.fromScreenLocation(pointRightBottom);
String bounds = "latlongLeftTOP = " + latlongLeftTOP.toString()
+ ", latlongRightBottom = " + latlongRightBottom.toString();
Toast.makeText(context, bounds, Toast.LENGTH_SHORT).show();
System.out.println(bounds);
// 输出: latlongLeftTOP = latitude: 39.92848276020053, longitude:
// 116.39216931419946, latlongRightBottom = latitude: 39.89841818515667,
// longitude: 116.41558813884458
}
6.2 百度封装的方法
/**
* 用百度自带的方法获取屏幕经纬度范围
*/
private void getScreenLatlon() {
MapStatus status = mBaiduMap.getMapStatus();
// 得到地图中心对应屏幕坐标
Point point = status.targetScreen;
// 得到地图中心经纬度
LatLng latlon = status.target;
LatLngBounds bouns = status.bound;
LatLng southwest = bouns.southwest;
LatLng northeast = bouns.northeast;
System.out.println("point= " + point + ", latlon = " + latlon
+ " ,bounds = " + bouns.toString());
效果图:
7.添加多个标注并监听
7.1添加标注
用list搜集标注,便于对标注处理
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.icon_marka);
/**
* 在地图上画图标
*
* @param bean
*/
private void makerOverlay(Rows bean) {
double lat = Double.valueOf(bean.getArea_lat());
double lon = Double.valueOf(bean.getArea_lon());
// 定义Maker坐标点
LatLng point = new LatLng(lat, lon);
// 构建Marker图标
// 构建MarkerOption,用于在地图上添加Marker
MarkerOptions option = new MarkerOptions().position(point).icon(bitmap);
// 掉下动画
option.animateType(MarkerAnimateType.drop);
// 在地图上添加Marker,并显示
Overlay overLay = mBaiduMap.addOverlay(option);
Marker mMarkerA = (Marker) (overLay);
map.put(mMarkerA, bean);
}
效果图
7.2标注监听
@Override
protected void initListener() {
// 点击泡泡
mBaiduMap
.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
clickMarker(marker);
return true;
}
});
}
/**
* 点击marker事件
*
* @param marker
*/
private void clickMarker(Marker marker) {
Button button = new Button(getApplicationContext());
button.setBackgroundResource(R.drawable.popup);
OnInfoWindowClickListener listener = null;
Set<Marker> set = map.keySet();
for (Marker mark : set) {
if (mark == marker) {
final Rows data = map.get(marker);
button.setText(data.getTitle());
button.setTextColor(getResources().getColor(
android.R.color.holo_red_dark));
listener = new OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick() {
// TODO Auto-generated method stub
mBaiduMap.hideInfoWindow();
Toast.makeText(context, "点击了 id = "+data.getId()+" 的数据",
Toast.LENGTH_SHORT).show();
}
};
break;
}
}
LatLng ll = marker.getPosition();
mInfoWindow = new InfoWindow(BitmapDescriptorFactory.fromView(button),
ll, -47, listener);
mBaiduMap.showInfoWindow(mInfoWindow);
}
效果图:
8.在pc浏览器对获取的坐标验证,检验手机端获取坐标是否正确
8.1手机屏幕:
8.1.1 手机屏幕左上角坐标为:
latlongLeftTOP = latitude: 39.92848276020053, longitude: 116.39216931419946
8.1.2 截图如下:
8.2 pc端获取坐标位置
8.2.1打开百度地图,点击地图开放平台
8.2.2选取坐标拾取器
8.2.3输入坐标比较
对比结果,看出位置一致
9. 部分类说明
9.1 BDLocation类:
BDLocation location
location.getAddrStr();//详细地址,比如:中国上海市浦东新区郭守敬路498号-20号楼-101
location.getCity() //城市,比如上海市
location.getDistrict();//区,比如浦东新区
9.2 ReverseGeoCodeResult类
ReverseGeoCodeResult result;
result.getAddress() //上海市浦东新区张衡路1670号
ReverseGeoCodeResult.AddressComponent comp = result.getAddressDetail();
// 市,区,比如:上海市,浦东新区
String district =comp.city+","+ comp.district;
应用混淆
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-dontwarn com.baidu.**
保证百度类不能被混淆,否则会出现网络不可用等运行时异常
附上源码:
参考:
百度地图,Android SDK事件监听