我在使用“zoomToBoundingBox()”时遇到问题。 根据我在这里读到的内容,我创建了自己的 MapView 类来在 On Layout() 中调用 ZoomToBoundingBox() 。这是我的代码:
公共(public)类 MyMapView 扩展了 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:
@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();
}
因此,计算出的边界框显然应该导致获得最大缩放级别,但事实并非如此。
第一,计算问题; onLayout()
在 onResume()
之后调用,我探索了 zoomToBoundingBox()
的代码,以下是每个数据计算的结果:
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 的缩放级别,为什么?
不管怎样,17.0的requiredLongitudeZoom并不是最好的结果。
如您所见here ,最高等级可以达到18.0。
那么我应该如何使用zoomToBoundingBox()
?
最佳答案
我遇到了同样的问题,this.mMapView.zoomToBoundingBox(boundingBox);
导致某些情况下的缩放级别不理想,因此我实现了自己的版本。
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
}
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;
}
}
请注意,该代码仅在 map View 完全初始化时才有效,否则地面分辨率的计算将失败或产生错误的结果
关于OSMDroid5 : can't get zoomToBoundingBox() working correctly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34577385/