如何创建一个静态的,实际宽度的MKOverlayPathRenderer子类?

时间:2014-05-19 17:56:01

标签: ios mapkit mkoverlay mkoverlaypathrenderer

我一直在处理现有MKMapView的简单路径覆盖。它需要一个CGMutablePath并将其绘制到地图上。目标是绘制表示实际宽度的路径。例如子类采用以米为单位的宽度,并将该宽度转换为代表性的线宽。以下是计算线宽的代码的一个版本:

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
float mapPoints = meterWidth * MKMapPointsPerMeterAtLatitude(self.averageLatitude);
float screenPoints = mapPoints * zoomScale; // dividing would keep the apparent width constant 
self.lineWidth = ceilf(screenPoints * 2);

CGContextAddPath(context, _mutablePath);

[self applyStrokePropertiesToContext:context atZoomScale:zoomScale];

CGContextStrokePath(context);

这里我们首先找到与线宽对应的地图点数,然后将其转换为屏幕点。我们根据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.

最后,我们将路径添加到上下文中,将描边属性应用于路径并对其进行描边。

然而,这给出了非常好的结果。渲染器通常在预期的活动区域之外的各个位置绘制线的随机片段,或者根本不绘制一些瓦片。有时候CPU会一遍又一遍地重绘相同图块的多个版本(尽我所知)。在这种情况下,文档没有多大帮助。

我确实有一个正常工作的版本,但它似乎不是正确的解决方案,因为它完全忽略了zoomScale并且没有使用-applyStrokePropertiesToContext:atZoomScale:

float mapPoints = meterWidth * MKMapPointsPerMeterAtLatitude(self.averageLatitude);
self.lineWidth = ceilf(mapPoints * 2);

CGContextAddPath(context, _mutablePath);
CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineCap(context, kCGLineCapRound);

CGContextStrokePath(context);

有人指出这个实现有什么问题吗?

0 个答案:

没有答案