-
Notifications
You must be signed in to change notification settings - Fork 315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable night style when inside tunnel #1127
Conversation
…ble dark mode upon entrance and reset to default style mode upon exit.
… lie within the tunnel route.
…ted by styleManager's styles property.
@@ -635,6 +646,10 @@ extension RouteController: CLLocationManagerDelegate { | |||
updateRouteStepProgress(for: location) | |||
updateRouteLegProgress(for: location) | |||
|
|||
if routeProgress.currentLegProgress.currentStep.containsTunnel { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this if into detectRouteStepInTunnel(for:)
and return early if it's true.
// - Current location to exit must be greater than zero meters. | ||
// - Distance to tunnel entrance must be less than tunnel distance. | ||
// - Distance to tunnel exit must also be less than tunnel distance. | ||
if (tunnelDistance - distanceToExit) > 0 && distanceToEntrance <= tunnelDistance && distanceToExit <= tunnelDistance { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it's possible to have only 2 conditions here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bsudekum Yes indeed. Good looks 👍
MapboxCoreNavigation/RouteStep.swift
Outdated
/** | ||
Returns the entry and exit intersections of the tunnel on the current route step | ||
*/ | ||
var tunnelIntersection: (entry: Intersection, exit: Intersection)? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tunnelIntersection
denotes a single intersection, while in reality, we're calculating the entry and exit of a tunnel here. Could you come up with a more descriptive variable name for this variable?
@@ -561,6 +561,14 @@ extension NavigationViewController: RouteControllerDelegate { | |||
} | |||
return advancesToNextLeg | |||
} | |||
|
|||
@objc public func routeController(_ routeController: RouteController, didEnterTunnelAt location: CLLocation?) { | |||
if let _ = location { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact we're not using location
here might clue us in that it may not be necessary to send this param over.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
MapboxCoreNavigation/RouteStep.swift
Outdated
*/ | ||
var tunnelDistance: CLLocationDistance? { | ||
guard let tunnelIntersection = tunnelIntersection else { return nil } | ||
return tunnelIntersection.entry.location.distance(to: tunnelIntersection.exit.location) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This distance calculation is an absolute point to point distance. Instead, we should be using a function which calculates distance along a line. I believe Polyline
is a struct and contains a distance variable. It may be possible to remove this and just use tunnelSlice.distance
.
MapboxCoreNavigation/RouteStep.swift
Outdated
guard let intersections = intersections, containsTunnel else { return nil } | ||
for i in 0..<(intersections.count) where intersections.count > 1 { | ||
if intersections[i].outletRoadClasses == .tunnel { | ||
return (entry: intersections[i], exit: intersections[i+1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double check that i + 1 is always within bounds before returning here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line #77
already does that check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't line 77 only checking where the number of intersections is greater that 1? Not necessarily that the current index in the loop has a follow on index.
|
||
@objc public func routeController(_ routeController: RouteController, didEnterTunnelAt location: CLLocation?) { | ||
if let _ = location { | ||
self.styleManager.applyStyle(NightStyle()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we could first check if the style needs to be updated before continually updating the style on every location update?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bsudekum I do a safety check before I apply the style in applyStyle(_:)
on line #111
.
MapboxNavigation/StyleManager.swift
Outdated
@@ -96,7 +96,7 @@ open class StyleManager: NSObject { | |||
resetTimeOfDayTimer() | |||
} | |||
|
|||
func applyStyle() { | |||
func applyStyle(_ newStyle: Style? = nil) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to avoid the special case for custom style below if we’d take a StyleType
instead of a specific style here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frederoni you're right 👍
…igation-ios into tunnel/dark_mode_style
@bsudekum and @frederoni Thanks for your feedback 👍 |
@@ -561,6 +561,14 @@ extension NavigationViewController: RouteControllerDelegate { | |||
} | |||
return advancesToNextLeg | |||
} | |||
|
|||
@objc public func didEnterTunnel(_ darkModeEnabled: Bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
darkModeEnabled
makes it seem like it was already enabled.
@@ -96,6 +96,21 @@ open class StyleManager: NSObject { | |||
resetTimeOfDayTimer() | |||
} | |||
|
|||
func applyStyle(type styleType: StyleType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this func be combined with the applyStyle
below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I considered it. However, this func applyStyle(type:)
is cleaner, since it requires the styleType
. The other func applyStyle
scope is getting a bit bigger and complex with more conditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UPDATES:
I also refactored applyStyle
so that we have a function applyStyle(type:)
to contain styleType
related logic.
- parameter darkModeEnabled: The darkModeEnabled flag determines whether a `DarkStyle` should apply. | ||
*/ | ||
@objc(didEnterTunnel:) | ||
optional func didEnterTunnel(_ darkModeEnabled: Bool) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should remove the notion of dark mode from RouteController
because MapboxCoreNavigation deals with non-UI related functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. Will do.
// Pre-conditions: | ||
// - Current location to exit must be greater than zero meters. | ||
// - Distance to tunnel entrance must be less than tunnel distance. | ||
if (tunnelDistance - distanceToExit) > 0 && distanceToEntrance <= tunnelDistance { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would something like
if distanceToEntrance <= tunnelDistance && distanceToExit <= tunnelDistance {
...
I only suggest this since it's easier to understand what we're comparing on each side of the && operator.
let distanceToEntrance = currentLocation.distance(to: tunnelStartCoordinate) | ||
let distanceToExit = currentLocation.distance(to: tunnelEndCoordinate) | ||
|
||
// Capute any location which lies within the tunnel route. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: no need for route
in tunnel route
. Also, Capute
-> Compute
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
capture
-- misspelt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great – thanks for managing this deluge of feedback and iterating on the approach. 😄 Since this has been a pretty long review, here are a few outstanding pieces of feedback to consider before merging:
@@ -417,21 +417,10 @@ open class RouteStepProgress: NSObject { | |||
} | |||
|
|||
/** | |||
Returns all the intersection distances on the current step. | |||
Returns an array of the calculated distances from the current intersection to the next intersection on the current step. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this is a property, not a method, so it is set to the array rather than returning the array.
/** | ||
A Boolean value that determines whether the dark style should be automatically activated when a route controller enters a tunnel. | ||
*/ | ||
@objc public var automaticallySwitchStyleForTunnels: Bool = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: use the declarative form instead of the imperative form when naming a property. In Objective-C, a property’s getter can look identical to an action method:
// Does this line immediately switch the style?
[navigationViewController automaticallySwitchStyleForTunnels];
A clearer name would be automaticallySwitchesStyleInsideTunnels
or usesNightStyleInsideTunnels
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, I prefer to use enableNightStyleInsideTunnelFeatureEnabled
to hint that variable is a feature flag. Just my 2¢
.
@@ -388,21 +388,39 @@ open class RouteStepProgress: NSObject { | |||
/** | |||
The next intersection the user will travel through. | |||
|
|||
The step must contains `Intersections` for this value not be `nil`. | |||
The step must contain `intersectionsIncludingUpcomingManeuverIntersection` for this value not be `nil`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still unclear, because intersectionsIncludingUpcomingManeuverIntersection
is a property of RouteStepProgress, not RouteStep.
If
intersectionsIncludingUpcomingManeuverIntersection
isnil
, this property is alsonil
.
MapboxNavigation/Constants.swift
Outdated
/** | ||
The minimum distance of a tunnel intersection on a given route step. | ||
*/ | ||
public var MBMinimumTunnelLengthForUsingNightStyle: CLLocationDistance = 100 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the intent was to address the feedback in #1127 (comment) by moving this constant, but I don’t see where it got moved to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@1ec5 we're not using this constant at the moment. The tunnel distance check will be done on my upcoming PR for simulation of the tunnel navigation.
…and upcoming intersections, along with their corresponding calculated distances.
…ersections bounds. Modified description text for current and upcoming intersections. Modified variable to indicate when night style should be enabled inside a tunnel.
…ersections bounds.
…ck on intersections bounds to initial state.
@@ -409,7 +409,7 @@ public class NavigationViewController: UIViewController { | |||
|
|||
mapViewController?.notifyDidChange(routeProgress: routeProgress, location: location, secondsRemaining: secondsRemaining) | |||
|
|||
if automaticallySwitchStyleForTunnels, | |||
if enableNightStyleInsideTunnelFeatureEnabled, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property has the word enable(d)
in it twice. I too am a fan of suggestion - automaticallySwitchesStyleInsideTunnels
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…ersections bounds.
@@ -628,6 +628,10 @@ extension RouteController: CLLocationManagerDelegate { | |||
let currentStepProgress = routeProgress.currentLegProgress.currentStepProgress | |||
let currentStep = currentStepProgress.step | |||
|
|||
let intersectionDistances = routeProgress.currentLegProgress.currentStepProgress.intersectionDistances |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the user has set NavigationViewController.automaticallyChangeStyleForTunnel
to false, is it necessary to perform these calculations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bsudekum FYI
- It shouldn't be restricted to automaticallyChangeStyleForTunnel. It should be wrapped within a isDeadReckoningEnabled flag.
- This calculation updates the
intersectionIndex
- fix for issue Intersection index is always 0 #1170. @1ec5 do you need to use this fix for a task unrelated to dead reckoning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vincethecoder I don't think this code should be intertwined with isDeadReckoningEnabled
. Let's keep these as separate ideas for now.
IMO, the fix here is to move NavigationViewController.automaticallyChangeStyleForTunnel
to RouteController
and rename it to something more appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, in #1127 (comment) I recommended keeping UI-related stuff out of Core Navigation. I stand by that recommendation.
…ck on intersections bounds to initial state.
…e route controller.
routeController.isDeadReckoningEnabled = true | ||
} else { | ||
styleManager.timeOfDayChanged() | ||
routeController.isDeadReckoningEnabled = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is isDeadReckoningEnabled
being mutated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to continue mark the intersection as a candidate for dead reckoning.
@@ -942,6 +948,12 @@ extension RouteController: CLLocationManagerDelegate { | |||
} else { | |||
routeProgress.currentLegProgress.stepIndex += 1 | |||
} | |||
|
|||
if isDeadReckoningEnabled, let coordinates = routeProgress.currentLegProgress.currentStep.coordinates, let intersections = routeProgress.currentLegProgress.currentStep.intersections { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If intersectionDistances
is only set when dead reckoning is enabled, then the documentation for that property should say so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code should not be influenced by dead reckoning. Remove if isDeadReckoningEnabled
from this check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already removed - post our discussion on slack 😺
… on night style in tunnels.
This detects tunnels on a
routeStep
and sets thestyle
toDayStyle
.cc @mapbox/navigation-ios
Issue addressed: #559, #1170
NOTE:
When calculating the
distance
to the tunnel entrance usingPolyline
'sdistance(from:to:)
, there was inconsistent results. This issue is similar to the reported issue here: mapbox/turf-swift#27In this case, the distance to the tunnel entrance reports lower values as it approaches the entrance. However, in the mid-way of the tunnel commute, it suddenly begins to jump to higher values (greater than the tunnel distance) and then reduces to lower values before it exits the tunnel. The screenshot below highlights these inconsistencies: