调整 MKMapView 大小后的 ZoomScale 不等于绘制 MKOverlay 时的 ZoomScale

Ana*_*sia 1 objective-c mapkit ios mkoverlay mkmapviewdelegate

我有一个使用 MapKit 的应用程序。
我在调整地图大小后计算当前缩放。
通过定义(来自MKGeometry.h文件)

MKZoomScale provides a conversion factor between MKMapPoints and screen points.
When MKZoomScale = 1, 1 screen point = 1 MKMapPoint.  When MKZoomScale is
0.5, 1 screen point = 2 MKMapPoints.
Run Code Online (Sandbox Code Playgroud)

所以,我是这样计算的:

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    CGSize screenSize = mapView.bounds.size;
    MKMapRect mapRect = mapView.visibleMapRect;
    MKZoomScale zoomScale = screenSize.width * screenSize.height / (mapRect.size.width * mapRect.size.height);
}
Run Code Online (Sandbox Code Playgroud)

计算结果zoomScale符合定义(我已经检查过)。

我还在方法中的 mapView 上绘制了一个叠加层

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
Run Code Online (Sandbox Code Playgroud)

问题是,我的计算结果zoomScale不等于系统传递给该方法的结果。我希望它们相等,因为drawMapRect:在调整大小后立即调用(实际上,调整大小会导致调用此方法)。

这里有什么问题吗?

我也尝试使用

currentZoomScale = mapView.bounds.size.width / mapView.visibleMapRect.size.width;
Run Code Online (Sandbox Code Playgroud)

这里建议,但这currentZoomScale也不等于传递给drawMapRect:

Ric*_*hin 5

我和一位同事今天确实发现了一些奇怪的现象,这可能可以解释这种行为:MKZoomScale传递到该drawMapRect:方法中的 始终反映在 中绘制的地图图块的当前缩放级别MKMapView

例如,如果您将地图精确调整为缩放级别 7,它将从缩放级别 7 绘制地图图块,因此,中的缩放比例MKOverlay drawMapRect:1 / (2^(20-level)) = ~0.000122。现在,如果您再放大一点,但又没有放大到地图必须使用 8 级图块的程度,那么您会期望drawMapRect:再次调用时缩放比例会增加。但是,缩放比例保持不变。

导致这种情况发生的一个行为如下:在内部放置一个断点drawMapRect:并稍微缩放——同样,这不足以使用一组新的图块。您会注意到drawMapRect:实际上并没有被调用!事实上,只有两种方法可以让它被调用:

  1. 平移地图,直到绘制一组新的图块
  2. 放大或缩小,直到达到必须渲染新级别图块的阈值

回想起来,这是完全有道理的。Core Graphics 进行了高度优化,并且希望尽可能少地进行绘制。当用户放大或缩小一点点时,它很可能使用覆盖图块的缓存图像,并适当地放大或缩小它。

然后,我们可以合理地假设,即使MKMapView缩放比例可能是 0 到 1 之间的任何小数十进制数字,但MKOverlay只有当缩放比例达到需要重新绘制的阈值时,即在从 1 开始的整数缩放级别时,才会绘制 。 -20,即缩放比例为 1、1/2、1/4、1/8、1/16...