From ae47cc106a92cc8dd8733926e2b4d053edc71213 Mon Sep 17 00:00:00 2001 From: Jacob Fielding Date: Mon, 7 Oct 2024 15:38:15 -0700 Subject: [PATCH] Feat: annotation parsing on iOS --- apple/DemoApp/Demo/DemoNavigationView.swift | 4 +- .../FerrostarCore/Models/Annotations.swift | 9 ++--- .../FerrostarCore/Models/MaxSpeed.swift | 37 ++++++++++--------- .../FerrostarCore/NavigationState.swift | 4 +- .../DynamicallyOrientingNavigationView.swift | 2 +- .../Views/LandscapeNavigationView.swift | 2 +- .../Views/PortraitNavigationView.swift | 2 +- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/apple/DemoApp/Demo/DemoNavigationView.swift b/apple/DemoApp/Demo/DemoNavigationView.swift index 6bb36b5f..f1346ccc 100644 --- a/apple/DemoApp/Demo/DemoNavigationView.swift +++ b/apple/DemoApp/Demo/DemoNavigationView.swift @@ -17,7 +17,7 @@ struct DemoNavigationView: View { // NOTE: This is probably not ideal but works for demo purposes. // This causes a thread performance checker warning log. private let spokenInstructionObserver = AVSpeechSpokenInstructionObserver(isMuted: false) - + private var locationProvider: LocationProviding @ObservedObject private var ferrostarCore: FerrostarCore @@ -227,7 +227,7 @@ struct DemoNavigationView: View { } return annotation.speedLimit?.measurementValue } - + private func preventAutoLock() { UIApplication.shared.isIdleTimerDisabled = true } diff --git a/apple/Sources/FerrostarCore/Models/Annotations.swift b/apple/Sources/FerrostarCore/Models/Annotations.swift index a6ec011e..cfb22161 100644 --- a/apple/Sources/FerrostarCore/Models/Annotations.swift +++ b/apple/Sources/FerrostarCore/Models/Annotations.swift @@ -2,20 +2,19 @@ import Foundation /// A Valhalla OSRM flavored annotations object. public struct ValhallaOsrmAnnotation: Decodable { - enum CodingKeys: String, CodingKey { case speedLimit = "maxspeed" case speed case distance case duration } - + /// The speed limit for the current line segment. public let speedLimit: MaxSpeed? - + public let speed: Double? - + public let distance: Double? - + public let duration: Double? } diff --git a/apple/Sources/FerrostarCore/Models/MaxSpeed.swift b/apple/Sources/FerrostarCore/Models/MaxSpeed.swift index b26f9e67..93fdad9b 100644 --- a/apple/Sources/FerrostarCore/Models/MaxSpeed.swift +++ b/apple/Sources/FerrostarCore/Models/MaxSpeed.swift @@ -8,32 +8,31 @@ import Foundation /// - https://docs.mapbox.com/api/navigation/directions/#route-leg-object (search for `max_speed`) /// - https://valhalla.github.io/valhalla/speeds/#assignment-of-speeds-to-roadways public enum MaxSpeed: Decodable { - public enum Units: String, Decodable { case kilometersPerHour = "km/h" case milesPerHour = "mph" case knots // "knots" are an option in core OSRM docs, though unsure if they're ever used in this context. } - + /// There is no speed limit (it's unlimited, e.g. German Autobahn) case none - + /// The speed limit is not known. case unknown - + /// The speed limit is a known value and unit (this may be localized depending on the API). case speed(Double, unit: Units) - + enum CodingKeys: CodingKey { case none case unknown case speed case unit } - + public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - + if let none = try container.decodeIfPresent(Bool.self, forKey: .none) { // The speed configuration is `{none: true}` for unlimited. self = .none @@ -41,29 +40,31 @@ public enum MaxSpeed: Decodable { // The speed configuration is `{unknown: true}` for unknown. self = .unknown } else if let value = try container.decodeIfPresent(Double.self, forKey: .speed), - let unit = try container.decodeIfPresent(Units.self, forKey: .unit) { + let unit = try container.decodeIfPresent(Units.self, forKey: .unit) + { // The speed is a known value with units. Some API's may localize, others only support a single unit. self = .speed(value, unit: unit) } else { - throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Invalid MaxSpeed, see docstrings for reference links")) + throw DecodingError.dataCorrupted(.init( + codingPath: decoder.codingPath, + debugDescription: "Invalid MaxSpeed, see docstrings for reference links" + )) } } - + /// The MaxSpeed as a measurement public var measurementValue: Measurement? { switch self { - - case .none: return nil - case .unknown: return nil - case .speed(let value, let unit): + case .none: nil + case .unknown: nil + case let .speed(value, unit): switch unit { - case .kilometersPerHour: - return .init(value: value, unit: .kilometersPerHour) + .init(value: value, unit: .kilometersPerHour) case .milesPerHour: - return .init(value: value, unit: .milesPerHour) + .init(value: value, unit: .milesPerHour) case .knots: - return .init(value: value, unit: .knots) + .init(value: value, unit: .knots) } } } diff --git a/apple/Sources/FerrostarCore/NavigationState.swift b/apple/Sources/FerrostarCore/NavigationState.swift index a8b0fea8..1c13f396 100644 --- a/apple/Sources/FerrostarCore/NavigationState.swift +++ b/apple/Sources/FerrostarCore/NavigationState.swift @@ -57,7 +57,7 @@ public struct NavigationState: Hashable { return annotationJson } - + /// The current geometry segment's annotations. /// /// A segment is the line between two coordinates on the geometry. @@ -69,7 +69,7 @@ public struct NavigationState: Hashable { guard let data = currentAnnotationJSON?.data(using: .utf8) else { return nil } - + return try JSONDecoder().decode(type, from: data) } } diff --git a/apple/Sources/FerrostarMapLibreUI/Views/DynamicallyOrientingNavigationView.swift b/apple/Sources/FerrostarMapLibreUI/Views/DynamicallyOrientingNavigationView.swift index 5f08bfc3..2e433c41 100644 --- a/apple/Sources/FerrostarMapLibreUI/Views/DynamicallyOrientingNavigationView.swift +++ b/apple/Sources/FerrostarMapLibreUI/Views/DynamicallyOrientingNavigationView.swift @@ -26,7 +26,7 @@ public struct DynamicallyOrientingNavigationView: View, CustomizableNavigatingIn var calculateSpeedLimit: ((NavigationState?) -> Measurement?)? @State var speedLimit: Measurement? - + var onTapExit: (() -> Void)? public var minimumSafeAreaInsets: EdgeInsets diff --git a/apple/Sources/FerrostarMapLibreUI/Views/LandscapeNavigationView.swift b/apple/Sources/FerrostarMapLibreUI/Views/LandscapeNavigationView.swift index 9c5b0440..efc8250a 100644 --- a/apple/Sources/FerrostarMapLibreUI/Views/LandscapeNavigationView.swift +++ b/apple/Sources/FerrostarMapLibreUI/Views/LandscapeNavigationView.swift @@ -25,7 +25,7 @@ public struct LandscapeNavigationView: View, CustomizableNavigatingInnerGridView var calculateSpeedLimit: ((NavigationState?) -> Measurement?)? @State var speedLimit: Measurement? - + var onTapExit: (() -> Void)? public var minimumSafeAreaInsets: EdgeInsets diff --git a/apple/Sources/FerrostarMapLibreUI/Views/PortraitNavigationView.swift b/apple/Sources/FerrostarMapLibreUI/Views/PortraitNavigationView.swift index 2b01b7af..a742ba17 100644 --- a/apple/Sources/FerrostarMapLibreUI/Views/PortraitNavigationView.swift +++ b/apple/Sources/FerrostarMapLibreUI/Views/PortraitNavigationView.swift @@ -28,7 +28,7 @@ public struct PortraitNavigationView: View, CustomizableNavigatingInnerGridView var calculateSpeedLimit: ((NavigationState?) -> Measurement?)? @State var speedLimit: Measurement? - + var onTapExit: (() -> Void)? /// Create a portrait navigation view. This view is optimized for display on a portrait screen where the