From a8ae3cfc9346542600c5a17c10c1a6057693c38f Mon Sep 17 00:00:00 2001 From: Alex Azarov Date: Thu, 22 Apr 2021 14:32:23 +0300 Subject: [PATCH 1/3] Remove ElectronicHorizon struct --- CHANGELOG.md | 1 + Example/ViewController+FreeDrive.swift | 16 ++-- Example/ViewController.swift | 4 +- MapboxNavigation.xcodeproj/project.pbxproj | 4 - .../MapboxCoreNavigation/CoreConstants.swift | 13 +-- .../CoreNavigationNavigator.swift | 8 +- .../EHorizon/ElectronicHorizon.swift | 19 ----- .../EHorizon/ElectronicHorizonEdge.swift | 79 +++++++++---------- .../ElectronicHorizonEdgeMetadata.swift | 2 +- .../EHorizon/RoadGraph.swift | 6 +- .../EHorizon/RoadGraphPath.swift | 2 +- .../EHorizon/RoadGraphPosition.swift | 2 +- .../EHorizon/RoadObjectsStore.swift | 6 +- 13 files changed, 70 insertions(+), 92 deletions(-) delete mode 100644 Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizon.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c78f493a5..54d9ac4817 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ * Added the `Directions.calculateOffline(options:completionHandler:)` and `Directions.calculateWithCache(options:completionHandler:)` methods, which incorporate routing tiles from the predictive cache when possible to avoid relying on a network connection to calculate the route. `RouteController` now also uses the predictive cache when rerouting. ([#2848](https://github.com/mapbox/mapbox-navigation-ios/pull/2848)) * Fixed an issue where `PassiveLocationDataSource` and `RouteController` did not use the access token and host specified by `PassiveLocationDataSource.directions` and `RouteController.directions`, respectively. Added the `PredictiveCacheOptions.credentials` property for specifying the access token and host used for prefetching resources. ([#2876](https://github.com/mapbox/mapbox-navigation-ios/pull/2876)) * The top banner can now show a wider variety of turn lane configurations, such as combination U-turn/left turn lanes and combination through/slight right turn lanes. ([#2882](https://github.com/mapbox/mapbox-navigation-ios/pull/2882)) +* Removed `ElectronicHorizon` struct, now an electronic horizon notification directly contain pointer to a starting edge. `ElectronicHorizon.Edge` was renamed to `ElectronicHorizonEdge`. ## v1.3.0 diff --git a/Example/ViewController+FreeDrive.swift b/Example/ViewController+FreeDrive.swift index 4946a7d3ad..d432f210ce 100644 --- a/Example/ViewController+FreeDrive.swift +++ b/Example/ViewController+FreeDrive.swift @@ -97,17 +97,17 @@ extension ViewController { } @objc func didUpdateElectronicHorizonPosition(_ notification: Notification) { - guard let horizon = notification.userInfo?[ElectronicHorizon.NotificationUserInfoKey.treeKey] as? ElectronicHorizon else { + guard let horizon = notification.userInfo?[ElectronicHorizonEdge.NotificationUserInfoKey.treeKey] as? ElectronicHorizonEdge else { return } // Avoid repeating edges that have already been printed out. - guard currentEdgeIdentifier != horizon.start.identifier || - nextEdgeIdentifier != horizon.start.outletEdges.first?.identifier else { + guard currentEdgeIdentifier != horizon.identifier || + nextEdgeIdentifier != horizon.outletEdges.first?.identifier else { return } - currentEdgeIdentifier = horizon.start.identifier - nextEdgeIdentifier = horizon.start.outletEdges.first?.identifier + currentEdgeIdentifier = horizon.identifier + nextEdgeIdentifier = horizon.outletEdges.first?.identifier guard let currentEdgeIdentifier = currentEdgeIdentifier, let nextEdgeIdentifier = nextEdgeIdentifier else { return @@ -117,15 +117,15 @@ extension ViewController { var statusString = "Currently on \(edgeNames(identifier: currentEdgeIdentifier).joined(separator: " / ")), approaching \(edgeNames(identifier: nextEdgeIdentifier).joined(separator: " / "))" // If there is an upcoming intersection, include the names of the cross streets. - let branchEdgeIdentifiers = horizon.start.outletEdges.suffix(from: 1).map({ $0.identifier }) + let branchEdgeIdentifiers = horizon.outletEdges.suffix(from: 1).map({ $0.identifier }) if !branchEdgeIdentifiers.isEmpty { let branchNames = branchEdgeIdentifiers.flatMap { edgeNames(identifier: $0) } statusString += " at \(branchNames.joined(separator: ", "))" } } - func edgeNames(identifier: ElectronicHorizon.Edge.Identifier) -> [String] { - let passiveLocationDataSource = (navigationMapView.mapView.location.locationProvider as! PassiveLocationManager).dataSource + func edgeNames(identifier: ElectronicHorizonEdge.Identifier) -> [String] { + let passiveLocationDataSource = (navigationMapView.mapView.locationManager.locationProvider as! PassiveLocationManager).dataSource guard let metadata = passiveLocationDataSource.roadGraph.edgeMetadata(edgeIdentifier: identifier) else { return [] } diff --git a/Example/ViewController.swift b/Example/ViewController.swift index f20c0927c1..af2d65ba39 100755 --- a/Example/ViewController.swift +++ b/Example/ViewController.swift @@ -20,8 +20,8 @@ class ViewController: UIViewController { var rawTrackStyledFeature: StyledFeature! var speedLimitView: SpeedLimitView! - var currentEdgeIdentifier: ElectronicHorizon.Edge.Identifier? - var nextEdgeIdentifier: ElectronicHorizon.Edge.Identifier? + var currentEdgeIdentifier: ElectronicHorizonEdge.Identifier? + var nextEdgeIdentifier: ElectronicHorizonEdge.Identifier? typealias RouteRequestSuccess = ((RouteResponse) -> Void) typealias RouteRequestFailure = ((Error) -> Void) diff --git a/MapboxNavigation.xcodeproj/project.pbxproj b/MapboxNavigation.xcodeproj/project.pbxproj index 8578ab19fb..e36d8d9af4 100644 --- a/MapboxNavigation.xcodeproj/project.pbxproj +++ b/MapboxNavigation.xcodeproj/project.pbxproj @@ -373,7 +373,6 @@ DA303CA621B7A90100F921DC /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3529FCF521A5C5D900AEA9AA /* UIViewController.swift */; }; DA3525702010A5210048DDFC /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DA35256E2010A5200048DDFC /* Localizable.stringsdict */; }; DA443DDE2278C90E00ED1307 /* CPTrip.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA443DDD2278C90E00ED1307 /* CPTrip.swift */; }; - DA5F449A25F07A5C00F573EC /* ElectronicHorizon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F449925F07A5C00F573EC /* ElectronicHorizon.swift */; }; DA5F44AA25F07A6800F573EC /* RoadObjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44A325F07A6500F573EC /* RoadObjectType.swift */; }; DA5F44AC25F07A6800F573EC /* RoadGraphPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44A525F07A6500F573EC /* RoadGraphPosition.swift */; }; DA5F44AE25F07A6800F573EC /* RoadObjectDistanceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44A725F07A6500F573EC /* RoadObjectDistanceInfo.swift */; }; @@ -950,7 +949,6 @@ DA545AC41FAA86450090908E /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; DA5AD03C1FEBA03700FC7D7B /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Main.strings; sourceTree = ""; }; DA5AD0401FEBA23200FC7D7B /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Localizable.strings; sourceTree = ""; }; - DA5F449925F07A5C00F573EC /* ElectronicHorizon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronicHorizon.swift; sourceTree = ""; }; DA5F44A325F07A6500F573EC /* RoadObjectType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadObjectType.swift; sourceTree = ""; }; DA5F44A525F07A6500F573EC /* RoadGraphPosition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadGraphPosition.swift; sourceTree = ""; }; DA5F44A725F07A6500F573EC /* RoadObjectDistanceInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadObjectDistanceInfo.swift; sourceTree = ""; }; @@ -1865,7 +1863,6 @@ DA5F446325F0744C00F573EC /* EHorizon */ = { isa = PBXGroup; children = ( - DA5F449925F07A5C00F573EC /* ElectronicHorizon.swift */, DA5F44A925F07A6700F573EC /* ElectronicHorizonEdge.swift */, DA5F44B925F07AA500F573EC /* ElectronicHorizonEdgeMetadata.swift */, DA5F44FF25F07DE200F573EC /* ElectronicHorizonOptions.swift */, @@ -2776,7 +2773,6 @@ DA754E1923AC56E5007E16B5 /* MBXAccountsLoader.m in Sources */, 2BE701252535943900F46E4E /* BorderCrossing.swift in Sources */, 3582A25020EEC46B0029C5DE /* Router.swift in Sources */, - DA5F449A25F07A5C00F573EC /* ElectronicHorizon.swift in Sources */, 8D75F991212B5C7F00F99CF3 /* TunnelAuthority.swift in Sources */, C5E7A31C1F4F6828001CB015 /* NavigationRouteOptions.swift in Sources */, 352F464D20EB74C200147886 /* NavigationEventsManager.swift in Sources */, diff --git a/Sources/MapboxCoreNavigation/CoreConstants.swift b/Sources/MapboxCoreNavigation/CoreConstants.swift index 4cb8b35def..2f5a89e2a6 100644 --- a/Sources/MapboxCoreNavigation/CoreConstants.swift +++ b/Sources/MapboxCoreNavigation/CoreConstants.swift @@ -308,28 +308,28 @@ public extension Notification.Name { /** Posted when the user’s position in the electronic horizon changes. This notification may be posted multiple times after `electronicHorizonDidEnterRoadObject` until the user transitions to a new electronic horizon. - The user info dictionary contains the keys `ElectronicHorizon.NotificationUserInfoKey.positionKey`, `ElectronicHorizon.NotificationUserInfoKey.treeKey`, `ElectronicHorizon.NotificationUserInfoKey.updatesMostProbablePathKey`, and `ElectronicHorizon.NotificationUserInfoKey.distancesByRoadObjectKey`. + The user info dictionary contains the keys `ElectronicHorizonEdge.NotificationUserInfoKey.positionKey`, `ElectronicHorizonEdge.NotificationUserInfoKey.treeKey`, `ElectronicHorizonEdge.NotificationUserInfoKey.updatesMostProbablePathKey`, and `ElectronicHorizonEdge.NotificationUserInfoKey.distancesByRoadObjectKey`. */ static let electronicHorizonDidUpdatePosition: Notification.Name = .init(rawValue: "ElectronicHorizonDidUpdatePosition") /** Posted when the user enters a linear road object. - The user info dictionary contains the keys `ElectronicHorizon.NotificationUserInfoKey.roadObjectIdentifierKey` and `ElectronicHorizon.NotificationUserInfoKey.didTransitionAtEndpointKey`. + The user info dictionary contains the keys `ElectronicHorizonEdge.NotificationUserInfoKey.roadObjectIdentifierKey` and `ElectronicHorizonEdge.NotificationUserInfoKey.didTransitionAtEndpointKey`. */ static let electronicHorizonDidEnterRoadObject: Notification.Name = .init(rawValue: "ElectronicHorizonDidEnterRoadObject") /** Posted when the user exits a linear road object. - The user info dictionary contains the keys `ElectronicHorizon.NotificationUserInfoKey.roadObjectIdentifierKey` and `ElectronicHorizon.NotificationUserInfoKey.transitionKey`. + The user info dictionary contains the keys `ElectronicHorizonEdge.NotificationUserInfoKey.roadObjectIdentifierKey` and `ElectronicHorizonEdge.NotificationUserInfoKey.transitionKey`. */ static let electronicHorizonDidExitRoadObject: Notification.Name = .init(rawValue: "ElectronicHorizonDidExitRoadObject") } -extension ElectronicHorizon { +extension ElectronicHorizonEdge { /** - Keys in the user info dictionaries of various notifications posted by instances of `RouteController` or `PassiveLocationDataSource` about `ElectronicHorizon`s. + Keys in the user info dictionaries of various notifications posted by instances of `RouteController` or `PassiveLocationDataSource` about `ElectronicHorizonEdge`s. */ public struct NotificationUserInfoKey: Hashable, Equatable, RawRepresentable { public typealias RawValue = String @@ -343,7 +343,8 @@ extension ElectronicHorizon { public static let positionKey: NotificationUserInfoKey = .init(rawValue: "position") /** - A key in the user info dictionary of a `Notification.Name.electronicHorizonDidUpdatePosition` notification. The corresponding value is an `ElectronicHorizon` at the root of a tree of edges in the routing graph. */ + A key in the user info dictionary of a `Notification.Name.electronicHorizonDidUpdatePosition` notification. The corresponding value is an `ElectronicHorizonEdge` at the root of a tree of edges in the routing graph. This graph represents a probable path (or paths) of a vehicle within the routing graph for a certain distance in front of the vehicle, thus extending the user’s perspective beyond the “visible” horizon as the vehicle’s position and trajectory change. + */ public static let treeKey: NotificationUserInfoKey = .init(rawValue: "tree") /** diff --git a/Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift b/Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift index 229a01740f..9e8ee40f2e 100644 --- a/Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift +++ b/Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift @@ -147,9 +147,9 @@ class Navigator { extension Navigator: ElectronicHorizonObserver { public func onPositionUpdated(for position: ElectronicHorizonPosition, distances: [String : MapboxNavigationNative.RoadObjectDistanceInfo]) { - let userInfo: [ElectronicHorizon.NotificationUserInfoKey: Any] = [ + let userInfo: [ElectronicHorizonEdge.NotificationUserInfoKey: Any] = [ .positionKey: RoadGraph.Position(position.position()), - .treeKey: ElectronicHorizon(position.tree()), + .treeKey: try! position.tree(), .updatesMostProbablePathKey: position.type() == .UPDATE, .distancesByRoadObjectKey: distances.mapValues(RoadObjectDistanceInfo.init), ] @@ -157,7 +157,7 @@ extension Navigator: ElectronicHorizonObserver { } public func onRoadObjectEnter(for info: RoadObjectEnterExitInfo) { - let userInfo: [ElectronicHorizon.NotificationUserInfoKey: Any] = [ + let userInfo: [ElectronicHorizonEdge.NotificationUserInfoKey: Any] = [ .roadObjectIdentifierKey: info.roadObjectId, .didTransitionAtEndpointKey: info.isEnterFromStartOrExitFromEnd, ] @@ -165,7 +165,7 @@ extension Navigator: ElectronicHorizonObserver { } public func onRoadObjectExit(for info: RoadObjectEnterExitInfo) { - let userInfo: [ElectronicHorizon.NotificationUserInfoKey: Any] = [ + let userInfo: [ElectronicHorizonEdge.NotificationUserInfoKey: Any] = [ .roadObjectIdentifierKey: info.roadObjectId, .didTransitionAtEndpointKey: info.isEnterFromStartOrExitFromEnd, ] diff --git a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizon.swift b/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizon.swift deleted file mode 100644 index 28eadab109..0000000000 --- a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizon.swift +++ /dev/null @@ -1,19 +0,0 @@ -import Foundation -import MapboxNavigationNative - -/** - An electronic horizon is a probable path (or paths) of a vehicle within the routing graph. This structure contains metadata about the underlying edges of the graph for a certain distance in front of the vehicle, thus extending the user’s perspective beyond the “visible” horizon as the vehicle’s position and trajectory change. - - During active turn-by-turn navigation, the user-selected route and its metadata influence the path of the electronic horizon determined by `RouteController`. During passive navigation (free-driving), no route is actively selected, so `PassiveLocationDataSource` will determine the most probable path from the vehicle’s current location. You can receive notifications about changes in the current state of the electronic horizon by observing the `Notification.Name.electronicHorizonDidUpdatePosition`, `Notification.Name.electronicHorizonDidEnterRoadObject`, and `Notification.Name.electronicHorizonDidExitRoadObject` notifications. - - The road network ahead of the user is represented as a tree of edges. Each intersection has outlet edges. In turn, each edge has a probability of transition to another edge, as well as details about the road segment that the edge traverses. You can use these details to influence application behavior based on predicted upcoming conditions. - */ -public struct ElectronicHorizon { - - /// The starting edge leading to the upcoming probable paths. - public let start: Edge - - init(_ native: MapboxNavigationNative.ElectronicHorizon) { - self.start = Edge(native.start) - } -} diff --git a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdge.swift b/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdge.swift index cfe44d4fe0..4f7dc5ced9 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdge.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdge.swift @@ -1,48 +1,47 @@ import Foundation import MapboxNavigationNative -extension ElectronicHorizon { +/** + An electronic horizon is a probable path (or paths) of a vehicle. This structure contains metadata about an edge in a routing graph. For example, an edge may represent a road segment between two intersections or between the two ends of a bridge. An edge may traverse multiple road objects, and a road object may be associated with multiple edges. The road network ahead of the user is represented as a tree of edges. Each intersection has outlet edges. In turn, each edge has a probability of transition to another edge, as well as details about the road segment that the edge traverses. You can use these details to influence application behavior based on predicted upcoming conditions. + + During active turn-by-turn navigation, the user-selected route and its metadata influence the path of the electronic horizon determined by `RouteController`. During passive navigation (free-driving), no route is actively selected, so `PassiveLocationDataSource` will determine the most probable path from the vehicle’s current location. You can receive notifications about changes in the current state of the electronic horizon by observing the `Notification.Name.electronicHorizonDidUpdatePosition`, `Notification.Name.electronicHorizonDidEnterRoadObject`, and `Notification.Name.electronicHorizonDidExitRoadObject` notifications. + + Use a `RoadGraph` object to get an edge with a given identifier. + */ +public struct ElectronicHorizonEdge { + /** + Unique identifier of a directed edge. + + Use a `RoadGraph` object to get more information about the edge with a given identifier. + */ + public typealias Identifier = UInt + + /** Unique identifier of the directed edge. */ + public let identifier: Identifier /** - An edge in a routing graph. For example, an edge may represent a road segment between two intersections or between the two ends of a bridge. An edge may traverse multiple road objects, and a road object may be associated with multiple edges. - - Use a `RoadGraph` object to get an edge with a given identifier. + The level of the edge. + + A value of 0 indicates that the edge is part of the most probable path (MPP), a value of 1 indicates an edge that branches away from the MPP, and so on. */ - public struct Edge { - /** - Unique identifier of a directed edge. - - Use a `RoadGraph` object to get more information about the edge with a given identifier. - */ - public typealias Identifier = UInt - - /** Unique identifier of the directed edge. */ - public let identifier: Identifier - - /** - The level of the edge. - - A value of 0 indicates that the edge is part of the most probable path (MPP), a value of 1 indicates an edge that branches away from the MPP, and so on. - */ - public let level: UInt - - /** - The probability that the user will transition onto this edge, with 1 being certain and 0 being unlikely. - */ - public let probability: Double - - /** - The edges to which the user could transition from this edge. - - The most probable path may be split at some point if some of edges have a low probability difference (±0.05). For example, `outletEdges` can contain more than one edge with `level` set to 0. Currently, there is a maximum limit of one split per electronic horizon. - */ - public let outletEdges: [Edge] - - init(_ native: ElectronicHorizonEdge) { - self.identifier = UInt(native.id) - self.level = UInt(native.level) - self.probability = native.probability - self.outletEdges = native.out.map(Edge.init) - } + public let level: UInt + + /** + The probability that the user will transition onto this edge, with 1 being certain and 0 being unlikely. + */ + public let probability: Double + + /** + The edges to which the user could transition from this edge. + + The most probable path may be split at some point if some of edges have a low probability difference (±0.05). For example, `outletEdges` can contain more than one edge with `level` set to 0. Currently, there is a maximum limit of one split per electronic horizon. + */ + public let outletEdges: [ElectronicHorizonEdge] + + init(_ native: MapboxNavigationNative.ElectronicHorizonEdge) { + self.identifier = UInt(native.id) + self.level = UInt(native.level) + self.probability = native.probability + self.outletEdges = native.out.map(ElectronicHorizonEdge.init) } } diff --git a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdgeMetadata.swift b/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdgeMetadata.swift index 1e6564a207..3bccd59ebc 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdgeMetadata.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdgeMetadata.swift @@ -3,7 +3,7 @@ import CoreLocation import MapboxDirections import MapboxNavigationNative -extension ElectronicHorizon.Edge { +extension ElectronicHorizonEdge { /** Indicates how many directions the user may travel along an edge. */ diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift index e712bafcce..c0a935a4c5 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift @@ -3,7 +3,7 @@ import Turf import MapboxNavigationNative /** - `RoadGraph` provides methods to get edge shape (e.g. `ElectronicHorizon.Edge`) and metadata. + `RoadGraph` provides methods to get edge shape (e.g. `ElectronicHorizonEdge`) and metadata. You do not create a `RoadGraph` object manually. Instead, observe the `Notification.Name.electronicHorizonDidUpdatePosition` notification to obtain edge identifiers and get more details about the edges using the `RouteController.roadGraph` or `PassiveLocationDataSource.roadGraph` property. */ @@ -14,7 +14,7 @@ public final class RoadGraph { - returns: Metadata about the edge with the given edge identifier, or `nil` if the edge is inaccessible. */ - public func edgeMetadata(edgeIdentifier: ElectronicHorizon.Edge.Identifier) -> ElectronicHorizon.Edge.Metadata? { + public func edgeMetadata(edgeIdentifier: ElectronicHorizonEdge.Identifier) -> ElectronicHorizonEdge.Metadata? { if let edgeMetadata = native.getEdgeMetadata(forEdgeId: UInt64(edgeIdentifier)) { return ElectronicHorizon.Edge.Metadata(edgeMetadata) } @@ -26,7 +26,7 @@ public final class RoadGraph { - returns: A line string corresponding to the given edge identifier, or `nil` if the edge is inaccessible. */ - public func edgeShape(edgeIdentifier: ElectronicHorizon.Edge.Identifier) -> LineString? { + public func edgeShape(edgeIdentifier: ElectronicHorizonEdge.Identifier) -> LineString? { guard let locations = native.getEdgeShape(forEdgeId: UInt64(edgeIdentifier)) else { return nil } diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift index 638eb3ce2d..6f610226bb 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift @@ -7,7 +7,7 @@ extension RoadGraph { /** A position along a linear object in the road graph. */ public struct Path { /** The edge identifiers that fully or partially coincide with the linear object. */ - public let edgeIdentifiers: [ElectronicHorizon.Edge.Identifier] + public let edgeIdentifiers: [ElectronicHorizonEdge.Identifier] /** The distance from the start of an edge to the start of the linear object as a fraction of the edge’s length from 0 to 1. */ public let fractionFromStart: Double diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift index 730bd9042c..7346e7715c 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift @@ -7,7 +7,7 @@ extension RoadGraph { public struct Position { /** The edge identifier along which the point object lies. */ - public let edgeIdentifier: ElectronicHorizon.Edge.Identifier + public let edgeIdentifier: ElectronicHorizonEdge.Identifier /** The distance from the start of an edge to the point object as a fraction of the edge’s length from 0 to 1. */ public let fractionFromStart: Double diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadObjectsStore.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadObjectsStore.swift index e2e56f2b58..5ab3ff298c 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadObjectsStore.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadObjectsStore.swift @@ -4,7 +4,7 @@ import MapboxNavigationNative /** Identifies a road object in an electronic horizon. A road object represents a notable transition point along a road, such as a toll booth or tunnel entrance. A road object is similar to a `RouteAlert` but is more closely associated with the routing graph managed by the `RoadGraph` class. - Use a `RoadObjectsStore` object to get more information about a road object with a given identifier or get the locations of road objects along `ElectronicHorizon.Edge`s. + Use a `RoadObjectsStore` object to get more information about a road object with a given identifier or get the locations of road objects along `ElectronicHorizonEdge`s. */ public typealias RoadObjectIdentifier = String @@ -30,8 +30,8 @@ public final class RoadObjectsStore { which are lying on the edge with given identifier. - parameter edgeIdentifier: The identifier of the edge to query. */ - public func roadObjectEdgeLocations(edgeIdentifier: ElectronicHorizon.Edge.Identifier) -> [RoadObjectIdentifier : RoadObjectEdgeLocation] { let objects = native.getForEdgeId(UInt64(edgeIdentifier)) + public func roadObjectEdgeLocations(edgeIdentifier: ElectronicHorizonEdge.Identifier) -> [RoadObjectIdentifier : RoadObjectEdgeLocation] { return objects.mapValues(RoadObjectEdgeLocation.init) } @@ -65,7 +65,7 @@ public final class RoadObjectsStore { Returns list of road object ids which are (partially) belong to `edgeIds`. - parameter edgeIds list of edge ids */ - public func roadObjectIdentifiers(edgeIdentifiers: [ElectronicHorizon.Edge.Identifier]) -> [RoadObjectIdentifier] { + public func roadObjectIdentifiers(edgeIdentifiers: [ElectronicHorizonEdge.Identifier]) -> [RoadObjectIdentifier] { return native.getRoadObjectIdsByEdgeIds(forEdgeIds: edgeIdentifiers.map(NSNumber.init)) } From 31c1a7685cc4671dfbc1e0ee97817a749c5c84bd Mon Sep 17 00:00:00 2001 From: Alex Azarov Date: Tue, 27 Apr 2021 18:36:22 +0300 Subject: [PATCH 2/3] Rename ElectronicHorizonEdge to RoadGraph.Edge. --- CHANGELOG.md | 2 +- Example/ViewController+FreeDrive.swift | 6 +-- Example/ViewController.swift | 4 +- MapboxNavigation.xcodeproj/project.pbxproj | 16 +++--- .../MapboxCoreNavigation/CoreConstants.swift | 12 ++--- .../CoreNavigationNavigator.swift | 6 +-- .../EHorizon/ElectronicHorizonEdge.swift | 47 ----------------- .../EHorizon/RoadGraph.swift | 8 +-- .../EHorizon/RoadGraphEdge.swift | 52 +++++++++++++++++++ ...data.swift => RoadGraphEdgeMetadata.swift} | 2 +- .../EHorizon/RoadGraphPath.swift | 2 +- .../EHorizon/RoadGraphPosition.swift | 2 +- .../EHorizon/RoadObjectsStore.swift | 6 +-- 13 files changed, 85 insertions(+), 80 deletions(-) delete mode 100644 Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdge.swift create mode 100644 Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdge.swift rename Sources/MapboxCoreNavigation/EHorizon/{ElectronicHorizonEdgeMetadata.swift => RoadGraphEdgeMetadata.swift} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54d9ac4817..1d730ab8f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,7 +63,7 @@ * Added the `Directions.calculateOffline(options:completionHandler:)` and `Directions.calculateWithCache(options:completionHandler:)` methods, which incorporate routing tiles from the predictive cache when possible to avoid relying on a network connection to calculate the route. `RouteController` now also uses the predictive cache when rerouting. ([#2848](https://github.com/mapbox/mapbox-navigation-ios/pull/2848)) * Fixed an issue where `PassiveLocationDataSource` and `RouteController` did not use the access token and host specified by `PassiveLocationDataSource.directions` and `RouteController.directions`, respectively. Added the `PredictiveCacheOptions.credentials` property for specifying the access token and host used for prefetching resources. ([#2876](https://github.com/mapbox/mapbox-navigation-ios/pull/2876)) * The top banner can now show a wider variety of turn lane configurations, such as combination U-turn/left turn lanes and combination through/slight right turn lanes. ([#2882](https://github.com/mapbox/mapbox-navigation-ios/pull/2882)) -* Removed `ElectronicHorizon` struct, now an electronic horizon notification directly contain pointer to a starting edge. `ElectronicHorizon.Edge` was renamed to `ElectronicHorizonEdge`. +* Removed `ElectronicHorizon` struct, now an electronic horizon notification directly contain pointer to a starting edge. `ElectronicHorizon.Edge` was renamed to `RoadGraph.Edge`. `ElectronicHorizon.NotificationUserInfoKey` was renamed to `RoadGraph.NotificationUserInfoKey`. ## v1.3.0 diff --git a/Example/ViewController+FreeDrive.swift b/Example/ViewController+FreeDrive.swift index d432f210ce..59367b9350 100644 --- a/Example/ViewController+FreeDrive.swift +++ b/Example/ViewController+FreeDrive.swift @@ -97,7 +97,7 @@ extension ViewController { } @objc func didUpdateElectronicHorizonPosition(_ notification: Notification) { - guard let horizon = notification.userInfo?[ElectronicHorizonEdge.NotificationUserInfoKey.treeKey] as? ElectronicHorizonEdge else { + guard let horizon = notification.userInfo?[RoadGraph.NotificationUserInfoKey.treeKey] as? RoadGraph.Edge else { return } @@ -124,8 +124,8 @@ extension ViewController { } } - func edgeNames(identifier: ElectronicHorizonEdge.Identifier) -> [String] { - let passiveLocationDataSource = (navigationMapView.mapView.locationManager.locationProvider as! PassiveLocationManager).dataSource + func edgeNames(identifier: RoadGraph.Edge.Identifier) -> [String] { + let passiveLocationDataSource = (navigationMapView.mapView.location.locationProvider as! PassiveLocationManager).dataSource guard let metadata = passiveLocationDataSource.roadGraph.edgeMetadata(edgeIdentifier: identifier) else { return [] } diff --git a/Example/ViewController.swift b/Example/ViewController.swift index af2d65ba39..f8e6c5962c 100755 --- a/Example/ViewController.swift +++ b/Example/ViewController.swift @@ -20,8 +20,8 @@ class ViewController: UIViewController { var rawTrackStyledFeature: StyledFeature! var speedLimitView: SpeedLimitView! - var currentEdgeIdentifier: ElectronicHorizonEdge.Identifier? - var nextEdgeIdentifier: ElectronicHorizonEdge.Identifier? + var currentEdgeIdentifier: RoadGraph.Edge.Identifier? + var nextEdgeIdentifier: RoadGraph.Edge.Identifier? typealias RouteRequestSuccess = ((RouteResponse) -> Void) typealias RouteRequestFailure = ((Error) -> Void) diff --git a/MapboxNavigation.xcodeproj/project.pbxproj b/MapboxNavigation.xcodeproj/project.pbxproj index e36d8d9af4..56e1bef03e 100644 --- a/MapboxNavigation.xcodeproj/project.pbxproj +++ b/MapboxNavigation.xcodeproj/project.pbxproj @@ -376,8 +376,8 @@ DA5F44AA25F07A6800F573EC /* RoadObjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44A325F07A6500F573EC /* RoadObjectType.swift */; }; DA5F44AC25F07A6800F573EC /* RoadGraphPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44A525F07A6500F573EC /* RoadGraphPosition.swift */; }; DA5F44AE25F07A6800F573EC /* RoadObjectDistanceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44A725F07A6500F573EC /* RoadObjectDistanceInfo.swift */; }; - DA5F44B025F07A6800F573EC /* ElectronicHorizonEdge.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44A925F07A6700F573EC /* ElectronicHorizonEdge.swift */; }; - DA5F44BA25F07AA500F573EC /* ElectronicHorizonEdgeMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44B925F07AA500F573EC /* ElectronicHorizonEdgeMetadata.swift */; }; + DA5F44B025F07A6800F573EC /* RoadGraphEdge.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44A925F07A6700F573EC /* RoadGraphEdge.swift */; }; + DA5F44BA25F07AA500F573EC /* RoadGraphEdgeMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44B925F07AA500F573EC /* RoadGraphEdgeMetadata.swift */; }; DA5F44C625F07AB700F573EC /* RoadGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44C325F07AB500F573EC /* RoadGraph.swift */; }; DA5F44C725F07AB700F573EC /* RoadName.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44C425F07AB500F573EC /* RoadName.swift */; }; DA5F44C825F07AB700F573EC /* MapboxStreetsRoadClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44C525F07AB600F573EC /* MapboxStreetsRoadClass.swift */; }; @@ -952,8 +952,8 @@ DA5F44A325F07A6500F573EC /* RoadObjectType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadObjectType.swift; sourceTree = ""; }; DA5F44A525F07A6500F573EC /* RoadGraphPosition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadGraphPosition.swift; sourceTree = ""; }; DA5F44A725F07A6500F573EC /* RoadObjectDistanceInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadObjectDistanceInfo.swift; sourceTree = ""; }; - DA5F44A925F07A6700F573EC /* ElectronicHorizonEdge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronicHorizonEdge.swift; sourceTree = ""; }; - DA5F44B925F07AA500F573EC /* ElectronicHorizonEdgeMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronicHorizonEdgeMetadata.swift; sourceTree = ""; }; + DA5F44A925F07A6700F573EC /* RoadGraphEdge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadGraphEdge.swift; sourceTree = ""; }; + DA5F44B925F07AA500F573EC /* RoadGraphEdgeMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadGraphEdgeMetadata.swift; sourceTree = ""; }; DA5F44C325F07AB500F573EC /* RoadGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadGraph.swift; sourceTree = ""; }; DA5F44C425F07AB500F573EC /* RoadName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoadName.swift; sourceTree = ""; }; DA5F44C525F07AB600F573EC /* MapboxStreetsRoadClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapboxStreetsRoadClass.swift; sourceTree = ""; }; @@ -1863,10 +1863,10 @@ DA5F446325F0744C00F573EC /* EHorizon */ = { isa = PBXGroup; children = ( - DA5F44A925F07A6700F573EC /* ElectronicHorizonEdge.swift */, - DA5F44B925F07AA500F573EC /* ElectronicHorizonEdgeMetadata.swift */, DA5F44FF25F07DE200F573EC /* ElectronicHorizonOptions.swift */, DA5F44C325F07AB500F573EC /* RoadGraph.swift */, + DA5F44A925F07A6700F573EC /* RoadGraphEdge.swift */, + DA5F44B925F07AA500F573EC /* RoadGraphEdgeMetadata.swift */, DA2A01EF25F308B100AAB4C6 /* RoadGraphPath.swift */, DA5F44A525F07A6500F573EC /* RoadGraphPosition.swift */, DA5F44C425F07AB500F573EC /* RoadName.swift */, @@ -2779,7 +2779,7 @@ 351174F41EF1C0530065E248 /* ReplayLocationManager.swift in Sources */, 2BE701172535940D00F46E4E /* Tunnel.swift in Sources */, 8A3A219025EEC00200EDA999 /* CoreNavigationNavigator.swift in Sources */, - DA5F44BA25F07AA500F573EC /* ElectronicHorizonEdgeMetadata.swift in Sources */, + DA5F44BA25F07AA500F573EC /* RoadGraphEdgeMetadata.swift in Sources */, DA5F44E825F07D2800F573EC /* RoadObjectLocation.swift in Sources */, DABA591525E58D5600D0C1DB /* Accounts.swift in Sources */, C5C94C1C1DDCD2340097296A /* LegacyRouteController.swift in Sources */, @@ -2824,7 +2824,7 @@ DA5F44C825F07AB700F573EC /* MapboxStreetsRoadClass.swift in Sources */, C51DF8661F38C31C006C6A15 /* Locale.swift in Sources */, DA5F44F625F07D3B00F573EC /* RoadObjectsStore.swift in Sources */, - DA5F44B025F07A6800F573EC /* ElectronicHorizonEdge.swift in Sources */, + DA5F44B025F07A6800F573EC /* RoadGraphEdge.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/MapboxCoreNavigation/CoreConstants.swift b/Sources/MapboxCoreNavigation/CoreConstants.swift index 2f5a89e2a6..76408686e7 100644 --- a/Sources/MapboxCoreNavigation/CoreConstants.swift +++ b/Sources/MapboxCoreNavigation/CoreConstants.swift @@ -308,28 +308,28 @@ public extension Notification.Name { /** Posted when the user’s position in the electronic horizon changes. This notification may be posted multiple times after `electronicHorizonDidEnterRoadObject` until the user transitions to a new electronic horizon. - The user info dictionary contains the keys `ElectronicHorizonEdge.NotificationUserInfoKey.positionKey`, `ElectronicHorizonEdge.NotificationUserInfoKey.treeKey`, `ElectronicHorizonEdge.NotificationUserInfoKey.updatesMostProbablePathKey`, and `ElectronicHorizonEdge.NotificationUserInfoKey.distancesByRoadObjectKey`. + The user info dictionary contains the keys `RoadGraph.Edge.NotificationUserInfoKey.positionKey`, `RoadGraph.Edge.NotificationUserInfoKey.treeKey`, `RoadGraph.Edge.NotificationUserInfoKey.updatesMostProbablePathKey`, and `RoadGraph.Edge.NotificationUserInfoKey.distancesByRoadObjectKey`. */ static let electronicHorizonDidUpdatePosition: Notification.Name = .init(rawValue: "ElectronicHorizonDidUpdatePosition") /** Posted when the user enters a linear road object. - The user info dictionary contains the keys `ElectronicHorizonEdge.NotificationUserInfoKey.roadObjectIdentifierKey` and `ElectronicHorizonEdge.NotificationUserInfoKey.didTransitionAtEndpointKey`. + The user info dictionary contains the keys `RoadGraph.Edge.NotificationUserInfoKey.roadObjectIdentifierKey` and `RoadGraph.Edge.NotificationUserInfoKey.didTransitionAtEndpointKey`. */ static let electronicHorizonDidEnterRoadObject: Notification.Name = .init(rawValue: "ElectronicHorizonDidEnterRoadObject") /** Posted when the user exits a linear road object. - The user info dictionary contains the keys `ElectronicHorizonEdge.NotificationUserInfoKey.roadObjectIdentifierKey` and `ElectronicHorizonEdge.NotificationUserInfoKey.transitionKey`. + The user info dictionary contains the keys `RoadGraph.Edge.NotificationUserInfoKey.roadObjectIdentifierKey` and `RoadGraph.Edge.NotificationUserInfoKey.transitionKey`. */ static let electronicHorizonDidExitRoadObject: Notification.Name = .init(rawValue: "ElectronicHorizonDidExitRoadObject") } -extension ElectronicHorizonEdge { +extension RoadGraph { /** - Keys in the user info dictionaries of various notifications posted by instances of `RouteController` or `PassiveLocationDataSource` about `ElectronicHorizonEdge`s. + Keys in the user info dictionaries of various notifications posted by instances of `RouteController` or `PassiveLocationDataSource` about `RoadGraph.Edge`s. */ public struct NotificationUserInfoKey: Hashable, Equatable, RawRepresentable { public typealias RawValue = String @@ -343,7 +343,7 @@ extension ElectronicHorizonEdge { public static let positionKey: NotificationUserInfoKey = .init(rawValue: "position") /** - A key in the user info dictionary of a `Notification.Name.electronicHorizonDidUpdatePosition` notification. The corresponding value is an `ElectronicHorizonEdge` at the root of a tree of edges in the routing graph. This graph represents a probable path (or paths) of a vehicle within the routing graph for a certain distance in front of the vehicle, thus extending the user’s perspective beyond the “visible” horizon as the vehicle’s position and trajectory change. + A key in the user info dictionary of a `Notification.Name.electronicHorizonDidUpdatePosition` notification. The corresponding value is an `RoadGraph.Edge` at the root of a tree of edges in the routing graph. This graph represents a probable path (or paths) of a vehicle within the routing graph for a certain distance in front of the vehicle, thus extending the user’s perspective beyond the “visible” horizon as the vehicle’s position and trajectory change. */ public static let treeKey: NotificationUserInfoKey = .init(rawValue: "tree") diff --git a/Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift b/Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift index 9e8ee40f2e..eff9e3bb0b 100644 --- a/Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift +++ b/Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift @@ -147,7 +147,7 @@ class Navigator { extension Navigator: ElectronicHorizonObserver { public func onPositionUpdated(for position: ElectronicHorizonPosition, distances: [String : MapboxNavigationNative.RoadObjectDistanceInfo]) { - let userInfo: [ElectronicHorizonEdge.NotificationUserInfoKey: Any] = [ + let userInfo: [RoadGraph.NotificationUserInfoKey: Any] = [ .positionKey: RoadGraph.Position(position.position()), .treeKey: try! position.tree(), .updatesMostProbablePathKey: position.type() == .UPDATE, @@ -157,7 +157,7 @@ extension Navigator: ElectronicHorizonObserver { } public func onRoadObjectEnter(for info: RoadObjectEnterExitInfo) { - let userInfo: [ElectronicHorizonEdge.NotificationUserInfoKey: Any] = [ + let userInfo: [RoadGraph.NotificationUserInfoKey: Any] = [ .roadObjectIdentifierKey: info.roadObjectId, .didTransitionAtEndpointKey: info.isEnterFromStartOrExitFromEnd, ] @@ -165,7 +165,7 @@ extension Navigator: ElectronicHorizonObserver { } public func onRoadObjectExit(for info: RoadObjectEnterExitInfo) { - let userInfo: [ElectronicHorizonEdge.NotificationUserInfoKey: Any] = [ + let userInfo: [RoadGraph.NotificationUserInfoKey: Any] = [ .roadObjectIdentifierKey: info.roadObjectId, .didTransitionAtEndpointKey: info.isEnterFromStartOrExitFromEnd, ] diff --git a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdge.swift b/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdge.swift deleted file mode 100644 index 4f7dc5ced9..0000000000 --- a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdge.swift +++ /dev/null @@ -1,47 +0,0 @@ -import Foundation -import MapboxNavigationNative - -/** - An electronic horizon is a probable path (or paths) of a vehicle. This structure contains metadata about an edge in a routing graph. For example, an edge may represent a road segment between two intersections or between the two ends of a bridge. An edge may traverse multiple road objects, and a road object may be associated with multiple edges. The road network ahead of the user is represented as a tree of edges. Each intersection has outlet edges. In turn, each edge has a probability of transition to another edge, as well as details about the road segment that the edge traverses. You can use these details to influence application behavior based on predicted upcoming conditions. - - During active turn-by-turn navigation, the user-selected route and its metadata influence the path of the electronic horizon determined by `RouteController`. During passive navigation (free-driving), no route is actively selected, so `PassiveLocationDataSource` will determine the most probable path from the vehicle’s current location. You can receive notifications about changes in the current state of the electronic horizon by observing the `Notification.Name.electronicHorizonDidUpdatePosition`, `Notification.Name.electronicHorizonDidEnterRoadObject`, and `Notification.Name.electronicHorizonDidExitRoadObject` notifications. - - Use a `RoadGraph` object to get an edge with a given identifier. - */ -public struct ElectronicHorizonEdge { - /** - Unique identifier of a directed edge. - - Use a `RoadGraph` object to get more information about the edge with a given identifier. - */ - public typealias Identifier = UInt - - /** Unique identifier of the directed edge. */ - public let identifier: Identifier - - /** - The level of the edge. - - A value of 0 indicates that the edge is part of the most probable path (MPP), a value of 1 indicates an edge that branches away from the MPP, and so on. - */ - public let level: UInt - - /** - The probability that the user will transition onto this edge, with 1 being certain and 0 being unlikely. - */ - public let probability: Double - - /** - The edges to which the user could transition from this edge. - - The most probable path may be split at some point if some of edges have a low probability difference (±0.05). For example, `outletEdges` can contain more than one edge with `level` set to 0. Currently, there is a maximum limit of one split per electronic horizon. - */ - public let outletEdges: [ElectronicHorizonEdge] - - init(_ native: MapboxNavigationNative.ElectronicHorizonEdge) { - self.identifier = UInt(native.id) - self.level = UInt(native.level) - self.probability = native.probability - self.outletEdges = native.out.map(ElectronicHorizonEdge.init) - } -} diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift index c0a935a4c5..c6c20edfe9 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift @@ -3,7 +3,7 @@ import Turf import MapboxNavigationNative /** - `RoadGraph` provides methods to get edge shape (e.g. `ElectronicHorizonEdge`) and metadata. + `RoadGraph` provides methods to get edge shape (e.g. `RoadGraph.Edge`) and metadata. You do not create a `RoadGraph` object manually. Instead, observe the `Notification.Name.electronicHorizonDidUpdatePosition` notification to obtain edge identifiers and get more details about the edges using the `RouteController.roadGraph` or `PassiveLocationDataSource.roadGraph` property. */ @@ -14,9 +14,9 @@ public final class RoadGraph { - returns: Metadata about the edge with the given edge identifier, or `nil` if the edge is inaccessible. */ - public func edgeMetadata(edgeIdentifier: ElectronicHorizonEdge.Identifier) -> ElectronicHorizonEdge.Metadata? { + public func edgeMetadata(edgeIdentifier: RoadGraph.Edge.Identifier) -> RoadGraph.Edge.Metadata? { if let edgeMetadata = native.getEdgeMetadata(forEdgeId: UInt64(edgeIdentifier)) { - return ElectronicHorizon.Edge.Metadata(edgeMetadata) + return RoadGraph.Edge.Metadata(edgeMetadata) } return nil } @@ -26,7 +26,7 @@ public final class RoadGraph { - returns: A line string corresponding to the given edge identifier, or `nil` if the edge is inaccessible. */ - public func edgeShape(edgeIdentifier: ElectronicHorizonEdge.Identifier) -> LineString? { + public func edgeShape(edgeIdentifier: RoadGraph.Edge.Identifier) -> LineString? { guard let locations = native.getEdgeShape(forEdgeId: UInt64(edgeIdentifier)) else { return nil } diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdge.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdge.swift new file mode 100644 index 0000000000..c744b9fc96 --- /dev/null +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdge.swift @@ -0,0 +1,52 @@ +import Foundation +import MapboxNavigationNative + +extension RoadGraph { + + /** + An edge in a routing graph. For example, an edge may represent a road segment between two intersections or between the two ends of a bridge. An edge may traverse multiple road objects, and a road object may be associated with multiple edges. + + An electronic horizon is a probable path (or paths) of a vehicle. The road network ahead of the user is represented as a tree of edges. Each intersection has outlet edges. In turn, each edge has a probability of transition to another edge, as well as details about the road segment that the edge traverses. You can use these details to influence application behavior based on predicted upcoming conditions. + + During active turn-by-turn navigation, the user-selected route and its metadata influence the path of the electronic horizon determined by `RouteController`. During passive navigation (free-driving), no route is actively selected, so `PassiveLocationDataSource` will determine the most probable path from the vehicle’s current location. You can receive notifications about changes in the current state of the electronic horizon by observing the `Notification.Name.electronicHorizonDidUpdatePosition`, `Notification.Name.electronicHorizonDidEnterRoadObject`, and `Notification.Name.electronicHorizonDidExitRoadObject` notifications. + + Use a `RoadGraph` object to get an edge with a given identifier. + */ + public struct Edge { + /** + Unique identifier of a directed edge. + + Use a `RoadGraph` object to get more information about the edge with a given identifier. + */ + public typealias Identifier = UInt + + /** Unique identifier of the directed edge. */ + public let identifier: Identifier + + /** + The level of the edge. + + A value of 0 indicates that the edge is part of the most probable path (MPP), a value of 1 indicates an edge that branches away from the MPP, and so on. + */ + public let level: UInt + + /** + The probability that the user will transition onto this edge, with 1 being certain and 0 being unlikely. + */ + public let probability: Double + + /** + The edges to which the user could transition from this edge. + + The most probable path may be split at some point if some of edges have a low probability difference (±0.05). For example, `outletEdges` can contain more than one edge with `level` set to 0. Currently, there is a maximum limit of one split per electronic horizon. + */ + public let outletEdges: [RoadGraph.Edge] + + init(_ native: ElectronicHorizonEdge) { + self.identifier = UInt(native.id) + self.level = UInt(native.level) + self.probability = native.probability + self.outletEdges = native.out.map(RoadGraph.Edge.init) + } + } +} diff --git a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdgeMetadata.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdgeMetadata.swift similarity index 99% rename from Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdgeMetadata.swift rename to Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdgeMetadata.swift index 3bccd59ebc..bbe25d7dde 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/ElectronicHorizonEdgeMetadata.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdgeMetadata.swift @@ -3,7 +3,7 @@ import CoreLocation import MapboxDirections import MapboxNavigationNative -extension ElectronicHorizonEdge { +extension RoadGraph.Edge { /** Indicates how many directions the user may travel along an edge. */ diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift index 6f610226bb..b7795432b7 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift @@ -7,7 +7,7 @@ extension RoadGraph { /** A position along a linear object in the road graph. */ public struct Path { /** The edge identifiers that fully or partially coincide with the linear object. */ - public let edgeIdentifiers: [ElectronicHorizonEdge.Identifier] + public let edgeIdentifiers: [RoadGraph.Edge.Identifier] /** The distance from the start of an edge to the start of the linear object as a fraction of the edge’s length from 0 to 1. */ public let fractionFromStart: Double diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift index 7346e7715c..03e555c654 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift @@ -7,7 +7,7 @@ extension RoadGraph { public struct Position { /** The edge identifier along which the point object lies. */ - public let edgeIdentifier: ElectronicHorizonEdge.Identifier + public let edgeIdentifier: RoadGraph.Edge.Identifier /** The distance from the start of an edge to the point object as a fraction of the edge’s length from 0 to 1. */ public let fractionFromStart: Double diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadObjectsStore.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadObjectsStore.swift index 5ab3ff298c..0ee267b5d4 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadObjectsStore.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadObjectsStore.swift @@ -4,7 +4,7 @@ import MapboxNavigationNative /** Identifies a road object in an electronic horizon. A road object represents a notable transition point along a road, such as a toll booth or tunnel entrance. A road object is similar to a `RouteAlert` but is more closely associated with the routing graph managed by the `RoadGraph` class. - Use a `RoadObjectsStore` object to get more information about a road object with a given identifier or get the locations of road objects along `ElectronicHorizonEdge`s. + Use a `RoadObjectsStore` object to get more information about a road object with a given identifier or get the locations of road objects along `RoadGraph.Edge`s. */ public typealias RoadObjectIdentifier = String @@ -30,8 +30,8 @@ public final class RoadObjectsStore { which are lying on the edge with given identifier. - parameter edgeIdentifier: The identifier of the edge to query. */ + public func roadObjectEdgeLocations(edgeIdentifier: RoadGraph.Edge.Identifier) -> [RoadObjectIdentifier : RoadObjectEdgeLocation] { let objects = native.getForEdgeId(UInt64(edgeIdentifier)) - public func roadObjectEdgeLocations(edgeIdentifier: ElectronicHorizonEdge.Identifier) -> [RoadObjectIdentifier : RoadObjectEdgeLocation] { return objects.mapValues(RoadObjectEdgeLocation.init) } @@ -65,7 +65,7 @@ public final class RoadObjectsStore { Returns list of road object ids which are (partially) belong to `edgeIds`. - parameter edgeIds list of edge ids */ - public func roadObjectIdentifiers(edgeIdentifiers: [ElectronicHorizonEdge.Identifier]) -> [RoadObjectIdentifier] { + public func roadObjectIdentifiers(edgeIdentifiers: [RoadGraph.Edge.Identifier]) -> [RoadObjectIdentifier] { return native.getRoadObjectIdsByEdgeIds(forEdgeIds: edgeIdentifiers.map(NSNumber.init)) } From 7ac85dc505d47ad250575c8807eed1b4e069b3c7 Mon Sep 17 00:00:00 2001 From: Alex Azarov Date: Wed, 28 Apr 2021 17:53:11 +0300 Subject: [PATCH 3/3] Refactor RoadGraph.Edge usage --- Example/ViewController+FreeDrive.swift | 12 ++++++------ Sources/MapboxCoreNavigation/CoreConstants.swift | 8 ++++---- .../MapboxCoreNavigation/EHorizon/RoadGraph.swift | 6 +++--- .../EHorizon/RoadGraphEdge.swift | 4 ++-- .../EHorizon/RoadGraphPath.swift | 2 +- .../EHorizon/RoadGraphPosition.swift | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Example/ViewController+FreeDrive.swift b/Example/ViewController+FreeDrive.swift index 59367b9350..45bb9c4b16 100644 --- a/Example/ViewController+FreeDrive.swift +++ b/Example/ViewController+FreeDrive.swift @@ -97,17 +97,17 @@ extension ViewController { } @objc func didUpdateElectronicHorizonPosition(_ notification: Notification) { - guard let horizon = notification.userInfo?[RoadGraph.NotificationUserInfoKey.treeKey] as? RoadGraph.Edge else { + guard let startingEdge = notification.userInfo?[RoadGraph.NotificationUserInfoKey.treeKey] as? RoadGraph.Edge else { return } // Avoid repeating edges that have already been printed out. - guard currentEdgeIdentifier != horizon.identifier || - nextEdgeIdentifier != horizon.outletEdges.first?.identifier else { + guard currentEdgeIdentifier != startingEdge.identifier || + nextEdgeIdentifier != startingEdge.outletEdges.first?.identifier else { return } - currentEdgeIdentifier = horizon.identifier - nextEdgeIdentifier = horizon.outletEdges.first?.identifier + currentEdgeIdentifier = startingEdge.identifier + nextEdgeIdentifier = startingEdge.outletEdges.first?.identifier guard let currentEdgeIdentifier = currentEdgeIdentifier, let nextEdgeIdentifier = nextEdgeIdentifier else { return @@ -117,7 +117,7 @@ extension ViewController { var statusString = "Currently on \(edgeNames(identifier: currentEdgeIdentifier).joined(separator: " / ")), approaching \(edgeNames(identifier: nextEdgeIdentifier).joined(separator: " / "))" // If there is an upcoming intersection, include the names of the cross streets. - let branchEdgeIdentifiers = horizon.outletEdges.suffix(from: 1).map({ $0.identifier }) + let branchEdgeIdentifiers = startingEdge.outletEdges.suffix(from: 1).map({ $0.identifier }) if !branchEdgeIdentifiers.isEmpty { let branchNames = branchEdgeIdentifiers.flatMap { edgeNames(identifier: $0) } statusString += " at \(branchNames.joined(separator: ", "))" diff --git a/Sources/MapboxCoreNavigation/CoreConstants.swift b/Sources/MapboxCoreNavigation/CoreConstants.swift index 76408686e7..8d34e5d49c 100644 --- a/Sources/MapboxCoreNavigation/CoreConstants.swift +++ b/Sources/MapboxCoreNavigation/CoreConstants.swift @@ -308,28 +308,28 @@ public extension Notification.Name { /** Posted when the user’s position in the electronic horizon changes. This notification may be posted multiple times after `electronicHorizonDidEnterRoadObject` until the user transitions to a new electronic horizon. - The user info dictionary contains the keys `RoadGraph.Edge.NotificationUserInfoKey.positionKey`, `RoadGraph.Edge.NotificationUserInfoKey.treeKey`, `RoadGraph.Edge.NotificationUserInfoKey.updatesMostProbablePathKey`, and `RoadGraph.Edge.NotificationUserInfoKey.distancesByRoadObjectKey`. + The user info dictionary contains the keys `RoadGraph.NotificationUserInfoKey.positionKey`, `RoadGraph.NotificationUserInfoKey.treeKey`, `RoadGraph.NotificationUserInfoKey.updatesMostProbablePathKey`, and `RoadGraph.NotificationUserInfoKey.distancesByRoadObjectKey`. */ static let electronicHorizonDidUpdatePosition: Notification.Name = .init(rawValue: "ElectronicHorizonDidUpdatePosition") /** Posted when the user enters a linear road object. - The user info dictionary contains the keys `RoadGraph.Edge.NotificationUserInfoKey.roadObjectIdentifierKey` and `RoadGraph.Edge.NotificationUserInfoKey.didTransitionAtEndpointKey`. + The user info dictionary contains the keys `RoadGraph.NotificationUserInfoKey.roadObjectIdentifierKey` and `RoadGraph.NotificationUserInfoKey.didTransitionAtEndpointKey`. */ static let electronicHorizonDidEnterRoadObject: Notification.Name = .init(rawValue: "ElectronicHorizonDidEnterRoadObject") /** Posted when the user exits a linear road object. - The user info dictionary contains the keys `RoadGraph.Edge.NotificationUserInfoKey.roadObjectIdentifierKey` and `RoadGraph.Edge.NotificationUserInfoKey.transitionKey`. + The user info dictionary contains the keys `RoadGraph.NotificationUserInfoKey.roadObjectIdentifierKey` and `RoadGraph.NotificationUserInfoKey.transitionKey`. */ static let electronicHorizonDidExitRoadObject: Notification.Name = .init(rawValue: "ElectronicHorizonDidExitRoadObject") } extension RoadGraph { /** - Keys in the user info dictionaries of various notifications posted by instances of `RouteController` or `PassiveLocationDataSource` about `RoadGraph.Edge`s. + Keys in the user info dictionaries of various notifications posted by instances of `RouteController` or `PassiveLocationDataSource` about `RoadGraph`s. */ public struct NotificationUserInfoKey: Hashable, Equatable, RawRepresentable { public typealias RawValue = String diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift index c6c20edfe9..db6f81a102 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraph.swift @@ -14,9 +14,9 @@ public final class RoadGraph { - returns: Metadata about the edge with the given edge identifier, or `nil` if the edge is inaccessible. */ - public func edgeMetadata(edgeIdentifier: RoadGraph.Edge.Identifier) -> RoadGraph.Edge.Metadata? { + public func edgeMetadata(edgeIdentifier: Edge.Identifier) -> Edge.Metadata? { if let edgeMetadata = native.getEdgeMetadata(forEdgeId: UInt64(edgeIdentifier)) { - return RoadGraph.Edge.Metadata(edgeMetadata) + return Edge.Metadata(edgeMetadata) } return nil } @@ -26,7 +26,7 @@ public final class RoadGraph { - returns: A line string corresponding to the given edge identifier, or `nil` if the edge is inaccessible. */ - public func edgeShape(edgeIdentifier: RoadGraph.Edge.Identifier) -> LineString? { + public func edgeShape(edgeIdentifier: Edge.Identifier) -> LineString? { guard let locations = native.getEdgeShape(forEdgeId: UInt64(edgeIdentifier)) else { return nil } diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdge.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdge.swift index c744b9fc96..7c8f27aa78 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdge.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphEdge.swift @@ -40,13 +40,13 @@ extension RoadGraph { The most probable path may be split at some point if some of edges have a low probability difference (±0.05). For example, `outletEdges` can contain more than one edge with `level` set to 0. Currently, there is a maximum limit of one split per electronic horizon. */ - public let outletEdges: [RoadGraph.Edge] + public let outletEdges: [Edge] init(_ native: ElectronicHorizonEdge) { self.identifier = UInt(native.id) self.level = UInt(native.level) self.probability = native.probability - self.outletEdges = native.out.map(RoadGraph.Edge.init) + self.outletEdges = native.out.map(Edge.init) } } } diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift index b7795432b7..6b768815b3 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPath.swift @@ -7,7 +7,7 @@ extension RoadGraph { /** A position along a linear object in the road graph. */ public struct Path { /** The edge identifiers that fully or partially coincide with the linear object. */ - public let edgeIdentifiers: [RoadGraph.Edge.Identifier] + public let edgeIdentifiers: [Edge.Identifier] /** The distance from the start of an edge to the start of the linear object as a fraction of the edge’s length from 0 to 1. */ public let fractionFromStart: Double diff --git a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift index 03e555c654..d1bce0a98d 100644 --- a/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift +++ b/Sources/MapboxCoreNavigation/EHorizon/RoadGraphPosition.swift @@ -7,7 +7,7 @@ extension RoadGraph { public struct Position { /** The edge identifier along which the point object lies. */ - public let edgeIdentifier: RoadGraph.Edge.Identifier + public let edgeIdentifier: Edge.Identifier /** The distance from the start of an edge to the point object as a fraction of the edge’s length from 0 to 1. */ public let fractionFromStart: Double