百度地图开发(二)--定位,lbs数据查询,路径规划

来源:互联网 发布:如何做合格淘宝客服 编辑:程序博客网 时间:2024/06/06 01:55

1 初始化
在 Application 中或 Activity,Fragment中初始化

SDKInitializer.initialize(this);

2 在xml文件中放置地图控件

 <com.baidu.mapapi.map.MapView        android:id="@+id/bmapView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:clickable="true" />

3 定位的两种方式
①直接使用LocationClient

private void initMapLoc() {        map = bmapView.getMap();        map.setTrafficEnabled(true);        // 开启定位图层        map.setMyLocationEnabled(true);        // 定位初始化        BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory                .fromResource(R.drawable.own_loc_icon);        map.setMyLocationConfigeration(new MyLocationConfiguration(                LocationMode.FOLLOWING, true, mCurrentMarker, 0xAAFFFF88,                0xAA00FF00));        mLocClient = new LocationClient(this);        mLocClient.registerLocationListener(myListener);        LocationClientOption option = new LocationClientOption();        option.setOpenGps(true); // 打开gps        option.setCoorType("bd09ll"); // 设置坐标类型        option.setScanSpan(1000);        mLocClient.setLocOption(option);        mLocClient.start();    }
/**     * 定位SDK监听函数     */    public class MyLocationListenner implements BDLocationListener {        @Override        public void onReceiveLocation(BDLocation location) {            // map view 销毁后不在处理新接收的位置            if (location == null || map == null) {                return;            }            MyLocationData locData = new MyLocationData.Builder()                    .accuracy(location.getRadius())                    // 此处设置开发者获取到的方向信息,顺时针0-360                    .direction(100).latitude(location.getLatitude())                    .longitude(location.getLongitude()).build();            map.setMyLocationData(locData);            if (isFirstLoc || hasTarget) {                isFirstLoc = false;                LatLng ll = new LatLng(location.getLatitude(),                        location.getLongitude());                MapStatus.Builder builder = new MapStatus.Builder();                builder.target(ll).zoom(12);                map.animateMapStatus(MapStatusUpdateFactory                        .newMapStatus(builder.build()));                cenpt = ll;                mLocClient.stop();            }            if (!hasTarget) {                searchCityCloud();            } else {                hasTarget = false;            }        }        public void onReceivePoi(BDLocation poiLocation) {        }    }
    @Override    protected void onDestroy() {        super.onDestroy();        // 退出时销毁定位        mLocClient.stop();        // 关闭定位图层        map.setMyLocationEnabled(false);        bmapView.onDestroy();        bmapView = null;    }    @Override    public void onPause() {        super.onPause();        bmapView.onPause();        mLocClient.stop();        CloudManager.getInstance().destroy();    }    @Override    public void onResume() {        super.onResume();        bmapView.onResume();    }

② 包装到service

/***     * Stop location service     */    @Override    protected void onStop() {        // TODO Auto-generated method stub        locationService.unregisterListener(listener); // 注销掉监听        locationService.stop(); // 停止定位服务        super.onStop();    }    @Override    protected void onStart() {        super.onStart();        // -----------location config ------------        locationService = ((TyhcApplication) getApplication()).locationService;        // 获取locationservice实例,建议应用中只初始化1个location实例,然后使用,可以参考其他示例的activity,都是通过此种方式获取locationservice实例的        locationService.registerListener(listener);        // 注册监听        int type = getIntent().getIntExtra("from", 0);        if (type == 0) {            locationService.setLocationOption(locationService                    .getDefaultLocationClientOption());        } else if (type == 1) {            locationService.setLocationOption(locationService.getOption());        }        locationService.start();// 定位SDK    }
/** * @author baidu */public class LocationService {    private LocationClient client = null;    private LocationClientOption mOption,DIYoption;    private Object  objLock = new Object();    /***     *      * @param locationContext     */    public LocationService(Context locationContext){        synchronized (objLock) {            if(client == null){                client = new LocationClient(locationContext);                client.setLocOption(getDefaultLocationClientOption());            }        }    }    /***     *      * @param listener     * @return     */    public boolean registerListener(BDLocationListener listener){        boolean isSuccess = false;        if(listener != null){            client.registerLocationListener(listener);            isSuccess = true;        }        return  isSuccess;    }    public void unregisterListener(BDLocationListener listener){        if(listener != null){            client.unRegisterLocationListener(listener);        }    }    /***     *      * @param option     * @return isSuccessSetOption     */    public boolean setLocationOption(LocationClientOption option){        boolean isSuccess = false;        if(option != null){            if(client.isStarted())                client.stop();            DIYoption = option;            client.setLocOption(option);            isSuccess = true;        }        return isSuccess;    }    public LocationClientOption getOption(){        return DIYoption;    }    /***     *      * @return DefaultLocationClientOption     */    public LocationClientOption getDefaultLocationClientOption(){        if(mOption == null){            mOption = new LocationClientOption();            mOption.setLocationMode(LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备            mOption.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;            mOption.setScanSpan(3000);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的            mOption.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要            mOption.setIsNeedLocationDescribe(true);//可选,设置是否需要地址描述            mOption.setNeedDeviceDirect(false);//可选,设置是否需要设备方向结果            mOption.setOpenGps(true); // 打开gps            mOption.setLocationNotify(false);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果            mOption.setIgnoreKillProcess(true);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死               mOption.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”            mOption.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到            mOption.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集        }        return mOption;    }    public void start()    {        synchronized (objLock)         {            if(client != null && !client.isStarted()){                client.start();            }        }    }    public void stop(){        synchronized (objLock) {            if(client != null && client.isStarted()){                client.stop();            }        }    }}

4 LBS数据查询
①数据存储:首先开发者需要将待检索数据存入LBS云;
在百度LBS开放平台中的虎鲸数据平台新建一张数据表
这里写图片描述
增加自己需要的属性字段
这里写图片描述
数据存入
这里写图片描述
②数据检索:利用SDK为开发者提供的接口检索自己的数据;
继承CloudListener接口,重载方法

@Override    public void onGetSearchResult(CloudSearchResult result, int arg1) {    }    @Override    public void onGetCloudRgcResult(CloudRgcResult arg0, int arg1) {    }    @Override    public void onGetDetailSearchResult(DetailSearchResult arg0, int arg1) {    }

初始化云管理器

CloudManager.getInstance().init(this);

发起区域搜索请求

    /**     * 区域检索     */    public void searchCityCloud() {        NearbySearchInfo info = new NearbySearchInfo();        info.ak = "此处需填入服务端的AK";        info.geoTableId = 位置数据表ID;        info.radius = 30000;        info.location = cenpt.longitude + "," + cenpt.latitude;        CloudManager.getInstance().nearbySearch(info);    }

区域检索成功后回调onGetSearchResult方法

@Override    public void onGetSearchResult(CloudSearchResult result, int arg1) {        // TODO 自动生成的方法存根        if (result != null && result.poiList != null                && result.poiList.size() > 0) {            dragView.setVisibility(View.VISIBLE);            Log.d("附近门店",                    "onGetSearchResult, result length: "                            + result.poiList.size());            BitmapDescriptor bd = BitmapDescriptorFactory                    .fromResource(R.drawable.poi_loc_icon);            LatLng ll;            LatLngBounds.Builder builder = new Builder();            for (CloudPoiInfo info : result.poiList) {// 将云数据添加到覆盖物集合中                System.out.println(info.toString());                ll = new LatLng(info.latitude, info.longitude);                ChildShopBean bean = new ChildShopBean();                bean.setAddress(info.address);                bean.setBh("" + info.extras.get("bh"));                bean.setLatitude(info.latitude);                bean.setLongitude(info.longitude);                bean.setMimg("" + info.extras.get("memberimg"));                bean.setMid(info.extras.get("memberid") + "");                bean.setPhone("" + info.extras.get("phone"));                bean.setTitle(info.title);                Bundle data = new Bundle();                data.putSerializable("shopBean", bean);                OverlayOptions oo = new MarkerOptions().icon(bd).position(ll)                        .extraInfo(data);                overlayOptions.add(oo);                map.addOverlay(oo);                builder.include(ll);            }            if (!hasTarget) { // 从搜索界面返回来,有目标店铺,不需指定第一条数据                // 指定第一条数据                Map<String, Object> hashMap = result.poiList.get(0).extras;                CloudPoiInfo info = result.poiList.get(0);                ChildShopBean bean = new ChildShopBean();                bean.setAddress(info.address);                bean.setBh((String) (hashMap.get("bh")));                bean.setLatitude(info.latitude);                bean.setLongitude(info.longitude);                bean.setMimg((String) (hashMap.get("memberimg")));                bean.setMid(hashMap.get("memberid") + "");                bean.setPhone((String) (hashMap.get("phone")));                bean.setTitle(info.title);                setShopInfo(bean);            }            hasTarget = false;            // 定义地图状态            MapStatus mMapStatus = new MapStatus.Builder().target(cenpt)                    .zoom(12).build();            // 定义MapStatusUpdate对象,以便描述地图状态将要发生的变化            MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory                    .newMapStatus(mMapStatus);            // 改变地图状态            map.setMapStatus(mMapStatusUpdate);        } else if (result.poiList != null && result.poiList.size() == 0) {            // 定义地图状态            MapStatus mMapStatus = new MapStatus.Builder().target(cenpt)                    .zoom(12).build();            // 定义MapStatusUpdate对象,以便描述地图状态将要发生的变化            MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory                    .newMapStatus(mMapStatus);            // 改变地图状态            map.setMapStatus(mMapStatusUpdate);            dragView.setVisibility(View.GONE);        }    }

由于云搜索管理器实例是静态实例,退出activity时需要销毁,否则其他activity无法使用。

CloudManager.getInstance().destroy();

点击地图上的标注

final OverlayManager overlayManager = new OverlayManager(map) {            @Override            public boolean onMarkerClick(Marker marker) {                // 因为这里复写了onMarkerClick方法所以                // mBaiduMap.setOnMarkerClickListener()无效了                // 要在                // mBaiduMap.setOnMarkerClickListener()往这里传marker;把需要实现的方法写在这里                System.out.println(marker.getExtraInfo());                Bundle bundle = marker.getExtraInfo();                if (bundle == null || !bundle.containsKey("shopBean")) {                    return false;                }                ChildShopBean bean = (ChildShopBean) bundle                        .getSerializable("shopBean");                if (bean == null) {                    return false;                }                setShopInfo(bean);                searchProcess(cenpt,                        new LatLng(bean.getLatitude(), bean.getLongitude()));                return true;            }            @Override            public List<OverlayOptions> getOverlayOptions() {                return overlayOptions;// 这个是必须要实现的,把要显示的覆盖物放在List<OverlayOptions>            }            @Override            public boolean onPolylineClick(Polyline arg0) {                // TODO Auto-generated method stub                return false;            }        };        overlayManager.addToMap();        overlayManager.zoomToSpan();        map.setOnMarkerClickListener(new OnMarkerClickListener() {            @Override            public boolean onMarkerClick(final Marker marker) {                // TODO Auto-generated method stub                overlayManager.onMarkerClick(marker);// 把marker传入就行                return true;            }        });

5 路径规划
继承 OnGetRoutePlanResultListener 接口 ,重载 6个方法

    @Override    public void onGetWalkingRouteResult(WalkingRouteResult result) {    }    @Override    public void onGetBikingRouteResult(BikingRouteResult arg0) {    }    @Override    public void onGetDrivingRouteResult(DrivingRouteResult arg0) {    }    @Override    public void onGetIndoorRouteResult(IndoorRouteResult arg0) {    }    @Override    public void onGetMassTransitRouteResult(MassTransitRouteResult arg0) {    }    @Override    public void onGetTransitRouteResult(TransitRouteResult arg0) {    }

初始化路径规划管理器

// 初始化搜索模块,注册事件监听        mSearch = RoutePlanSearch.newInstance();        mSearch.setOnGetRoutePlanResultListener(this);

查看路线

/**     * 查看路线     */    private void searchProcess(LatLng startLat, LatLng endLat) {        if (startLat == null || endLat == null) {            Toast.makeText(this, "没有选择起始点和终点", 0).show();            return;        }        iv_guide.setVisibility(View.VISIBLE);        // 处理搜索按钮响应        PlanNode stNode = PlanNode.withLocation(startLat);        PlanNode enNode = PlanNode.withLocation(endLat);        mSearch.walkingSearch((new WalkingRoutePlanOption()).from(stNode).to(                enNode));    }

这里是查看步行路线,回调onGetWalkingRouteResult方法

/**     * 步行路线规划     */    WalkingRouteLine route = null;    @Override    public void onGetWalkingRouteResult(WalkingRouteResult result) {        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {            Toast.makeText(this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();        }        if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {            // 起终点或途经点地址有岐义,通过以下接口获取建议查询信息            // result.getSuggestAddrInfo()            return;        }        if (result.error == SearchResult.ERRORNO.NO_ERROR) {            if (result.getRouteLines().size() > 0) {                // 直接显示                if (routeOverlay != null) {                    routeOverlay.removeFromMap();                }                route = result.getRouteLines().get(0);                route.setStarting(null);                route.setTerminal(null);                drawRouteLine(route);            } else {                Log.d("route result", "结果数<0");                return;            }        }    }    private void drawRouteLine(WalkingRouteLine walkingRouteLine) {        final ArrayList<OverlayOptions> list = new ArrayList<OverlayOptions>();        PolylineOptions object = new PolylineOptions();        List<LatLng> arg0 = new ArrayList<LatLng>();        List<WalkingStep> allStep = walkingRouteLine.getAllStep();        for (int i = 0; i < allStep.size(); i++) {            WalkingStep drivingStep = allStep.get(i);            List<LatLng> wayPoints = drivingStep.getWayPoints();            arg0.addAll(wayPoints);        }        object.color(Color.argb(178, 0, 78, 255)).width(10).points(arg0);        list.add(object);        OverlayManager overlayManager = new OverlayManager(map) {            @Override            public boolean onPolylineClick(Polyline arg0) {                return false;            }            @Override            public boolean onMarkerClick(Marker arg0) {                return false;            }            @Override            public List<OverlayOptions> getOverlayOptions() {                return list;            }        };        routeOverlay = overlayManager;        overlayManager.addToMap();        overlayManager.zoomToSpan();        MapStatus mMapStatus = new MapStatus.Builder().target(cenpt)                .zoom(12).build();        // 定义MapStatusUpdate对象,以便描述地图状态将要发生的变化        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory                .newMapStatus(mMapStatus);        // 改变地图状态        map.setMapStatus(mMapStatusUpdate);    }

6 加载百度地图遇到的问题
①后台前台切换时,mapview黑屏的问题。在activity失去焦点和获取焦点的过程中对mapView同样操作。

@Override    public void onPause() {        super.onPause();        bmapView.onPause();    }    @Override    public void onResume() {        super.onResume();        bmapView.onResume();    }

②android 6.0以上机型适配问题

③当GPS和Wifi都开启时,一直是离线定位成功,导致定位结果不准确,获取不到详细地址以及城市编码。
设置默认定位方式为GPS定位。

option.setPriority(LocationClientOption.GpsFirst);
0 0