我已经构建了一个自定义的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()
}
答案 0 :(得分:2)
一些观察结果:
您正在使用points
,该MKMapPoint
已经是MKPolygonRenderer
的数组(至少在MKMapPointForCoordinate
中)并且正在调用MKMapPointForCoordinate
。如果您想使用coordinates
,请将points
传递给pointForMapPoint
,而不是CGContextSetFillColorWithColor
。也许您已经定义了自己的属性,但我可能会更改属性的名称以避免混淆。
您需要使用fillColor
将地图点转换为屏幕点。
此外,您正在呼叫MKPolygonRenderer
,但是将其传递给fillColor
。但假设您的类是UIColor
的子类,CGColor
是points
,而不是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
也很好奇。您正在调用一些自定义初始化方法(这很好),但您正在通过overlay
和currentPolygon
。但是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()
}
}