OSMDroid5:无法让 zoomToBoundingBox() 正常工作 [英] OSMDroid5 : can't get zoomToBoundingBox() working correctly

查看:64
本文介绍了OSMDroid5:无法让 zoomToBoundingBox() 正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 ``zoomToBoundingBox()``` 时遇到问题.根据我在这里读到的内容,我创建了自己的 MapView 类来在 On Layout() 中调用 zoomToBoundingBox().这是我的代码:

I have problem to use ``zoomToBoundingBox()```. According to what I've read somewhere here, I've created my own MapView class to call zoomToBoundingBox() in On Layout(). Here is my code:

公共类 MyMapView 扩展了 MapView {

public class MyMapView extends MapView {

    public void setBoundingBox(BoundingBoxE6 boundingBox) {
        this.boundingBox = boundingBox;
    }

    private BoundingBoxE6 boundingBox = null;

    ...

    @Override
    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
        super.onLayout(arg0, arg1, arg2, arg3, arg4);

        // Now that we have laid out the map view,
        // zoom to any bounding box
        if (this.boundingBox != null) {
            this.zoomToBoundingBox(this.boundingBox);
        }
    }
}

所以,在我的片段中,我初始化了 boundingBox:

So, In my fragment I initialize the boundingBox:

@Override
public void onResume() {
    super.onResume();

    final BoundingBoxE6 boundingBox = new BoundingBoxE6( ... );
    // this gives ``N:44899816; E:5020385; S:44899001; W:5019482``

    mMapView.setBoundingBox(boundingBox);

    mMapView.invalidate();

}

因此,计算出的边界框显然应该导致获得最大缩放级别,但事实并非如此.

So, the calculated bounding box should obviously cause to get a max zoom level but it doesn't.

第一,计算问题;onLayout()onResume() 之后被调用,我探索了 zoomToBoundingBox() 的代码,这里是每个数据计算的结果:

First, problem in calculation; onLayout() is called after onResume() and I explored the code of zoomToBoundingBox() and here are the results on each data calculated:

zoomLevel = 0
maxZoomLatitudeSpan = 55.08
requiredLatitudeZoom = 14.0  // I have a big doubt on this result!
maxZoomLongitudeSpan = 472.07
requiredLongitudeZoom = 17.0  // hum well, better but not best expected value

那么 zoomToBoundingBox() 为什么会选择 14.0 的缩放级别?无论如何,requiredLongitudeZoom 17.0 并不是最好的结果.正如您在此处所见,最高等级为 18.0 是可能的.

So zoomToBoundingBox() will choose a zoom level of 14.0 why? Anyway, requiredLongitudeZoom of 17.0 is not the best result. As you can see here, the max level of 18.0 is possible.

那么我应该如何使用 zoomToBoundingBox() ?

So how should I use zoomToBoundingBox() ?

推荐答案

我遇到了同样的问题,this.mMapView.zoomToBoundingBox(boundingBox); 在某些情况下导致了次优缩放级别,所以我实现了我自己的版本.

I had the same problem that this.mMapView.zoomToBoundingBox(boundingBox); resulted in a sub-optimal zoomlevels for some situations so i Implemented my own version.

改编自 LocationMapFragment.java

private void zoomToBoundingBox(BoundingBoxE6 boundingBox) {
    GeoPoint min = new GeoPoint(boundingBox.getLatSouthE6(), boundingBox.getLonWestE6());

    GeoPoint max = new GeoPoint(boundingBox.getLatNorthE6(), boundingBox.getLonEastE6());
    ZoomUtil.zoomTo(this.mMapView, min, max);
    // this.mMapView.zoomToBoundingBox(boundingBox); this is to inexact
}

改编自 ZoomUtil.java

public class ZoomUtil {
    public static void zoomTo(MapView mapView, IGeoPoint min, IGeoPoint max) {
        MapTileProviderBase tileProvider = mapView.getTileProvider();
        IMapController controller = mapView.getController();
        IGeoPoint center = new GeoPoint((max.getLatitudeE6() + min.getLatitudeE6()) / 2, (max.getLongitudeE6() + min.getLongitudeE6()) / 2);

        // diagonale in pixels
        double pixels = Math.sqrt((mapView.getWidth() * mapView.getWidth()) + (mapView.getHeight() * mapView.getHeight()));
        final double requiredMinimalGroundResolutionInMetersPerPixel = ((double) new GeoPoint(min.getLatitudeE6(), min.getLongitudeE6()).distanceTo(max)) / pixels;
        int zoom = calculateZoom(center.getLatitude(), requiredMinimalGroundResolutionInMetersPerPixel, tileProvider.getMaximumZoomLevel(), tileProvider.getMinimumZoomLevel());
        controller.setZoom(zoom);
        controller.setCenter(center);
    }

    private static int calculateZoom(double latitude, double requiredMinimalGroundResolutionInMetersPerPixel, int maximumZoomLevel, int minimumZoomLevel) {
        for (int zoom = maximumZoomLevel; zoom >= minimumZoomLevel; zoom--) {
            if (TileSystem.GroundResolution(latitude, zoom) > requiredMinimalGroundResolutionInMetersPerPixel)
                return zoom;
        }

        return NO_ZOOM;
    }
}

请注意,代码仅在完全初始化地图视图时才有效,否则地面分辨率的计算会失败或产生错误的结果

Note that the code only works if the mapview is initialized completely else the calculation of the ground resolution fails or produces wrong results

这篇关于OSMDroid5:无法让 zoomToBoundingBox() 正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆