Android 百度地图某区域永远在屏幕内

原理:利用百度地图的api,获取到行政区域的边界经纬度。然后依照在屏幕内的四个点(左上,左下,右上,右下):来判断边界和屏幕的关系,以此来控制地图位置。

效果,拖动地图,一旦自己定的区域范围离开屏幕,就重新确定地图的位置。

首先要获取到行政区域边界的经纬度。请参考百度地图api。或者https://blog.csdn.net/weixin_38256472/article/details/81162048这篇文章。

因为我们没必要每次都利用百度地图的api获取经纬度边界。所以,我想把它保留下来,保存为文件。以后直接读取文件的经纬度,岂不快哉。

坑一:记得调用下面的方法最好在mBaiduMap.setOnMapLoadedCallback();里面调用

坑二:如果不获取不到经纬度,画不出来看看是不是有mBaiduMap.clear();这个方法在做鬼。

注意:这个经纬度很多,log打印不全。最好的方法是在调试的时候,在AndroidStudio的logcat里面copy这个值,然后复制到txt文本里面。copy完之后的经纬度呢,嘿嘿,不能直接使用。然后把他变成json格式,然后推荐使用http://www.bejson.com/。在打印log的时候有没有发现,polyline是分成多段的,这里我们也要分成多段。然后的json文件是这样的。我这里有个例子,大家可以看一下,也可以直接用https://download.csdn.net/download/u013778491/11750649。我这里的区域是南京江北新区的,所以这包含六合区和浦口区。是这样的:

有了这个文件,我们把他放到assent目录。

然后读取这个文件

public static String readLins(Context context) {
    InputStream is = null;
    try {
        is = context.getResources().getAssets().open("js1.txt");
        Reader in = new InputStreamReader(is);
        BufferedReader bufferedReader = new BufferedReader(in);
        String line = null;
        StringBuilder stringBuilder = new StringBuilder();
        while (null != (line = bufferedReader.readLine())) {
            stringBuilder.append(line);
        }
        bufferedReader.close();
        in.close();
        is.close();
        return stringBuilder.toString();
    } catch (Exception e) {

    }
    return "";
}

这样以后每次就读取文件就可以画出边界线了。

private void DrawLines() {
    String lins = FileUtil.readLins(instance);
    try {
        org.json.JSONArray jsonArray = new org.json.JSONArray(lins);
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        List<LatLng> array1 = null;
        for (int i = 0; i < jsonArray.length(); i++) {
            org.json.JSONArray array = (org.json.JSONArray) jsonArray.get(i);
            array1 = new ArrayList<>();
            LatLng latLng = null;
            for (int j = 0; j < array.length(); j++) {
                org.json.JSONObject object = (org.json.JSONObject) array.get(j);
                Double la = object.getDouble("latitude");
                Double lo = object.getDouble("longitude");
                latLng = new LatLng(la, lo);
                array1.add(latLng);
                builder.include(latLng);
                line_poit.add(latLng);
            }
            PolylineOptions ooPolyline11 = new PolylineOptions().width(2)
                    .points(array1).dottedLine(true).color(Color.RED);
            mBaiduMap.addOverlay(ooPolyline11);
        }
        mBaiduMap.setMapStatus(MapStatusUpdateFactory
                .newLatLngBounds(builder.build()));
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

我们在画线的时候顺便把这些经纬度点都保存到集合里面line_poit

然后在mBaiduMap.setOnMapStatusChangeListener()里面使用它

mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
    @Override
    public void onMapStatusChangeStart(MapStatus mapStatus) {

    }

    @Override
    public void onMapStatusChangeStart(MapStatus mapStatus, int i) {

    }

    @Override
    public void onMapStatusChange(MapStatus mapStatus) {

    }

    @Override
    public void onMapStatusChangeFinish(MapStatus mapStatus) {
        // 地图看得见的地方的左上角坐标
        Point point1 = new Point();
        point1.x = 0;
        point1.y = 0;// 状态栏高度加标题栏高度
        // 地图看得见的地方的左下角坐标
        Point point2 = new Point();
        point2.x = 0;
        int h = instance.getWindowManager().getDefaultDisplay().getHeight();
        int w = instance.getWindowManager().getDefaultDisplay().getWidth();
        point2.y = h;
        // 地图看得见的地方的右上角坐标
        Point point3 = new Point();
        point3.x = w;
        point3.y = 0;
        // 地图看得见的地方的右下角坐标
        Point point4 = new Point();
        point4.x = w;
        point4.y = h;

        LatLng latlng1 = mBaiduMap.getProjection().fromScreenLocation(point1);
        LatLng latlng2 = mBaiduMap.getProjection().fromScreenLocation(point2);
        LatLng latlng3 = mBaiduMap.getProjection().fromScreenLocation(point3);
        LatLng latlng4 = mBaiduMap.getProjection().fromScreenLocation(point4);

        LatLngBounds.Builder b = new LatLngBounds.Builder();
        b.include(latlng1);
        b.include(latlng2);
        b.include(latlng3);
        b.include(latlng4);
        LatLng latlng_center = b.build().getCenter();
        boolean ok = false;
        boolean hasone = false;
        boolean hastwo = false;
        boolean hasthree = false;
        boolean hasfour = false;
        if (line_poit.size() > 0) {
            for (LatLng latLng : line_poit) {
                Double la = latLng.latitude;
                Double lo = latLng.longitude;
                if (la > latlng2.latitude && la < latlng3.latitude && lo > latlng2.longitude && lo < latlng3.longitude) {
                    ok = true;
                    break;
                }
            }
            if (!ok)
                for (LatLng latLng : line_poit) {
                    Double la = latLng.latitude;
                    Double lo = latLng.longitude;
                    if (la > latlng_center.latitude && lo > latlng_center.longitude) {
                        hasone = true;
                        break;
                    }
                }
            if (!ok)
                for (LatLng latLng : line_poit) {
                    Double la = latLng.latitude;
                    Double lo = latLng.longitude;
                    if (la < latlng_center.latitude && lo < latlng_center.longitude) {
                        hastwo = true;
                        break;
                    }
                }
            if (!ok)
                for (LatLng latLng : line_poit) {
                    Double la = latLng.latitude;
                    Double lo = latLng.longitude;
                    if (la < latlng_center.latitude && lo > latlng_center.longitude) {
                        hasthree = true;
                        break;
                    }
                }
            if (!ok)
                for (LatLng latLng : line_poit) {
                    Double la = latLng.latitude;
                    Double lo = latLng.longitude;
                    if (la > latlng_center.latitude && lo < latlng_center.longitude) {
                        hasfour = true;
                        break;
                    }
                }
            if (!ok) {
                if (hasone && hastwo && hasthree && hasfour) {

                } else {
                    LatLng ll = new LatLng(32.245193, 118.767211);
                    navigateTo(ll);
                }

            }
        }
    }
});
private void navigateTo(LatLng ll) {
    mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(ll));
}

到此结束!!以下可以不看。

算法解释:有些情况下,我们不需要重新定位。比如

第一个图第二个图可以用if (la > latlng2.latitude && la < latlng3.latitude && lo > latlng2.longitude && lo < latlng3.longitude) { ok = true; break; }来判断,第三个图就有点麻烦了,因为会出现这样的情况。,所以才会有下面的几个判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值