Skip to content

Commit a383f71

Browse files
committed
🎨 Remove some genericity from TurfCore
1 parent 593393a commit a383f71

35 files changed

+1471
-941
lines changed

‎.swiftpm/xcode/xcshareddata/xcschemes/Turf.xcscheme

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,6 @@
2020
ReferencedContainer = "container:">
2121
</BuildableReference>
2222
</BuildActionEntry>
23-
<BuildActionEntry
24-
buildForTesting = "YES"
25-
buildForRunning = "NO"
26-
buildForProfiling = "NO"
27-
buildForArchiving = "NO"
28-
buildForAnalyzing = "YES">
29-
<BuildableReference
30-
BuildableIdentifier = "primary"
31-
BlueprintIdentifier = "TurfTests"
32-
BuildableName = "TurfTests"
33-
BlueprintName = "TurfTests"
34-
ReferencedContainer = "container:">
35-
</BuildableReference>
36-
</BuildActionEntry>
3723
</BuildActionEntries>
3824
</BuildAction>
3925
<TestAction
@@ -78,16 +64,21 @@
7864
skipped = "NO">
7965
<BuildableReference
8066
BuildableIdentifier = "primary"
81-
BlueprintIdentifier = "TurfTests"
82-
BuildableName = "TurfTests"
83-
BlueprintName = "TurfTests"
67+
BlueprintIdentifier = "TurfCoreTests"
68+
BuildableName = "TurfCoreTests"
69+
BlueprintName = "TurfCoreTests"
70+
ReferencedContainer = "container:">
71+
</BuildableReference>
72+
</TestableReference>
73+
<TestableReference
74+
skipped = "NO">
75+
<BuildableReference
76+
BuildableIdentifier = "primary"
77+
BlueprintIdentifier = "GeodeticGeometryTests"
78+
BuildableName = "GeodeticGeometryTests"
79+
BlueprintName = "GeodeticGeometryTests"
8480
ReferencedContainer = "container:">
8581
</BuildableReference>
86-
<SkippedTests>
87-
<Test
88-
Identifier = "SnapshotTests">
89-
</Test>
90-
</SkippedTests>
9182
</TestableReference>
9283
</Testables>
9384
</TestAction>

‎Sources/Geodesy/CoordinateComponent.swift

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,24 @@ import SwiftGeoToolbox
1414

1515
public typealias CoordinateComponent = ValueWithUnit.Value
1616

17-
// // MARK: CustomStringConvertible
18-
//
19-
// var description: String {
20-
// let formatter = NumberFormatter()
21-
// formatter.numberStyle = .decimal
22-
// formatter.maximumFractionDigits = 9
23-
// formatter.locale = .en
24-
// return formatter.string(for: Double(self))
25-
// ?? "\(self.rawValue.rawValue)"
26-
// }
27-
28-
// // MARK: CustomDebugStringConvertible
29-
//
30-
// var debugDescription: String {
31-
// let formatter = NumberFormatter()
32-
// formatter.numberStyle = .decimal
33-
// formatter.maximumFractionDigits = 99
34-
// formatter.locale = .en
35-
// return formatter.string(for: Double(self))
36-
// ?? "\(self.rawValue.rawValue)"
37-
// }
17+
// MARK: CustomStringConvertible & CustomDebugStringConvertible
18+
19+
public extension CoordinateComponent {
20+
var description: String {
21+
let formatter = NumberFormatter()
22+
formatter.numberStyle = .decimal
23+
formatter.maximumFractionDigits = 9
24+
formatter.locale = .en
25+
return formatter.string(for: Double(self.rawValue)) ?? String(describing: self.rawValue)
26+
}
27+
var debugDescription: String {
28+
let formatter = NumberFormatter()
29+
formatter.numberStyle = .decimal
30+
formatter.locale = .en
31+
formatter.maximumFractionDigits = 99
32+
return formatter.string(for: Double(self.rawValue)) ?? String(reflecting: self.rawValue)
33+
}
34+
}
3835

3936
// MARK: - ValidatableCoordinateComponent
4037

‎Sources/Geodesy/Coordinates.swift

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
//
2+
// Coordinates.swift
3+
// SwiftGeo
4+
//
5+
// Created by Rémi Bardon on 01/10/2022.
6+
// Copyright © 2022 Rémi Bardon. All rights reserved.
7+
//
8+
9+
import SwiftGeoToolbox
10+
11+
// MARK: - Coordinates
12+
13+
public protocol Coordinates<CRS>:
14+
Hashable,
15+
Zeroable,
16+
AdditiveArithmetic,
17+
MultiplicativeArithmetic,
18+
InitializableByNumber,
19+
CustomStringConvertible,
20+
CustomDebugStringConvertible
21+
{
22+
associatedtype CRS: Geodesy.CoordinateReferenceSystem
23+
associatedtype Components
24+
25+
var components: Components { get set }
26+
27+
init(components: Components)
28+
}
29+
30+
// CustomStringConvertible & CustomDebugStringConvertible
31+
public extension Coordinates {
32+
var description: String { String(describing: self.components) }
33+
var debugDescription: String {
34+
"<\(Self.CRS.epsgName)>\(String(reflecting: self.components))"
35+
}
36+
}
37+
38+
// MARK: 2D Coordinates
39+
40+
public protocol AtLeastTwoDimensionalCoordinates<CRS>: Geodesy.Coordinates
41+
where CRS: AtLeastTwoDimensionalCRS {
42+
associatedtype X: CoordinateComponent
43+
associatedtype Y: CoordinateComponent
44+
45+
var x: X { get set }
46+
var y: Y { get set }
47+
}
48+
49+
public extension AtLeastTwoDimensionalCoordinates where X == Geodesy.Latitude {
50+
typealias Latitude = Geodesy.Latitude
51+
var latitude: Latitude { self.x }
52+
}
53+
54+
public extension AtLeastTwoDimensionalCoordinates where Y == Geodesy.Longitude {
55+
typealias Longitude = Geodesy.Longitude
56+
var longitude: Longitude { self.y }
57+
}
58+
59+
public protocol TwoDimensionalCoordinates<CRS>: AtLeastTwoDimensionalCoordinates
60+
where Components == (X, Y) {
61+
init(x: X, y: Y)
62+
}
63+
64+
public struct Coordinates2DOf<CRS>: TwoDimensionalCoordinates
65+
where CRS: TwoDimensionalCRS
66+
{
67+
public typealias X = CRS.CoordinateSystem.Axis1.Value
68+
public typealias Y = CRS.CoordinateSystem.Axis2.Value
69+
70+
public var x: X
71+
public var y: Y
72+
73+
public var components: (X, Y) {
74+
get { (self.x, self.y) }
75+
set {
76+
self.x = newValue.0
77+
self.y = newValue.1
78+
}
79+
}
80+
81+
public init(x: X, y: Y) {
82+
#warning("TODO: Perform validations")
83+
self.x = x
84+
self.y = y
85+
}
86+
public init(components: (X, Y)) {
87+
self.init(x: components.0, y: components.1)
88+
}
89+
}
90+
91+
// Zeroable
92+
public extension Coordinates2DOf {
93+
static var zero: Self { Self.init(x: .zero, y: .zero) }
94+
}
95+
96+
// AdditiveArithmetic
97+
public extension Coordinates2DOf {
98+
static func + (lhs: Self, rhs: Self) -> Self {
99+
Self.init(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
100+
}
101+
static func - (lhs: Self, rhs: Self) -> Self {
102+
Self.init(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
103+
}
104+
}
105+
// MultiplicativeArithmetic
106+
public extension Coordinates2DOf {
107+
static func * (lhs: Self, rhs: Self) -> Self {
108+
Self.init(x: lhs.x * rhs.x, y: lhs.y * rhs.y)
109+
}
110+
static func / (lhs: Self, rhs: Self) -> Self {
111+
Self.init(x: lhs.x / rhs.x, y: lhs.y / rhs.y)
112+
}
113+
}
114+
115+
// InitializableByInteger
116+
public extension Coordinates2DOf {
117+
init<Source: BinaryInteger>(_ value: Source) {
118+
self.init(x: .init(value), y: .init(value))
119+
}
120+
}
121+
// InitializableByFloatingPoint
122+
public extension Coordinates2DOf {
123+
init<Source: BinaryFloatingPoint>(_ value: Source) {
124+
self.init(x: .init(value), y: .init(value))
125+
}
126+
}
127+
128+
public extension TwoDimensionalCoordinates where X == Latitude {
129+
var latitude: X { self.x }
130+
}
131+
public extension TwoDimensionalCoordinates where Y == Longitude {
132+
var longitude: Y { self.y }
133+
var withPositiveLongitude: Self {
134+
Self.init(x: self.x, y: self.longitude.positive)
135+
}
136+
}
137+
public extension TwoDimensionalCoordinates
138+
where X == Latitude, Y == Longitude
139+
{
140+
init(latitude: X, longitude: Y) {
141+
self.init(x: latitude, y: longitude)
142+
}
143+
}
144+
145+
// MARK: 3D Coordinates
146+
147+
public protocol AtLeastThreeDimensionalCoordinates<CRS>: AtLeastTwoDimensionalCoordinates
148+
where CRS: AtLeastTwoDimensionalCRS {
149+
associatedtype Z: CoordinateComponent
150+
151+
var z: Z { get set }
152+
}
153+
public protocol ThreeDimensionalCoordinates<CRS>: AtLeastThreeDimensionalCoordinates
154+
where Components == (X, Y, Z) {
155+
init(x: X, y: Y, z: Z)
156+
}
157+
158+
public struct Coordinates3DOf<CRS: ThreeDimensionalCRS>: ThreeDimensionalCoordinates {
159+
public typealias X = CRS.CoordinateSystem.Axis1.Value
160+
public typealias Y = CRS.CoordinateSystem.Axis2.Value
161+
public typealias Z = CRS.CoordinateSystem.Axis3.Value
162+
163+
public var x: X
164+
public var y: Y
165+
public var z: Z
166+
167+
public var components: (X, Y, Z) {
168+
get { (self.x, self.y, self.z) }
169+
set {
170+
self.x = newValue.0
171+
self.y = newValue.1
172+
self.z = newValue.2
173+
}
174+
}
175+
176+
public init(x: X, y: Y, z: Z) {
177+
#warning("TODO: Perform validations")
178+
self.x = x
179+
self.y = y
180+
self.z = z
181+
}
182+
public init(components: (X, Y, Z)) {
183+
self.init(x: components.0, y: components.1, z: components.2)
184+
}
185+
}
186+
187+
// Zeroable
188+
public extension Coordinates3DOf {
189+
static var zero: Self { Self.init(x: .zero, y: .zero, z: .zero) }
190+
}
191+
192+
// AdditiveArithmetic
193+
public extension Coordinates3DOf {
194+
static func + (lhs: Self, rhs: Self) -> Self {
195+
Self.init(x: lhs.x + rhs.x, y: lhs.y + rhs.y, z: lhs.z + rhs.z)
196+
}
197+
static func - (lhs: Self, rhs: Self) -> Self {
198+
Self.init(x: lhs.x - rhs.x, y: lhs.y - rhs.y, z: lhs.z - rhs.z)
199+
}
200+
}
201+
// MultiplicativeArithmetic
202+
public extension Coordinates3DOf {
203+
static func * (lhs: Self, rhs: Self) -> Self {
204+
Self.init(x: lhs.x * rhs.x, y: lhs.y * rhs.y, z: lhs.z * rhs.z)
205+
}
206+
static func / (lhs: Self, rhs: Self) -> Self {
207+
Self.init(x: lhs.x / rhs.x, y: lhs.y / rhs.y, z: lhs.z / rhs.z)
208+
}
209+
}
210+
211+
// InitializableByInteger
212+
public extension Coordinates3DOf {
213+
init<Source: BinaryInteger>(_ value: Source) {
214+
self.init(x: .init(value), y: .init(value), z: .init(value))
215+
}
216+
}
217+
// InitializableByFloatingPoint
218+
public extension Coordinates3DOf {
219+
init<Source: BinaryFloatingPoint>(_ value: Source) {
220+
self.init(x: .init(value), y: .init(value), z: .init(value))
221+
}
222+
}
223+
224+
public extension ThreeDimensionalCoordinates where X == Latitude {
225+
var latitude: X { self.x }
226+
}
227+
public extension ThreeDimensionalCoordinates where Y == Longitude {
228+
var longitude: Y { self.y }
229+
var withPositiveLongitude: Self {
230+
Self.init(x: self.x, y: self.longitude.positive, z: self.z)
231+
}
232+
}
233+
public extension ThreeDimensionalCoordinates where Z == Altitude {
234+
var altitude: Z { self.z }
235+
}
236+
237+
public extension ThreeDimensionalCoordinates
238+
where X == Latitude, Y == Longitude, Z == Altitude
239+
{
240+
init(latitude: X, longitude: Y, altitude: Z) {
241+
self.init(x: latitude, y: longitude, z: altitude)
242+
}
243+
}

0 commit comments

Comments
 (0)