百度地图开发全解析

三大核心

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

posted @ 2015-12-14 22:54  朱培  阅读(518)  评论(0编辑  收藏  举报