-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathNearestPoint.swift
More file actions
74 lines (60 loc) · 2.39 KB
/
NearestPoint.swift
File metadata and controls
74 lines (60 loc) · 2.39 KB
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#if canImport(CoreLocation)
import CoreLocation
#endif
import Foundation
// Ported from https://github.com/Turfjs/turf/blob/master/packages/turf-nearest-point
extension BoundingBox {
/// Takes a reference coordinate and returns the coordinate from the reveiver closest to the reference.
/// This calculation is geodesic.
///
/// - Parameter other: The other coordinate
public func nearestCoordinate(
from other: Coordinate3D
) -> (coordinate: Coordinate3D, distance: CLLocationDistance)? {
self.boundingBoxPolygon.nearestCoordinate(from: other)
}
/// Takes a reference point and returns the point from the reveiver closest to the reference.
/// This calculation is geodesic.
///
/// - Parameter other: The other point
public func nearestPoint(
from other: Point
) -> (point: Point, distance: CLLocationDistance)? {
self.boundingBoxPolygon.nearestPoint(from: other)
}
}
extension GeoJson {
/// Takes a reference coordinate and returns the coordinate from the reveiver closest to the reference.
/// This calculation is geodesic.
///
/// - Parameter other: The other coordinate
public func nearestCoordinate(
from other: Coordinate3D
) -> (coordinate: Coordinate3D, distance: CLLocationDistance)? {
let other = other.projected(to: projection)
let allCordinates = self.allCoordinates
guard !allCordinates.isEmpty else { return nil }
var bestCoordinate: Coordinate3D = allCordinates[0]
var bestDistance: CLLocationDistance = bestCoordinate.distance(from: other)
for coordinate in allCordinates {
let distance = coordinate.distance(from: other)
if distance < bestDistance {
bestDistance = distance
bestCoordinate = coordinate
}
}
return (coordinate: bestCoordinate, distance: bestDistance)
}
/// Takes a reference point and returns the point from the reveiver closest to the reference.
/// This calculation is geodesic.
///
/// - Parameter other: The other point
public func nearestPoint(
from other: Point
) -> (point: Point, distance: CLLocationDistance)? {
if let nearest = nearestCoordinate(from: other.coordinate) {
return (point: Point(nearest.coordinate), distance: nearest.distance)
}
return nil
}
}