在绘制MKOverlay时,调整MKMapView大小后的zoomScale不等于zoomScale

时间:2013-08-06 18:38:20

标签: ios objective-c mapkit mkoverlay mkmapviewdelegate

我有一个使用MapKit的应用。
我在调整地图大小后计算当前缩放。
通过define(来自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.

所以,我用这种方式计算:

- (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);
}

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

我还在方法

中的mapView上绘制了一个叠加层
-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context

问题是,我的计算zoomScale不等于系统传递给此方法的那个drawMapRect:。我希望它们是相同的,因为currentZoomScale = mapView.bounds.size.width / mapView.visibleMapRect.size.width; 在调整大小后调用(实际上,调整大小会导致调用此方法)。

这里有什么问题?

我也尝试使用

currentZoomScale

,建议here,但此drawMapRect:也不等于传递给{{1}}。

1 个答案:

答案 0 :(得分:3)

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

例如,如果您将地图操作为精确缩放级别7,则会从缩放级别7绘制地图图块,因此,MKOverlay {{中的缩放比例1}}是drawMapRect:。现在,如果你进一步放大,但不是太多,以至于地图必须使用8级平铺,你会发现当再次调用1 / (2^(20-level)) = ~0.000122时缩放比例会增加。但是,缩放比例保持不变。

一个显示出现这种情况的行为如下:在drawMapRect:内放置一个断点并稍微缩放 - 再次,不足以使用一组新的切片。您会注意到drawMapRect:实际上并未被调用!实际上,只有两种方法可以调用它:

  1. 平移地图,直到必须绘制一组新的图块
  2. 放大或缩小,直至达到必须呈现新级别图块的阈值
  3. 回想起来,这很有道理。 Core Graphics经过高度优化,希望尽可能少地绘制。当用户稍微放大或缩小时,它很可能使用叠加图块的缓存图像,并且只是适当地向上或向下缩放。

    我们可以合理地假设即使drawMapRect:可能具有介于0和1之间的任何小数十进制数的缩放比例,但只有在缩放比例达到阈值时才会绘制MKMapView需要重新绘制,即在1-20的整数缩放级别,即缩放比例1,1 / 2,1 / 4,1 / 8,1 / 16 ......