自定义MKOverlayRenderer drawMapRect函数不绘制多边形

时间:2016-05-27 00:52:22

标签: ios swift mkoverlay

我已经构建了一个自定义的MKOverlayRenderer来构建多边形,应用混合模式,然后将它们添加到地图视图中。在我的drawMapRect函数中,我使用CGPoints数组来构建多边形,并创建一个路径。

但是,在运行时,我的地图视图中没有显示任何内容。我最好的猜测是我在drawMapRect函数中创建多边形的顺序。非常感谢任何帮助或指导,谢谢!

override func drawMapRect(mapRect: MKMapRect, zoomScale: MKZoomScale, inContext context: CGContext) {

    super.drawMapRect(mapRect, zoomScale: zoomScale, inContext: context)
    CGContextSaveGState(context)
    CGContextSetBlendMode(context, CGBlendMode.Exclusion)
    CGContextSetFillColorWithColor(context, self.fillColor)
    CGContextSetStrokeColorWithColor(context, UIColor.whiteColor().CGColor)
    CGContextSetLineWidth(context, 1.0)

    let point = MKMapPointForCoordinate(self.polygon.points[0])
    CGContextMoveToPoint(context, CGFloat(point.x), CGFloat(point.y))
    for i in 1..<self.polygon.points.count {
        let point = polygon.points[i]
        let p = MKMapPointForCoordinate(point)
        CGContextAddLineToPoint(context, CGFloat(p.x), CGFloat(p.y))
    }

    CGContextClosePath(context)
    CGContextDrawPath(context, CGPathDrawingMode.FillStroke)
    CGContextRestoreGState(context)
}

这是我的自定义叠加渲染器初始化的位置:

func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
    if (overlay is MKPolygon) {
        let polygonRenderer = MyCustomMapRenderer(overlay: overlay, fillColor: self.polyFactory!.getPolygonColor().CGColor, polygon: self.currentPolygon!)
        return polygonRenderer
    }
    return MKOverlayRenderer()
}

3 个答案:

答案 0 :(得分:2)

一些观察结果:

  • 您正在使用points,该MKMapPoint已经是MKPolygonRenderer的数组(至少在MKMapPointForCoordinate中)并且正在调用MKMapPointForCoordinate。如果您想使用coordinates,请将points传递给pointForMapPoint,而不是CGContextSetFillColorWithColor。也许您已经定义了自己的属性,但我可能会更改属性的名称以避免混淆。

  • 您需要使用fillColor将地图点转换为屏幕点。

  • 此外,您正在呼叫MKPolygonRenderer,但是将其传递给fillColor。但假设您的类是UIColor的子类,CGColorpoints,而不是MKPolygonRenderer

  • 您似乎正在访问某些属性points,但points()没有MKPolygonRenderer属性,而是MKOverlayRenderer方法。< / p>

尽管如此,我还不清楚你的代码是如何编译的。我怀疑你没有从MKPolygonRender继承,而是继承drawMapRect,然后自己实现了一堆属性?如果您继承class MyCustomMapRenderer: MKPolygonRenderer { override func drawMapRect(mapRect: MKMapRect, zoomScale: MKZoomScale, inContext context: CGContext) { //super.drawMapRect(mapRect, zoomScale: zoomScale, inContext: context) CGContextSaveGState(context) CGContextSetBlendMode(context, CGBlendMode.Exclusion) CGContextSetFillColorWithColor(context, fillColor!.CGColor) CGContextSetStrokeColorWithColor(context, UIColor.whiteColor().CGColor) CGContextSetLineWidth(context, 1.0) if polygon.pointCount > 1 { CGContextBeginPath(context) let point = pointForMapPoint(polygon.points()[0]) CGContextMoveToPoint(context, CGFloat(point.x), CGFloat(point.y)) for i in 1 ..< polygon.pointCount { let point = pointForMapPoint(polygon.points()[i]) CGContextAddLineToPoint(context, CGFloat(point.x), CGFloat(point.y)) } CGContextClosePath(context) CGContextDrawPath(context, CGPathDrawingMode.FillStroke) } CGContextRestoreGState(context) } } ,则可以免费获得所有多边形行为,只需实现rendererForOverlay

overlay

顺便说一句,我们可能在这里更复杂一些(检查点是否可见,在给定比例的情况下确定要渲染的点...即,如果多边形具有数千个点并且缩放为100x100部分在视图中,也许你不必渲染所有的点,等等。参见WWDC 2010 Customizing Maps with Overlays,虽然过时,仍然具有相关性。

顺便说一句,你的currentPolygon也很好奇。您正在调用一些自定义初始化方法(这很好),但您正在通过overlaycurrentPolygon。但是rendererForOverlay 多边形,所以我不知道这个overlay是什么。并且func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer { if let polygon = overlay as? MKPolygon { let polygonRenderer = MyCustomMapRenderer(polygon: polygon) polygonRenderer.fillColor = polyFactory!.getPolygonColor() return polygonRenderer } fatalError("Unexpected overlay type") } 是无状态的,因此我不鼓励您引用某些属性,而只是采用传递给该方法的{{1}}。这样,您可以拥有多个多边形,并让地图视图跟踪哪个是多边形。所以我做了类似的事情:

{{1}}

答案 1 :(得分:0)

Rob's answer in Swift 3

class MyRenderer: MKPolylineRenderer {

    override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {

        context.saveGState()
        context.setBlendMode(CGBlendMode.exclusion)

        let clear = UIColor.clear

        context.setFillColor(clear.cgColor)

        let green = UIColor.green

        context.setStrokeColor(green.cgColor)

        context.setLineWidth(10.0)

        if self.polyline.pointCount > 1 {

            context.beginPath()

            let point_ = self.point(for: self.polyline.points()[0])

            context.move(to: CGPoint(x: point_.x, y: point_.y))

            for element in 1 ..< self.polyline.pointCount {

                let point_ = self.point(for: polyline.points()[element])

                context.addLine(to: CGPoint(x: point_.x, y: point_.y))

            }

            context.closePath()

            context.drawPath(using: .fillStroke)

        }

        context.restoreGState()

    }


 }

答案 2 :(得分:0)

Rob在Swift 4中的答案

class MyCustomMapRenderer: MKPolygonRenderer {

    override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
        //super.drawMapRect(mapRect, zoomScale: zoomScale, inContext: context)

        context.saveGState()
        context.setBlendMode(CGBlendMode.exclusion)
        context.setFillColor(fillColor!.cgColor)
        context.setStrokeColor(UIColor.white.cgColor)
        context.setLineWidth(1.0)

        if polygon.pointCount > 1 {
            context.beginPath()

            let point = self.point(for: polygon.points()[0])
            context.move(to: point)
            for i in 1 ..< polygon.pointCount {
                let point = self.point(for: polygon.points()[i])
                context.addLine(to: point)
            }

            context.closePath()
            context.drawPath(using: CGPathDrawingMode.fillStroke)
        }
        context.restoreGState()
    }

}