MapKit:添加 MKPolyline 隐藏 MKTileOverlay
Posted
技术标签:
【中文标题】MapKit:添加 MKPolyline 隐藏 MKTileOverlay【英文标题】:MapKit : add MKPolyline hide MKTileOverlay 【发布时间】:2015-01-09 15:48:33 【问题描述】:我有一个 MKMapView
与一个 MKTileOverlay
一起工作,显示来自本地数据库的图块。它工作正常。
然后我使用MKDirections
来获取两个坐标之间的方向并像这样绘制路线:
MKRoute *route = response.routes.lastObject;
MKPolyline *polyline = route.polyline;
// Draw path on overlay
[self.mapView insertOverlay:polyline aboveOverlay:self.tileOverlay];
但是当我放大看这条线时,它看起来没有平铺背景(通常从MKTileOverlay
加载(存储到self.tileOverlay
))。为了看得更清楚,我加入了一张图片。
我还编写了这段代码来渲染叠加层:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
if ([overlay isKindOfClass:[MKTileOverlay class]])
return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
else if ([overlay isKindOfClass:[MKPolyline class]])
MKPolylineRenderer *lineView = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
lineView.strokeColor = [UIColor greenColor];
lineView.lineWidth = 3;
return lineView;
return nil;
这就像渲染线的“瓷砖”隐藏从MKTileOverlay
加载的瓷砖。我该怎么做:
- 指定我的MKPolyline
覆盖必须是透明的?
- 重新加载背景图块?
截图:
See the tile with line has no background anymore http://sigmanet.ch/tmp/screen.png
【问题讨论】:
【参考方案1】:经过几天的工作,这是我自己的解决方案。
扩展MKPolylineRenderer
并添加对MKTileOverlayRenderer
的引用。我们称这个新类为MCPolylineRenderer
。
在这个类中,重写这两个方法:
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
// Draw path only if tile render has a tile
if ([self.tileRenderRef canDrawMapRect:mapRect zoomScale:zoomScale])
[super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale
// We can draw path only if tile render can also
return [self.tileRenderRef canDrawMapRect:mapRect zoomScale:zoomScale];
现在,在mapView:renderedForOverlay
方法中,替换
MKPolylineRenderer *lineView = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
与
MCPolylineRenderer *lineView = [[MCPolylineRenderer alloc] initWithPolyline:overlay];
lineView.tileRenderRef = self.tileRender;
此外,您需要确保loadTileAtPath:result:
方法不会在没有要渲染的内容时生成图块(例如“找不到图块”图像)。
这段代码的作用是,当没有背景瓦片要渲染时,路径也不会被绘制。
【讨论】:
此解决方案也适用于 ImageRenderer 和 TileRenderer。非常感谢!【参考方案2】:您必须继承 MKPolylineRenderer 以同步渲染器的绘图能力。
import Foundation
import MapKit
class MyPolylineRenderer: MKPolylineRenderer
var tileRenderer: MKTileOverlayRenderer?
override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext)
if (tileRenderer?.canDraw(mapRect, zoomScale: zoomScale) ?? true)
super.draw(mapRect, zoomScale: zoomScale, in: context)
override func canDraw(_ mapRect: MKMapRect, zoomScale: MKZoomScale) -> Bool
return tileRenderer?.canDraw(mapRect, zoomScale: zoomScale) ?? super.canDraw(mapRect, zoomScale: zoomScale)
然后在您的 MKMapViewDelegate
中,保留对您的 tileRenderer 的引用并实现 rendererForOverlay
:
var tileRenderer: MKTileOverlayRenderer?
public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
if let polyline = overlay as? MKPolyline
let lineRenderer = NXPolylineRenderer(overlay: overlay)
lineRenderer.tileRenderer = tileRenderer
// Configure your polyline overlay renderer here...
return lineRenderer;
if let tileOverlay = overlay as? MKTileOverlay
if tileRenderer == nil || tileRenderer.overlay != overlay
tileRenderer = MKTileOverlayRenderer(overlay: overlay)
return tileRenderer
return MKOverlayRenderer(overlay: overlay)
这个想法的所有功劳都归于@Jonathan,我只是发布了一个 swift 准备为新人复制/粘贴代码。
【讨论】:
在我的情况下,多边形和折线在瓷砖加载后消失。我该如何解决这个问题? @AnirudhaMahale 添加折线或多边形时,您可以选择它的级别(请参阅developer.apple.com/documentation/mapkit/…)您还可以调整叠加层的 Z 级别(developer.apple.com/documentation/mapkit/mkmapview/…)希望您会发现有用那里有信息。以上是关于MapKit:添加 MKPolyline 隐藏 MKTileOverlay的主要内容,如果未能解决你的问题,请参考以下文章
如何向 MKPolyline 和 MKPolygon 添加描述?
添加 MKPolyLine NSInvalidArgumentException