百度地图开发全解析
三大核心
SDKInitalizer
BaiduM
MapViewap
基本地图
增加权限重点是处理位置信息权限
Layout中添加MapView控件用于展示地图
创建管理工具,
并初使化
SDKInitializer在initialize时校验key(permission check error)和网络状态(network error),关于状态码信息我们可以在SDKInitializer查询
注意:
控制MapView的onResume、onPause、onDestroy ;
SDKInitializer对象创建一个就可以;
必须校验key,并且key值不能为空;
Initialize方法接受的参数必须是global Application,不能传递Activity。
通过MapView设置缩放控件showZoomControls(false),默认显示
缩放级别:V2.0之前支持(3-18),V2.0之后多一级(3-19)
默认的缩放级别 12
设置地图的中心位置
BaiduMap baiduMap = mapView.getMap();
double latitude = 26.8865320000; //纬度
double longitude = 112.6912620000;//经度
LatLng hmPos = new LatLng(latitude, longitude);//湖南工学院
BaiduMap地图移动、缩放、旋转:控制
动画形式移动 :animateMapStatus(MapStatusUpdate)
缩放:MapStatusUpdateFactory:
zoomOut()—缩小;zoomIn()—放大;zoomTo (float)—指 定缩放级别;zoomBy(float) —按增量缩放级别;
旋转:MapStatus
水平方向:rotate(float),旋转角范围: 0 ~ 360 , 单位:度 默认值为0度,逆时针旋转为角度增大方向,通过BaiduMap的getMapStatus() .rotate获取当前角度
俯视: overlook(float) ,俯角范围: -45 ~ 0 , 单位: 度
指南针设置:UiSettings().setCompassPosition(new Point(x, y)),坐标系原点为MapView左上顶点 ,
指南针在3D模式下自动显现,隐藏指南针UiSettings().setCompassEnabled(false)
地图图层
底图 、交通图 、卫星图
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 底图 交通图 卫星图
switch (keyCode) {
case KeyEvent.KEYCODE_1:
// 底图
// 设置地图类型 MAP_TYPE_NORMAL 普通图; MAP_TYPE_SATELLITE 卫星图
baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
baiduMap.setTrafficEnabled(false);
break;
case KeyEvent.KEYCODE_2:
// 卫星图
baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
baiduMap.setTrafficEnabled(false);
break;
case KeyEvent.KEYCODE_3:
// 交通图
// 是否打开交通图层
baiduMap.setTrafficEnabled(true);
break;
default:
break;
}
return super.onKeyDown(keyCode, event);
}
覆盖物
*本地覆盖物的抽象基类:OverlayOptions(核心类)
*绘制圆CircleOptions
// ① 创建自己
CircleOptions circleOptions = new CircleOptions();
// ② 给自己设置数据
circleOptions.center(hmPos)// 圆心
.radius(1000)// 半径 单位是米
.fillColor(0x60FF0000);// 透明度 红 绿 蓝
// .stroke(new Stroke(10, 0x600FF000));// 边框 参数1 线宽 参数2 颜色
// ③ 把覆盖物添加到地图中
baiduMap.addOverlay(circleOptions);
*文字覆盖物TextOptions
private void draw() {
TextOptions textOptions = new TextOptions();
textOptions.fontColor(0x60FF0000)
.text("指令汇地图") // 文字内容
.position(hmPos) // 位置
.fontSize(24)// 字体大小
.typeface(Typeface.SERIF);// 字体
// .rotate(30);// 旋转
baiduMap.addOverlay(textOptions);
}
面试题:
typeface
安卓自带字体有三种:对称(SERIF),不对称(SANS_SERIF)、等宽(MONOSPACE)
*marker覆盖物: MarkerOptions
BitmapDescriptor bitmapDes = BitmapDescriptorFactory
.fromResource(R.drawable.eat_icon);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(hmPos)// 设置位置
.icon(bitmapDes)// 设置图标
.draggable(true)// 设置是否可以拖拽 默认是否
.title("指令汇分部");// 设置标题
baiduMap.addOverlay(markerOptions);
添加监听——————
class MyListener implements OnMarkerClickListener{
@Override
public boolean onMarkerClick(Marker result) {
// 当点击时 更新pop的位置 设置为显示
LayoutParams params = new MapViewLayoutParams.Builder()
.layoutMode(MapViewLayoutParams.ELayoutMode.mapMode)// 按照经纬度设置位置
.position(result.getPosition())// 不能传null
.width(MapViewLayoutParams.WRAP_CONTENT)
.height(MapViewLayoutParams.WRAP_CONTENT)
.yOffset(-5)// 距离position的像素 向下是正值 向上是负值
.build();
mapview.updateViewLayout(pop, params);
pop.setVisibility(View.VISIBLE);
title.setText(result.getTitle());
return true;
}
private void initPop() {
// 加载pop 添加到mapview 设置为隐藏
pop = View.inflate(getApplicationContext(), R.layout.pop, null);
LayoutParams params = new MapViewLayoutParams.Builder()
.layoutMode(MapViewLayoutParams.ELayoutMode.mapMode)// 按照经纬度设置位置
.position(hmPos)// 不能传null 设置为mapMode时 必须设置position
.width(MapViewLayoutParams.WRAP_CONTENT)
.height(MapViewLayoutParams.WRAP_CONTENT)
.build();
mapview.addView(pop, params);
pop.setVisibility(View.INVISIBLE);
title = (TextView) pop.findViewById(R.id.title);
}
*驾车路线覆盖物:DrivingRouteOverlay
private void search() {
routePlanSearch = RoutePlanSearch.newInstance();
routePlanSearch.setOnGetRoutePlanResultListener(new MyListener());
DrivingRoutePlanOption drivingOption = new DrivingRoutePlanOption();
PlanNode from = PlanNode.withLocation(tfPos);// 创建起点
PlanNode to = PlanNode.withLocation(new LatLng(26.8865320000,112.6912620000));// 创建终点
drivingOption.from(from);// 设置起点
drivingOption.to(to);// 设置终点
List<PlanNode> nodes = new ArrayList<PlanNode>();
nodes.add(PlanNode.withCityNameAndPlaceName("湖南", "衡阳"));
drivingOption.passBy(nodes);
drivingOption.policy(DrivingRoutePlanOption.DrivingPolicy.ECAR_DIS_FIRST);// 设置策略
routePlanSearch.drivingSearch(drivingOption);
}
*步行路线覆盖物:WalkingRouteOverlay
class MyListener implements OnGetRoutePlanResultListener{
@Override
public void onGetDrivingRouteResult(DrivingRouteResult result) {}
@Override
public void onGetTransitRouteResult(TransitRouteResult result) {
}
@Override
public void onGetWalkingRouteResult(WalkingRouteResult result) {
if (result == null
|| SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error) {
Toast.makeText(getApplicationContext(), "未搜索到结果", 0).show();
return;
}
WalkingRouteOverlay overlay = new WalkingRouteOverlay(baiduMap);
baiduMap.setOnMarkerClickListener(overlay);// 把事件传递给overlay
overlay.setData(result.getRouteLines().get(0));// 设置线路为第一条
overlay.addToMap();
overlay.zoomToSpan();
}
}
*换乘路线覆盖物:TransitOverlay
private void search() {
routePlanSearch = RoutePlanSearch.newInstance();
routePlanSearch.setOnGetRoutePlanResultListener(new MyListener());
TransitRoutePlanOption transitOption = new TransitRoutePlanOption();
PlanNode from = PlanNode.withLocation(tfPos);// 创建起点
PlanNode to = PlanNode.withLocation(new LatLng(26.9046070000,
112.5954510000));// 创建终点
transitOption.from(from);
transitOption.to(to);
transitOption.city("衡阳");
transitOption.policy(TransitRoutePlanOption.TransitPolicy.EBUS_WALK_FIRST);
routePlanSearch.transitSearch(transitOption);
}
搜索
定位
public class LocationDemo extends BaseActivity {
public LocationClient mLocationClient;
public BDLocationListener myListener;
private BitmapDescriptor geo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lacate();
}
private void lacate() {
mLocationClient = new LocationClient(getApplicationContext());
myListener = new MyListener();
mLocationClient.registerLocationListener(myListener);
LocationClientOption option = new LocationClientOption();
option.setLocationMode(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有效时按照1S1次频率输出GPS结果
option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
option.setIgnoreKillProcess(false);//可选,默认false,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认杀死
option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
mLocationClient.setLocOption(option);
geo = BitmapDescriptorFactory
.fromResource(R.drawable.icon_geo);
MyLocationConfiguration configuration = new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.FOLLOWING, true, geo);
baiduMap.setMyLocationConfigeration(configuration);// 设置定位显示的模式
baiduMap.setMyLocationEnabled(true);// 打开定位图层
}
@Override
protected void onStart() {
mLocationClient.start();
super.onStart();
}
@Override
protected void onPause() {
mLocationClient.stop();
super.onPause();
}
class MyListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation result) {
if (result != null) {
MyLocationData data = new MyLocationData.Builder()
.latitude(result.getLatitude())
.longitude(result.getLongitude()).build();
baiduMap.setMyLocationData(data);
}
}
}
}
额,好吧,我承认用这个定位的时候是定位到非洲去了,可能是百度系统安全升级什么的吧,比较复杂的说,不知道是不是因为火星坐标的原因,反正折腾的我够呛,而百度官方提供的demo比较不实用,下次我如果发现更好的再分享出来咯,反正方法就是这个样子,可以看到官网上面的解释:
1、您需要确保程序编译通过。如果对自己写的代码有疑问,可以下载官方高级示例,查看标准源代码。
2、请确保网络通畅,无论是连接wifi还是使用2G/3G信号。
3、定位SDK的调用必须在主线程中。
4、必须在定位SDK启动前设定好参数,例如是否使用GPS,扫描时间间隔设置等。我们强烈建议您设置自己的prodName,并保管好,这样方便我们为您提供更好的定位服务。
5、定位SDK start之后立即执行,这种情况下很难定位成功,因为定位SDK刚开始启动还没有获取到定位信息。这时getlocation一般为null。如果是要获取位置成功,可以在listerner中添加一个判断如果strData为空,则再发起一次定位。
6、定位覆盖率大概在98%。建议打开WiFi,或者尝试走到别的地方,多试几次即可成功定位。
7、请使用真机,且插上SIM卡。在虚拟机上无法进行定位测试。
附百度地图官网链接:http://developer.baidu.com/map/index.php?title=androidsdk