正确地继承MKOverlayRenderer

时间:2016-07-03 10:58:54

标签: ios iphone swift mapkit mkoverlay

我试图在运行时修改MKPolyline的路径,以避免它与另一个重叠。

我已经设法获得所有重叠点和我尝试做的是在MKPolylineRenderer的func createPath()中添加一个偏移来做点,理论上,它应该用相加的小偏移绘制相同的路径,并且它不应该重叠,但遗憾的是,这不会发生,并且Polyline以相同的方式绘制,就像没有任何改变一样。

我首先尝试在addPolyline()函数之后执行此操作,但我读到一旦你这样做,重绘Polyline的一种方法是删除它并再次添加它,所以我决定,为了测试目的,在添加Polyline之前完成所有这些操作,所以当我最终将它添加到地图时,它已经有关于重叠点的信息,但这也没有用。

假设:

1.有一些事情要做,地图在不同的线程上工作,并且由于这个原因,没有反映出这些变化。这没关系。它应该是这种优化渲染的方式。

2。完成此操作的正确方法不在createPath()函数中。确实不是

  1. 我应该在渲染器的draw()函数中应用 transform 这是
  2. 这是createPath()函数

    override func createPath()
    {
       let poly = polyline as! TransportPolyline
    
       switch poly.id
        {
        case 1:
            let newPath = CGMutablePath()
    
            for index in 0...poly.pointCount
            {
                let point = poly.points()[index]
                let predicate = { MKMapPointEqualToPoint($0, poly.points()[index]) }
                //This is the offset I should apply
                let offset: CGFloat = overlapsAtPoints.contains(predicate) ? 100000.0 : 0.0
                //I tried to use a transform as well, but the result was the same
                var transform = CGAffineTransform(translationX: offset, y: offset)
    
                if index == 0
                {
                    //Here I add the offset and/or the transform without success
                    newPath.moveTo(&transform, x: CGFloat(point.x) + offset, y: CGFloat(point.y) + offset)
                }
                else
                {
                    //Here as well
                    newPath.addLineTo(&transform, x: CGFloat(point.x) + offset, y: CGFloat(point.y) + offset)
                }
            }
    
            //Set the new path to the Renderer path property
            self.path = newPath
        default: break
        }
    }
    

    <击> 这是draw()函数

    override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext)
        {
            let poly = polyline as! TransportPolyline
    
            guard poly.id == 1 else {
                super.draw(mapRect, zoomScale: zoomScale, in: context)
                return
            }
    
            //If I apply this the Polyline does move, obviously it move all the Path and not only the segments I want.
            context.translate(x: 1000, y: 1000)
    
            super.draw(mapRect, zoomScale: zoomScale, in: context)
        }
    

    非常感谢任何建议。

    更新

    我发现问题可能出在我如何在draw方法中绘制上下文。

    文档说:

      

    此方法的默认实现不执行任何操作。子类是   期望覆盖此方法并使用它来绘制叠加层   内容。

    所以致电super.draw()我没有做任何事情。

    有关如何正确覆盖此方法的任何想法?还要考虑到这一点:

      

    为了提高绘图性能,地图视图可能会划分叠加层   分成多个图块并在单独的线程上渲染每个图块。您的   因此,这种方法的实施必须能够安全   同时从多个线程运行。另外,你应该   避免每次使用此方法绘制叠加层的全部内容   叫做。相反,始终将mapRect参数放入   考虑并避免在该矩形之外绘制内容。

1 个答案:

答案 0 :(得分:0)

所以基本上我在正确的轨道上,但使用了错误的工具。实现此目的的实际方法是覆盖MKPolylineRenderer子类中的draw()函数。

override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext)
{
   //First validate that the Rect you are asked to draw in actually 
     has some content. See last quote above.
   let theMapRect: MKMapRect = self.overlay.boundingMapRect;

   guard (MKMapRectIntersectsRect(mapRect, theMapRect)) || self.path != nil else {
        return
   }

   //Do some logic if needed.

   //Create and draw your path
   let path = CGMutablePath()
   path.moveTo(nil, x: self.path.currentPoint.x, y: self.path.currentPoint.y)
   path.addLines(nil, between: remainingPoints, count: remainingPoints.count)

   context.addPath(path)

   //Customise it
   context.setStrokeColor(strokeColor!.cgColor)
   context.setLineWidth((lineWidth + CGFloat(0.0)) / zoomScale)

   //And apply it 
   context.strokePath()
}

通过这样做,我能够成功地绘制我想要的每个叠加路径,没有任何麻烦。