Android Frament中的百度地图开发《三》通过POI添加特定区域边界、覆盖物

1、准备工作

地图的显示及定位参考我的上两篇博客,本篇实现通过POI获取区域边界坐标并添加覆盖物的功能

2、布局文件

在之前的基础上添加手动显示覆盖物的按钮

<Button
        android:id="@+id/weilan"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        android:layout_marginTop="60dp"
        android:background="@color/white"
        android:text="围"/>
3、主代码

这里的代码为之前基础上添加后的全部代码

public class map_content extends Fragment{
    private View view;
    private ImageView dingwei;
    private Button weilan;
    private TextureMapView mMapView = null;
    private BaiduMap mBaiduMap = null;
    private LocationClient mLocationClient = null;
    //防止每次定位都重新设置中心点和marker
    private boolean isFirstLocation = true;
    //注册LocationListener监听器
    MyLocationListener myLocationListener = new MyLocationListener();
    //经纬度
    private double lat;
    private double lon;
    //POI实例
    private PoiSearch poiSearch;
    
    public static Fragment newInstance(){
        map_content mapContent = new map_content();
        return maptContent;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在使用SDK各组件之前初始化context信息,传入ApplicationContext
        SDKInitializer.initialize(getActivity().getApplicationContext());
        //自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
        //包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
        SDKInitializer.setCoordType(CoordType.BD09LL);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.wuye_xqjs_xqdt,null);

        init();

        mBaiduMap = mMapView.getMap();
        mBaiduMap.setMyLocationEnabled(true);//开启地图的定位图层

        initMap();

        return view;
    }

    private void init(){
        mMapView = view.findViewById(R.id.bmapView);
        dingwei = view.findViewById(R.id.dingwei);
        weilan = view.findViewById(R.id.weilan);   
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        dingwei.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mLocationClient.requestLocation();
                LatLng ll =new LatLng(lat,lon);
                MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
                mBaiduMap.animateMapStatus(u);
                mBaiduMap.setMapStatus(u);
                MapStatusUpdate u1 = MapStatusUpdateFactory.zoomTo(16f);        //缩放
                mBaiduMap.animateMapStatus(u1);
            }
        });

        weilan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                searchInCity("此处传入要搜索的区域具体地址名,如中国地质大学(北京)");
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        isFirstLocation = true;//每次重新进入Fragement时修改为true,保证能够显示中心点
        searchInCity("此处传入要搜索的区域具体地址名,如中国地质大学(北京)");//每次重新进入Fragment时自动执行一次POI并显示覆盖物,若自动显示失败,则需手动点击按钮显示区域覆盖物
        mMapView.onResume();
    }
    @Override
    public void onPause() {
        super.onPause();
        //每次切换到其他Fragment时销毁定位,防止黑屏
        mLocationClient.unRegisterLocationListener(myLocationListener);
        mLocationClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mMapView.onPause();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        // 退出时销毁定位
        mLocationClient.unRegisterLocationListener(myLocationListener);
        mLocationClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        mMapView = null;
    }

    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //mapView 销毁后不在处理新接收的位置
            if (location == null || mMapView == null){
                return;
            }
            lat = location.getLatitude();
            lon = location.getLongitude();
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    // 此处设置开发者获取到的方向信息,顺时针0-360
                    .direction(location.getDirection())
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude()).build();

            //这个判断是为了防止每次定位都重新设置中心点和marker
            if (isFirstLocation) {
                isFirstLocation = false;
                //设置并显示中心点
                mBaiduMap.setMyLocationData(locData);
            }

        }
    }

    public void initMap(){
        //定位初始化
        mLocationClient = new LocationClient(getActivity().getApplicationContext());
        //通过LocationClientOption设置LocationClient相关参数
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(1000);

        //设置locationClientOption
        mLocationClient.setLocOption(option);
        mLocationClient.registerLocationListener(myLocationListener);
        //开启地图定位图层
        mLocationClient.start();

        //定位图标样式,采用默认图标,不显示精度外圈
        MyLocationConfiguration myLocationConfiguration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING,true,(BitmapDescriptor)null);
        myLocationConfiguration.accuracyCircleFillColor = 0x00000000;
        myLocationConfiguration.accuracyCircleStrokeColor = 0x00000000;
        mBaiduMap.setMyLocationConfiguration(myLocationConfiguration);
        //poi实例
        poiSearch = PoiSearch.newInstance();
    }
    /**
    *通过传参的形式进行城市POI,不知道为什么只有通过传参的形式输入具体地址名才能检索到,直接在keyword("")中放地址名很难检索出来
    */
    public void searchInCity(String keyword){
        // 设置检索参数
        PoiCitySearchOption citySearchOption = new PoiCitySearchOption();
        citySearchOption.city("北京");// 城市
        citySearchOption.keyword(keyword);// 关键字
        citySearchOption.pageCapacity(15);// 默认每页10条
        citySearchOption.pageNum(0);// 分页编号
        //搜索监听
        poiSearch.setOnGetPoiSearchResultListener(poiSearchListener);
        // 为PoiSearch设置搜索方式.
        poiSearch.searchInCity(citySearchOption);
    }

    OnGetPoiSearchResultListener poiSearchListener = new OnGetPoiSearchResultListener() {
        // 获取poiResult
        @Override
        public void onGetPoiResult(PoiResult poiResult) {
            if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {
                List<PoiInfo> poiList = poiResult.getAllPoi();
                String uid = poiList.get(0).uid;
                //通过uid进行地址访问,获取返回的json数据,捕获区域坐标
                String address = "http://map.baidu.com/?pcevaname=pc4.1&qt=ext&ext_ver=new&l=12&uid="+uid;

                //根据uid地址获取坐标
                HttpUtils.sendRequestWithOkhttp(address, new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {

                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String points = HttpUtils.parseJsonWithJsonObject(response);
                        //边界点
                        List<String[]> pointList = coordinateChange(points);
                        //中心点
                        List<Double> centerPoint = getCenterPoint(points);
                        addPolygon(pointList,centerPoint);
                    }
                });
            }else {
                Toast.makeText(getContext(),""+poiResult.error,Toast.LENGTH_SHORT).show();
                //因为每次进入地图自动POI时,总会POI失败受到PERMISSION_UNFINISHED错误返回信息,所以我的解决方法是一旦受到错误信息,就再POI一次,为了防止OOM建议大家加上次数限制
                searchInCity(current_com);
            }
        }
        // 当点击覆盖物的时候,查询详细的数据信息,作为回调返回数据信息
        @Override
        public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {

        }

        @Override
        public void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {

        }

        @Override
        public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
        }
    };

    /**
     * 区域边界坐标提取
     * @param mipoint
     * @return
     */
    public List<String[]> coordinateChange(String mipoint){
        String[] points1 = mipoint.split("-");
        String[] points2 = points1[1].replace(";","").split(",");

        List<String[]> points3 = new ArrayList<String[]>();

        for(int i=0;i<points2.length;i++){
            String[] temps = new String[2];
            temps[0] = points2[i];
            temps[1] = points2[i+1];
            points3.add(temps);
            i++;
        }
        return points3;
    }
   /**
   *提取区域中心点
   */
    public List<Double> getCenterPoint(String points){
        String[] points1 = points.split("-");
        String[] points2 = points1[0].split(";");//4|123243.4,54534.5   12334.5,323435.4|1
        String[] points3 = points2[0].split("\\|");//4  123243.4,54534.5
        String[] points4 = points2[1].split("\\|");//12334.5,323435.4   1
        String[] points5 = points3[1].split(",");//123243.4  54534.5
        String[] points6 = points4[0].split(",");//12334.5  323435.4
        Double x = (Double.valueOf(points5[0])+Double.valueOf(points6[0]))/2;
        Double y = (Double.valueOf(points5[1])+Double.valueOf(points6[1]))/2;

        List<Double> center = new ArrayList<Double>();
        center.add(x);
        center.add(y);
        return center;
    }

    /**
     * 添加多边形覆盖物
     * @param list
     */
    public void addPolygon(List<String[]> list,List<Double> center){
        //多边形顶点位置
        List<LatLng> points = new ArrayList<>();

        //因为获取到的坐标的墨卡托坐标,是米制坐标,需要转换成百度经纬度坐标
        for(int i=0;i<list.size();i++){
            Double lng = Double.valueOf(list.get(i)[0]);
            Double lat = Double.valueOf(list.get(i)[1]);
            LatLng sourceLatLng = new LatLng(lat,lng);
            // sourceLatLng待转换坐标
            CoordinateConverter converter  = new CoordinateConverter()
                    .from(CoordinateConverter.CoordType.BD09MC)
                    .coord(sourceLatLng);

            LatLng point = converter.convert();
            points.add(point);
        }
        //构造PolygonOptions
        PolygonOptions mPolygonOptions = new PolygonOptions()
                .points(points)
                .fillColor(0x5500CCFF) //填充颜色
                .stroke(new Stroke(5, 0xFFFF3300)); //边框宽度和颜色

        mBaiduMap.addOverlay(mPolygonOptions);

        //处理区域中心点坐标
        LatLng sourceLatLng1 = new LatLng(center.get(1),center.get(0));
        // sourceLatLng待转换坐标
        CoordinateConverter converter1  = new CoordinateConverter()
                .from(CoordinateConverter.CoordType.BD09MC)
                .coord(sourceLatLng1);
        LatLng centerPoint = converter1.convert();

        //缩放到围栏区域
        mLocationClient.requestLocation();
        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(centerPoint);
        mBaiduMap.animateMapStatus(u);
        mBaiduMap.setMapStatus(u);
        MapStatusUpdate u1 = MapStatusUpdateFactory.zoomTo(17f);        //缩放
        mBaiduMap.animateMapStatus(u1);
    }

}
4、网络处理工具代码

使用的框架是okhttp3
在builde.gradle(Module:app)中的dependencies中添加:

implementation 'com.squareup.okhttp3:okhttp:3.4.1'

工具类代码:

public class HttpUtils {
    public static void sendRequestWithOkhttp(String address, Callback callback){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(address).build();
        client.newCall(request).enqueue(callback);
    }

    public static String parseJsonWithJsonObject(Response response) throws IOException{
        String responseData = response.body().string();
        String geo = null;
        //具体的json数据解析请视自己收到的json数据组成而定
        try {
            JSONObject result = new JSONObject(responseData);
            JSONObject content = result.getJSONObject("content");
            geo = content.getString("geo");
        }catch (JSONException e){
            e.printStackTrace();
        }
        return geo;
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值