Skip to content

Instantly share code, notes, and snippets.

@worthbak
Last active January 14, 2016 23:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save worthbak/64fbfc15f0cde6350524 to your computer and use it in GitHub Desktop.
Save worthbak/64fbfc15f0cde6350524 to your computer and use it in GitHub Desktop.
A riff on Erica Saudi's Swift-y implementation of a distance calculator between two coordinates (http://ericasadun.com/2016/01/11/make-this-swift-er-coordinate-distances/)
import CoreLocation
import Darwin
private enum EarthUnits: Double {
case ImperialRadius = 3961.0
case MetricRadius = 6373.0
}
postfix operator ° {}
postfix func °(degrees: Double) -> Double {return degrees * M_PI / 180.0}
protocol CoordinateDistanceCalculatable {
var latitude: Double { get }
var longitude: Double { get }
}
extension CoordinateDistanceCalculatable {
func milesFrom(coordinate: CoordinateDistanceCalculatable) -> Double {
let radius = EarthUnits.ImperialRadius
let (dLat, dLon) = (latitude - coordinate.latitude, longitude - coordinate.longitude)
let (sqSinLat, sqSinLon) = (pow(sin(dLat° / 2.0), 2.0), pow(sin(dLon° / 2.0), 2.0))
let α = sqSinLat + sqSinLon * cos(latitude°) * cos(coordinate.latitude°)
return 2.0 * radius.rawValue * atan2(sqrt(α), sqrt(1.0 - α))
}
func kilometersFrom(coordinate: CoordinateDistanceCalculatable) -> Double {
let radius = EarthUnits.MetricRadius
let (dLat, dLon) = (latitude - coordinate.latitude, longitude - coordinate.longitude)
let (sqSinLat, sqSinLon) = (pow(sin(dLat° / 2.0), 2.0), pow(sin(dLon° / 2.0), 2.0))
let α = sqSinLat + sqSinLon * cos(latitude°) * cos(coordinate.latitude°)
return 2.0 * radius.rawValue * atan2(sqrt(α), sqrt(1.0 - α))
}
}
extension CLLocationCoordinate2D: CoordinateDistanceCalculatable {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment