-
Notifications
You must be signed in to change notification settings - Fork 6
/
Distance.swift
51 lines (40 loc) · 1.63 KB
/
Distance.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#if !os(Linux)
import CoreLocation
#endif
import Foundation
// Ported from https://github.com/Turfjs/turf/tree/master/packages/turf-distance
extension Coordinate3D {
/// Calculates the distance between two coordinates, in meters.
/// This uses the Haversine formula to account for global curvature.
///
/// - Parameter other: The other coordinate
public func distance(from other: Coordinate3D) -> CLLocationDistance {
switch projection {
case .epsg4326:
return _distance(from: other.projected(to: .epsg4326))
case .epsg3857:
// TODO: This can be improved
return projected(to: .epsg4326)._distance(from: other.projected(to: .epsg4326))
case .noSRID:
// TODO
return Double.infinity
}
}
private func _distance(from other: Coordinate3D) -> CLLocationDistance {
let dLatitude = (other.latitude - latitude).degreesToRadians
let dLongitude = (other.longitude - longitude).degreesToRadians
let latitude1 = latitude.degreesToRadians
let latitude2 = other.latitude.degreesToRadians
let a = pow(sin(dLatitude / 2.0), 2.0) + pow(sin(dLongitude / 2.0), 2.0) * cos(latitude1) * cos(latitude2)
return (2.0 * atan2(sqrt(a), sqrt(1 - a))) * GISTool.earthRadius
}
}
extension Point {
/// Calculates the distance between two points, in meters.
/// This uses the Haversine formula to account for global curvature.
///
/// - Parameter other: The other point
public func distance(from other: Point) -> CLLocationDistance {
coordinate.distance(from: other.coordinate)
}
}