Skip to content

Commit 7acf938

Browse files
committed
Code cleanup and commenting.
1 parent 7f3363b commit 7acf938

File tree

4 files changed

+214
-189
lines changed

4 files changed

+214
-189
lines changed

MapboxNavigation.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@
397397
DAFA92071F01735000A7FB09 /* DistanceFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 351BEC0B1E5BCC72006FE110 /* DistanceFormatter.swift */; };
398398
F43EE329261F98DC0039D56F /* NavigationMapView+RoadAnnotations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43EE328261F98DC0039D56F /* NavigationMapView+RoadAnnotations.swift */; };
399399
F43EE32A261F98DC0039D56F /* NavigationMapView+RoadAnnotations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43EE328261F98DC0039D56F /* NavigationMapView+RoadAnnotations.swift */; };
400+
F488A0BE26261C4600A4CC8C /* NavigationMapView+IntersectionAnnotations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F488A0BD26261C4600A4CC8C /* NavigationMapView+IntersectionAnnotations.swift */; };
401+
F488A0C826261D8100A4CC8C /* ElectronicHorizon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F488A0C726261D8100A4CC8C /* ElectronicHorizon.swift */; };
400402
F4BF512E24EAD7A50066A49B /* FeedbackSubtypeCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4BF512D24EAD7A50066A49B /* FeedbackSubtypeCollectionViewCell.swift */; };
401403
F4C5A26F24EF1D16004ED0DD /* FeedbackSubtypeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4C5A26E24EF1D16004ED0DD /* FeedbackSubtypeViewController.swift */; };
402404
/* End PBXBuildFile section */
@@ -1024,6 +1026,8 @@
10241026
DAFEB36E2093A3E000A86A83 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = "<group>"; };
10251027
DAFEB36F2093A3EF00A86A83 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ko; path = Resources/ko.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
10261028
F43EE328261F98DC0039D56F /* NavigationMapView+RoadAnnotations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NavigationMapView+RoadAnnotations.swift"; sourceTree = "<group>"; };
1029+
F488A0BD26261C4600A4CC8C /* NavigationMapView+IntersectionAnnotations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NavigationMapView+IntersectionAnnotations.swift"; sourceTree = "<group>"; };
1030+
F488A0C726261D8100A4CC8C /* ElectronicHorizon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElectronicHorizon.swift; sourceTree = "<group>"; };
10271031
F4BF512D24EAD7A50066A49B /* FeedbackSubtypeCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbackSubtypeCollectionViewCell.swift; sourceTree = "<group>"; };
10281032
F4C5A26E24EF1D16004ED0DD /* FeedbackSubtypeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbackSubtypeViewController.swift; sourceTree = "<group>"; };
10291033
/* End PBXFileReference section */
@@ -1662,6 +1666,8 @@
16621666
8AE9081125FAA53300F37077 /* Collection.swift */,
16631667
8A8C3D97260175D20071D274 /* CLLocationDirection.swift */,
16641668
8A446644260A7B24008BA55E /* BoundingBox.swift */,
1669+
F488A0BD26261C4600A4CC8C /* NavigationMapView+IntersectionAnnotations.swift */,
1670+
F488A0C726261D8100A4CC8C /* ElectronicHorizon.swift */,
16651671
);
16661672
name = Extensions;
16671673
sourceTree = "<group>";
@@ -2559,6 +2565,7 @@
25592565
8DEDEF3421E3FBE80049E114 /* NavigationViewControllerDelegate.swift in Sources */,
25602566
8A446645260A7B24008BA55E /* BoundingBox.swift in Sources */,
25612567
8AD866F625CA1BF10019A638 /* NavigationCamera.swift in Sources */,
2568+
F488A0C826261D8100A4CC8C /* ElectronicHorizon.swift in Sources */,
25622569
8D5DFFF1207C04840093765A /* NSAttributedString.swift in Sources */,
25632570
35CF34B11F0A733200C2692E /* UIFont.swift in Sources */,
25642571
8AD866F925CA1BF10019A638 /* ViewportDataSource.swift in Sources */,
@@ -2583,6 +2590,7 @@
25832590
160D8279205996DA00D278D6 /* DataCache.swift in Sources */,
25842591
8AFF437125F847340053CBB1 /* CameraOptions.swift in Sources */,
25852592
351BEBF21E5BCC63006FE110 /* Style.swift in Sources */,
2593+
F488A0BE26261C4600A4CC8C /* NavigationMapView+IntersectionAnnotations.swift in Sources */,
25862594
43FB386923A202420064481E /* Route.swift in Sources */,
25872595
3EA937B1F4DF73EB004BA6BE /* InstructionPresenter.swift in Sources */,
25882596
5A1C075824BDEB44000A6330 /* PassiveLocationManager.swift in Sources */,
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import MapboxCoreNavigation
2+
3+
extension ElectronicHorizon.Edge {
4+
var mpp: [ElectronicHorizon.Edge]? {
5+
6+
guard level == 0 else { return nil }
7+
8+
var mostProbablePath = [self]
9+
10+
for child in outletEdges {
11+
if let childMPP = child.mpp {
12+
mostProbablePath.append(contentsOf: childMPP)
13+
}
14+
}
15+
16+
return mostProbablePath
17+
}
18+
19+
func edgeNames(roadGraph: RoadGraph) -> [String] {
20+
guard let metadata = roadGraph.edgeMetadata(edgeIdentifier: identifier) else {
21+
return []
22+
}
23+
let names = metadata.names.map { name -> String in
24+
switch name {
25+
case .name(let name):
26+
return name
27+
case .code(let code):
28+
return "(\(code))"
29+
}
30+
}
31+
32+
// If the road is unnamed, fall back to the road class.
33+
if names.isEmpty {
34+
return ["\(metadata.mapboxStreetsRoadClass.rawValue)"]
35+
}
36+
return names
37+
}
38+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import CoreLocation
2+
import UIKit
3+
import MapboxDirections
4+
import MapboxCoreNavigation
5+
import Turf
6+
import MapboxMaps
7+
8+
extension NavigationMapView {
9+
10+
struct EdgeIntersection {
11+
var root: ElectronicHorizon.Edge
12+
var branch: ElectronicHorizon.Edge
13+
var rootMetadata: ElectronicHorizon.Edge.Metadata
14+
var rootShape: LineString
15+
var branchMetadata: ElectronicHorizon.Edge.Metadata
16+
var branchShape: LineString
17+
18+
var coordinate: CLLocationCoordinate2D? {
19+
rootShape.coordinates.first
20+
}
21+
22+
var annotationPoint: CLLocationCoordinate2D? {
23+
guard let length = branchShape.distance() else { return nil }
24+
let targetDistance = min(length / 2, Double.random(in: 15...30))
25+
guard let annotationPoint = branchShape.coordinateFromStart(distance: targetDistance) else { return nil }
26+
return annotationPoint
27+
}
28+
29+
var wayName: String? {
30+
guard let roadName = rootMetadata.names.first else { return nil }
31+
32+
switch roadName {
33+
case .name(let name):
34+
return name
35+
case .code(let code):
36+
return "(\(code))"
37+
}
38+
}
39+
var intersectingWayName: String? {
40+
guard let roadName = branchMetadata.names.first else { return nil }
41+
42+
switch roadName {
43+
case .name(let name):
44+
return name
45+
case .code(let code):
46+
return "(\(code))"
47+
}
48+
}
49+
50+
var incidentAngle: CLLocationDegrees {
51+
return (branchMetadata.heading - rootMetadata.heading).wrap(min: 0, max: 360)
52+
}
53+
54+
var description: String {
55+
return "EdgeIntersection: root: \(wayName ?? "") intersection: \(intersectingWayName ?? "") coordinate: \(String(describing: coordinate))"
56+
}
57+
}
58+
59+
enum AnnotationTailPosition: Int {
60+
case left
61+
case right
62+
case center
63+
}
64+
65+
class AnnotationCacheEntry: Equatable, Hashable {
66+
var wayname: String
67+
var coordinate: CLLocationCoordinate2D
68+
var intersection: EdgeIntersection?
69+
var feature: Feature
70+
var lastAccessTime: Date
71+
72+
init(coordinate: CLLocationCoordinate2D, wayname: String, intersection: EdgeIntersection? = nil, feature: Feature) {
73+
self.wayname = wayname
74+
self.coordinate = coordinate
75+
self.intersection = intersection
76+
self.feature = feature
77+
self.lastAccessTime = Date()
78+
}
79+
80+
static func == (lhs: AnnotationCacheEntry, rhs: AnnotationCacheEntry) -> Bool {
81+
return lhs.wayname == rhs.wayname
82+
}
83+
84+
func hash(into hasher: inout Hasher) {
85+
hasher.combine(wayname.hashValue)
86+
}
87+
}
88+
89+
class AnnotationCache {
90+
private let maxEntryAge = TimeInterval(30)
91+
var entries = Set<AnnotationCacheEntry>()
92+
var cachePruningTimer: Timer?
93+
94+
init() {
95+
// periodically prune the cache to remove entries that have been passed already
96+
cachePruningTimer = Timer.scheduledTimer(withTimeInterval: 15, repeats: true, block: { [weak self] _ in
97+
self?.prune()
98+
})
99+
}
100+
101+
deinit {
102+
cachePruningTimer?.invalidate()
103+
cachePruningTimer = nil
104+
}
105+
106+
func setValue(feature: Feature, coordinate: CLLocationCoordinate2D, intersection: EdgeIntersection?, for wayname: String) {
107+
entries.insert(AnnotationCacheEntry(coordinate: coordinate, wayname: wayname, intersection: intersection, feature: feature))
108+
}
109+
110+
func value(for wayname: String) -> AnnotationCacheEntry? {
111+
let matchingEntry = entries.first { entry -> Bool in
112+
entry.wayname == wayname
113+
}
114+
115+
if let matchingEntry = matchingEntry {
116+
// update the timestamp used for pruning the cache
117+
matchingEntry.lastAccessTime = Date()
118+
}
119+
120+
return matchingEntry
121+
}
122+
123+
private func prune() {
124+
let now = Date()
125+
126+
entries.filter { now.timeIntervalSince($0.lastAccessTime) > maxEntryAge }.forEach { remove($0) }
127+
}
128+
129+
public func remove(_ entry: AnnotationCacheEntry) {
130+
entries.remove(entry)
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)