3

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覆盖必须是透明的?
- 重新加载背景图块?

截图:

看到带线条的瓷砖没有背景了 http://sigmanet.ch/tmp/screen.png

4

2 回答 2

5

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

扩展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:方法不会在没有要渲染的内容时生成图块(例如“未找到图块”图像)。

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

于 2015-01-13T12:25:30.573 回答
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)
    }
}

然后在您的 tileRenderer 中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 准备好为新人复制/粘贴代码。

于 2017-08-17T15:19:45.110 回答