Skip to content

Commit 5a156d7

Browse files
committed
Added BoundingBox.position(of:) - position of a coordinate in relation to a bounding box
1 parent cbbb513 commit 5a156d7

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#if !os(Linux)
2+
import CoreLocation
3+
#endif
4+
import Foundation
5+
6+
extension BoundingBox {
7+
8+
/// Position of a coordinate in relation to a bounding box.
9+
public struct CoordinatePosition: OptionSet, Sendable {
10+
public let rawValue: Int
11+
12+
public init(rawValue: Int) {
13+
self.rawValue = rawValue
14+
}
15+
16+
public static let center = CoordinatePosition(rawValue: 1 << 0)
17+
public static let top = CoordinatePosition(rawValue: 1 << 1)
18+
public static let right = CoordinatePosition(rawValue: 1 << 2)
19+
public static let bottom = CoordinatePosition(rawValue: 1 << 3)
20+
public static let left = CoordinatePosition(rawValue: 1 << 4)
21+
public static let outside = CoordinatePosition(rawValue: 1 << 5)
22+
}
23+
24+
/// Returns the relative position of a coordinate with regards to the bounding box.
25+
public func position(of coordinate: Coordinate3D) -> CoordinatePosition {
26+
var position: CoordinatePosition = []
27+
28+
if !contains(coordinate) {
29+
position.insert(.outside)
30+
}
31+
32+
let latitudeSpan = northEast.latitude - southWest.latitude
33+
let longitudeSpan = northEast.longitude - southWest.longitude
34+
35+
let topCutoff = southWest.latitude + (latitudeSpan * 0.65)
36+
if coordinate.latitude > topCutoff {
37+
position.insert(.top)
38+
}
39+
40+
let rightCutoff = southWest.longitude + (longitudeSpan * 0.65)
41+
if coordinate.longitude > rightCutoff {
42+
position.insert(.right)
43+
}
44+
45+
let bottomCutoff = southWest.latitude + (latitudeSpan * 0.35)
46+
if coordinate.latitude < bottomCutoff {
47+
position.insert(.bottom)
48+
}
49+
50+
let leftCutoff = southWest.longitude + (longitudeSpan * 0.35)
51+
if coordinate.longitude < leftCutoff {
52+
position.insert(.left)
53+
}
54+
55+
if position.isEmpty {
56+
position.insert(.center)
57+
}
58+
59+
return position
60+
}
61+
62+
/// Returns the relative position of a point with regards to the bounding box.
63+
public func postion(of point: Point) -> CoordinatePosition {
64+
position(of: point.coordinate)
65+
}
66+
67+
// MARK: - CoreLocation compatibility
68+
69+
#if !os(Linux)
70+
71+
/// Returns the relative position of a coordinate with regards to the bounding box.
72+
public func postion(of coordinate: CLLocationCoordinate2D) -> CoordinatePosition {
73+
position(of: Coordinate3D(coordinate))
74+
}
75+
76+
/// Returns the relative position of a location with regards to the bounding box.
77+
public func postion(of coordinate: CLLocation) -> CoordinatePosition {
78+
position(of: Coordinate3D(coordinate))
79+
}
80+
81+
#endif
82+
83+
}

0 commit comments

Comments
 (0)