Skip to content

Instantly share code, notes, and snippets.

@MP0w
Created July 25, 2018 21:04
Show Gist options
  • Save MP0w/0bdbe302806039594ecb4046be59e7ec to your computer and use it in GitHub Desktop.
Save MP0w/0bdbe302806039594ecb4046be59e7ec to your computer and use it in GitHub Desktop.
Render location trace as image
private extension MKMapRect {
func with(offset: UIOffset, size: CGSize) -> MKCoordinateRegion {
let horizontalRatio = self.size.width / Double(size.width)
let verticalRatio = self.size.height / Double(size.height)
let mapRect = MKMapRectInset(self, horizontalRatio * Double(offset.horizontal), verticalRatio * Double(offset.vertical))
var region = MKCoordinateRegionForMapRect(mapRect)
let minSpan = 0.001
region.span = MKCoordinateSpanMake(max(region.span.latitudeDelta, minSpan), max(region.span.longitudeDelta, minSpan))
return region
}
}
private extension MKMapRect {
init(locations: [CLLocationCoordinate2D]) {
self = locations.reduce(MKMapRectNull) { (rect, coordinate) -> MKMapRect in
MKMapRectUnion(rect, MKMapRect(origin: MKMapPointForCoordinate(coordinate), size: MKMapSize(width: 0, height: 0)))
}
}
}
extension MKMapSnapshotter {
class func snapshotByAddingPolyline(with locations: [CLLocationCoordinate2D], size: CGSize, completion: (UIImage?) -> (Void)) {
guard let firstPoint = locations.first, let lastPoint = locations.last where size.height > 0 && size.width > 0 else {
completion(nil)
return
}
let options = MKMapSnapshotOptions()
options.size = size
options.region = MKMapRect(locations: locations).with(UIOffset(horizontal: -40, vertical: -50), size: size)
let snapshotter = MKMapSnapshotter(options: options)
snapshotter.startWithCompletionHandler { (snapshot, error) in
guard let snapshot = snapshot else {
dispatch_async(dispatch_get_main_queue()) {
completion(nil)
}
return
}
let image = snapshot.image
UIGraphicsBeginImageContextWithOptions(image.size, true, UIScreen.mainScreen().scale)
image.drawInRect(CGRect(origin: .zero, size: image.size))
let traceColor = UIColor(red: 0, green: 107 / 255, blue: 243 / 255, alpha: 1)
let startPointColor = UIColor(red: 46 / 255, green: 235 / 255, blue: 9 / 255, alpha: 1)
let endPointColor = UIColor(red: 251 / 255, green: 12 / 255, blue: 79 / 255, alpha: 1)
traceColor.setStroke()
snapshot.trace(for: locations).stroke()
endPointColor.setFill()
snapshot.circlePath(for: lastPoint).fill()
startPointColor.setFill()
snapshot.circlePath(for: firstPoint).fill()
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
dispatch_async(dispatch_get_main_queue()) {
completion(finalImage)
}
}
}
}
private extension MKMapSnapshot {
func circlePath(for coordinate: CLLocationCoordinate2D) -> UIBezierPath {
return UIBezierPath(arcCenter: pointForCoordinate(coordinate), radius: 5, startAngle: 0, endAngle: CGFloat(M_PI * 2), clockwise: true)
}
func trace(for locations: [CLLocationCoordinate2D]) -> UIBezierPath {
let path = UIBezierPath()
path.lineWidth = 4;
path.lineCapStyle = .Round;
path.lineJoinStyle = .Round;
path.moveToPoint(pointForCoordinate(locations.first!))
locations.forEach {
path.addLineToPoint(pointForCoordinate($0))
}
return path
}
}
MKMapSnapshotter.snapshotByAddingPolyline(with: [CLLocationCoordinate2DMake(34, 8), CLLocationCoordinate2DMake(44, 8)], size: CGSize(width: 100, height: 100)) { (image) -> (Void) in
let i = image
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment