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