-
Notifications
You must be signed in to change notification settings - Fork 0
/
EGM96Location.swift
107 lines (82 loc) · 3.27 KB
/
EGM96Location.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// class EGM96Location (need to rename)
// originally contained in package
// java package org.matthiaszimmermann.location;
// ported to swift by ChatGPT-3.5
import Foundation
import Darwin
public class EGM96Location {
// TODO verify if this is meaningful (eg. if this is sufficient for cm accuracy on earth)
public static let EPSILON: Double = 0.00000001
public static let LATITUDE_MIN_STRICT: Double = -90.0
public static let LATITUDE_MAX_STRICT: Double = 90.0
public static let LONGITUDE_MIN_STRICT: Double = 0.0
public static let LONGITUDE_MAX_STRICT: Double = 360.0
public var m_lat: Double = 0.0
public var m_lng: Double = 0.0
convenience init() {
self.init(lat: 0.0, lng: 0.0, lenient: true)
}
convenience init(lat: Double, lng: Double) {
self.init( lat: lat, lng: lng, lenient: true)
}
//convenience init(lat: Double, lng: Double, lenient: Bool) {
// self.init_model( lat: lat, lng: lng, lenient: lenient)
//}
init(lat: Double, lng: Double, lenient: Bool)
{
if lenient {
self.m_lat = normalizeLat(lat)
self.m_lng = normalizeLong(lng)
} else {
if lat < EGM96Location.LATITUDE_MIN_STRICT || lat > EGM96Location.LATITUDE_MAX_STRICT {
fatalError("latitude out of bounds [\(EGM96Location.LATITUDE_MIN_STRICT),\(EGM96Location.LATITUDE_MAX_STRICT)]")
}
if lng < EGM96Location.LONGITUDE_MIN_STRICT || lng >= EGM96Location.LONGITUDE_MAX_STRICT {
fatalError("longitude out of bounds [\(EGM96Location.LONGITUDE_MIN_STRICT),\(EGM96Location.LONGITUDE_MAX_STRICT))")
}
self.m_lat = lat
self.m_lng = lng
}
}
public var latitude: Double {
return m_lat
}
public var longitude: Double {
return m_lng
}
private func normalizeLat(_ lat: Double) -> Double {
if lat > 90.0 {
return normalizeLatPositive(lat)
} else if lat < -90.0 {
return -normalizeLatPositive(-lat)
}
return lat
}
private func normalizeLatPositive(_ lat: Double) -> Double {
let delta = (lat - 90.0).truncatingRemainder(dividingBy: 360.0)
if delta <= 180.0 {
return 90.0 - delta
} else {
return delta - 270.0
}
}
private func normalizeLong(_ lng: Double) -> Double {
let normalizedLng = lng.truncatingRemainder(dividingBy: 360.0)
if normalizedLng >= 0.0 {
return normalizedLng
} else {
return normalizedLng + 360.0
}
}
public static func ==(lhs: EGM96Location, rhs: EGM96Location) -> Bool {
return abs(lhs.latitude - rhs.latitude) <= EPSILON && abs(lhs.longitude - rhs.longitude) <= EPSILON
}
public func floorLocation(step: Double) -> EGM96Location {
guard step > 0.0 && step <= 1.0 else {
fatalError("precision out of bounds (0,1]")
}
let latFloor = floor(latitude / step) * step
let lngFloor = floor(longitude / step) * step
return EGM96Location(lat: latFloor, lng: lngFloor)
}
} // EGM96Location