自定义MKOverlayRenderer drawMapRect函数不绘制多边形 [英] Custom MKOverlayRenderer drawMapRect function not drawing polygons

查看:478
本文介绍了自定义MKOverlayRenderer drawMapRect函数不绘制多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have built a custom MKOverlayRenderer in order to build polygons, apply a blend mode, then add them to the map view. In my drawMapRect function, I use an array of CGPoints to build the polygon, and create a path.

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

However, during runtime nothing shows on my map view. My best guess would be the order of which I create the polygon in my drawMapRect function. Any help or guidance would be greatly appreciated, thanks!

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)
}

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

Here is where my custom overlay renderer is initialized:

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()
}


推荐答案

一些观察结果:


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

  • You are taking points, which is already an array of MKMapPoint (in MKPolygonRenderer, at least) and calling MKMapPointForCoordinate. If you want to use MKMapPointForCoordinate, you'd pass it coordinates, not points. Maybe you've defined your own properties, but I might change the name of the property to avoid confusion.

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

You need to convert map points to screen points with pointForMapPoint.

此外,您正在调用 CGContextSetFillColorWithColor ,但是传递它 fillColor 。但假设您的类是 MKPolygonRenderer 的子类, fillColor UIColor ,而不是 CGColor

Also, you are calling CGContextSetFillColorWithColor, but passing it fillColor. But assuming your class is a subclass of MKPolygonRenderer, the fillColor is a UIColor, not a CGColor.

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

You seem to be accessing some property, points, but the MKPolygonRenderer doesn't have points property, but rather points() method.

所有这些说,我不清楚你的代码是如何编译的。我怀疑你没有从 MKPolygonRenderer 继承,而是继承 MKOverlayRenderer ,然后自己实现了一堆属性?如果您继承 MKPolygonRender ,则可以免费获得所有多边形行为,只需要实现 drawMapRect

With all of that said, I'm unclear how your code even compiled. I suspect you didn't subclass from MKPolygonRenderer, but rather subclassed MKOverlayRenderer and then implemented a bunch of properties yourself? If you subclass MKPolygonRender, you get all the polygon behavior for free and only have to implement 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)
    }

}

顺便说一句,我们可能在这里更复杂(检查点是否可见,根据比例确定要渲染的点数...即如果多边形具有数千个点并被缩放到视图的100x100部分,也许您不必渲染所有点等等)。请参阅WWDC 2010 使用叠加层自定义地图,虽然已过时,但仍具有相关性。

By the way, we probably could be more sophisticated here (checking to see if the points were visible, figuring out what points to render given the scale ... i.e. if polygon with thousands of points and being scaled into a 100x100 portion of the view, perhaps you don't have to render all of the points, etc.). See WWDC 2010 Customizing Maps with Overlays, which, while dated, is still relevant.

另外,您的 rendererForOverlay 也很好奇。您正在调用一些自定义初始化方法(这很好),但您传递 overlay currentPolygon 。但 overlay 多边形,所以我不知道这个 currentPolygon 是什么。 rendererForOverlay 是无状态的,所以我不鼓励你引用某些属性,而只是采取 overlay 传递给方法。这样,你可以有多个多边形,让地图视图跟踪哪个是多边形。所以我会做类似的事情:

As an aside, your rendererForOverlay is curious, too. You are calling some custom initialization method (which is fine), but you're passing overlay and currentPolygon. But the overlay is the polygon, so I don't know what this currentPolygon is. And rendererForOverlay is stateless, so I'd discourage you from referencing some property, but rather just take the overlay that was passed to the method. That way, you could have multiple polygons and let map view keep track of which is which. So I'd do something like:

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")
}

这篇关于自定义MKOverlayRenderer drawMapRect函数不绘制多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆