draw line on MKMapView with pattern image

后端 未结 2 1653
时光说笑
时光说笑 2020-12-15 02:21

I try to draw a line on a MKMapView with a pattern image. The drawing is done by adding a custom MKMapOverlay view.

I\'m able to get the l

2条回答
  •  悲&欢浪女
    2020-12-15 02:47

    Swift version of accepted answer

    Add image as overlay using MKOverlayRenderer

    func addLayersOfAnimatingOverlay() {
            let sourcePoint = // enter as CLLocation
            let destinationPoint =  // enter as CLLocation
            let pointsCoordinatesArray = self.getLocationArrayFrom(startLocation: sourcePoint, endLocation: destinationPoint)
                //add overlay on above coordinates
            DispatchQueue.main.async{
                self.addDirectionOverlayInMap(locationArray: self.pointsCoordinates1, title: "1")
            }
    

    To get coordinates in a MKPolyline

        func getLocationArrayFrom(startLocation: CLLocation, endLocation: CLLocation) -> [CLLocationCoordinate2D] {
                var coordinatesArray: [CLLocationCoordinate2D] = []
                if let points = helperClass.getPointsOnRoute(from: startLocation, to: endLocation, on: mapView) {
                    for point in points {
                        let coordinate  = point.coordinate
                        coordinatesArray.append(coordinate)
                    }
                }
                return coordinatesArray
            }
    
        //MARK: get cordinates from line
            func getPointsOnRoute(from: CLLocation?, to: CLLocation?, on mapView: MKMapView?) -> [CLLocation]? {
                let NUMBER_OF_PIXELS_TO_SKIP: Int = 120
                //lower number will give a more smooth animation, but will result in more layers
                var ret = [Any]()
    
                var fromPoint: CGPoint? = nil
                if let aCoordinate = from?.coordinate {
                    fromPoint = mapView?.convert(aCoordinate, toPointTo: mapView)
                }
                var toPoint: CGPoint? = nil
                if let aCoordinate = to?.coordinate {
                    toPoint = mapView?.convert(aCoordinate, toPointTo: mapView)
                }
                let allPixels = getAllPoints(from: fromPoint!, to: toPoint!)
                var i = 0
                while i < (allPixels?.count)! {
                    let pointVal = allPixels![i] as? NSValue
                    ret.append(point(toLocation: mapView, from: (pointVal?.cgPointValue)!)!)
                    i += NUMBER_OF_PIXELS_TO_SKIP
                }
                ret.append(point(toLocation: mapView, from: toPoint!)!)
                return ret as? [CLLocation]
            }
    
    /**convert a CGPoint to a CLLocation according to a mapView*/
        func point(toLocation mapView: MKMapView?, from fromPoint: CGPoint) -> CLLocation? {
            let coord: CLLocationCoordinate2D? = mapView?.convert(fromPoint, toCoordinateFrom: mapView)
            return CLLocation(latitude: coord?.latitude ?? 0, longitude: coord?.longitude ?? 0)
        }
    
        func getAllPoints(from fPoint: CGPoint, to tPoint: CGPoint) -> [Any]? {
            /*Simplyfied implementation of Bresenham's line algoritme */
            var ret = [AnyHashable]()
            let deltaX: Float = fabsf(Float(tPoint.x - fPoint.x))
            let deltaY: Float = fabsf(Float(tPoint.y - fPoint.y))
            var x: Float = Float(fPoint.x)
            var y: Float = Float(fPoint.y)
            var err: Float = deltaX - deltaY
            var sx: Float = -0.5
            var sy: Float = -0.5
            if fPoint.x < tPoint.x {
                sx = 0.5
            }
            if fPoint.y < tPoint.y {
                sy = 0.5
            }
            repeat {
                ret.append(NSValue(cgPoint: CGPoint(x: CGFloat(x), y: CGFloat(y))))
                let e: Float = 2 * err
                if e > -deltaY {
                    err -= deltaY
                    x += sx
                }
                if e < deltaX {
                    err += deltaX
                    y += sy
                }
            } while round(Float(x)) != round(Float(tPoint.x)) && round(Float(y)) != round(Float(tPoint.y))
            ret.append(NSValue(cgPoint: tPoint))
            //add final point
            return ret
        }
    

    This will give the following effect (without animation)

    The project can be found here

提交回复
热议问题