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

MKPolyline 的问题

MKPolyLine,检测线条何时重叠并相应改变颜色

将 MKTileOverlay 与 MKPolyLine 一起使用

MapKit iPhone 开发;当前位置和注释