MapKit:添加MKPolyline隐藏MKTileOverlay

时间:2015-01-09 15:48:33

标签: objective-c mkpolyline mktileoverlay

我有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;
}

就像“tile”一样,该线条隐藏了从MKTileOverlay加载的图块。我怎么能:
- 指定MKPolyline叠加层必须是透明的吗? - 重新加载背景图块?

Screeshot:

See the tile with line has no background anymore http://sigmanet.ch/tmp/screen.png

2 个答案:

答案 0 :(得分:4)

经过几天的工作,这是我自己的解决方案。

扩展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:方法不会产生图块。

此代码会生效,当没有要渲染的背景图块时,路径也不会绘制。

答案 1 :(得分:1)

您必须子类化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,我只是发布了一个快速准备复制/粘贴新手的代码。