Skip to content

Commit

Permalink
Merge pull request #1127 from mapbox/tunnel/dark_mode_style
Browse files Browse the repository at this point in the history
Enable night style when inside tunnel
  • Loading branch information
vincethecoder committed Mar 13, 2018
2 parents 6624000 + 9c878c3 commit 2acbe46
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,15 @@
* Exposes `setOverheadCameraView(from:along:for:)` which is useful for fitting the camera to an overhead view for the remaining route coordinates.
* Changed the heuristics needed for a the users location to unsnap from the route line. [#1110](https://github.com/mapbox/mapbox-navigation-ios/pull/1122)
* Changes `routeController(:didDiscardLocation:)` to `routeController(:shouldDiscardLocation:)`. Now if implemented, developers can choose to keep a location when RouteController deems a location unqualified. [#1095](https://github.com/mapbox/mapbox-navigation-ios/pull/1095/)
* Exposes `RouteStepProgress.intersectionDistances` of each step which can be used to determine the distance between `RouteStepProgress.currentIntersection` and `RouteStepProgress.upcomingIntersection` for unique use cases such as detecting tunnels, tolls, motorway etc. of a given route. [#1127](https://github.com/mapbox/mapbox-navigation-ios/pull/1127)

## User Interface

* Added a `NavigationMapView.localizeLabels()` method that should be called within `MGLMapViewDelegate.mapView(_:didFinishLoading:)` for standalone `NavigationMapView`s to ensure that map labels are in the correct language. [#1111](https://github.com/mapbox/mapbox-navigation-ios/pull/1122)
* The `/` delimiter is longer shown when a shield is shown on either side of the delimiter. This also removes the dependency SDWebImage. [#1046](https://github.com/mapbox/mapbox-navigation-ios/pull/1046)
* Exposes constants used for styling the route line. [#1124](https://github.com/mapbox/mapbox-navigation-ios/pull/1124/)
* Exposes `update(for:)` on `InstructionBannerView`. This is helpful for developers creating a custom user interface. [#1085](https://github.com/mapbox/mapbox-navigation-ios/pull/1085/)
* Updates to set current `NavigationViewController.styleManager.applyStyle(type:)` to `.nightStyle` when the current step intersection contains a tunnel. Also, we reset the step style when we advance to the next intersection and the upcoming intersection doesn't contain a tunnel. [#1127](https://github.com/mapbox/mapbox-navigation-ios/pull/1127)

## Voice Guidance

Expand Down
20 changes: 19 additions & 1 deletion MapboxCoreNavigation/RouteController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public protocol RouteControllerDelegate: class {
optional func routeController(_ routeController: RouteController, willRerouteFrom location: CLLocation)

/**
Called when a location has been idenetified as unqualified to navigate on.
Called when a location has been identified as unqualified to navigate on.
See `CLLocation.isQualified` for more information about what qualifies a location.
Expand Down Expand Up @@ -554,6 +554,8 @@ extension RouteController: CLLocationManagerDelegate {
let currentStepProgress = routeProgress.currentLegProgress.currentStepProgress
let currentStep = currentStepProgress.step

updateIntersectionIndex(for: currentStepProgress)

// Notify observers if the step’s remaining distance has changed.
if let closestCoordinate = polyline.closestCoordinate(to: location.coordinate) {
let remainingDistance = polyline.distance(from: closestCoordinate.coordinate)
Expand Down Expand Up @@ -586,6 +588,12 @@ extension RouteController: CLLocationManagerDelegate {
checkForFasterRoute(from: location)
}

func updateIntersectionIndex(for currentStepProgress: RouteStepProgress) {
let intersectionDistances = currentStepProgress.intersectionDistances
let upcomingIntersectionIndex = intersectionDistances.index { $0 > currentStepProgress.distanceTraveled } ?? intersectionDistances.endIndex
currentStepProgress.intersectionIndex = upcomingIntersectionIndex > 0 ? intersectionDistances.index(before: upcomingIntersectionIndex) : 0
}

func updateRouteLegProgress(for location: CLLocation) {
let currentDestination = routeProgress.currentLeg.destination
let legDurationRemaining = routeProgress.currentLegProgress.durationRemaining
Expand Down Expand Up @@ -868,6 +876,16 @@ extension RouteController: CLLocationManagerDelegate {
} else {
routeProgress.currentLegProgress.stepIndex += 1
}

updateIntersectionDistances()
}

func updateIntersectionDistances() {
if let coordinates = routeProgress.currentLegProgress.currentStep.coordinates, let intersections = routeProgress.currentLegProgress.currentStep.intersections {
let polyline = Polyline(coordinates)
let distances = intersections.map { polyline.distance(from: coordinates.first, to: $0.location) }
routeProgress.currentLegProgress.currentStepProgress.intersectionDistances = distances
}
}
}

Expand Down
24 changes: 21 additions & 3 deletions MapboxCoreNavigation/RouteProgress.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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` otherwise this property will be `nil`.
*/
@objc public var upcomingIntersection: Intersection? {
guard let intersections = intersectionsIncludingUpcomingManeuverIntersection, intersectionIndex + 1 < intersections.endIndex else {
guard let intersections = intersectionsIncludingUpcomingManeuverIntersection, intersections.startIndex..<intersections.endIndex-1 ~= intersectionIndex else {
return nil
}

return intersections[intersectionIndex]
return intersections[intersections.index(after: intersectionIndex)]
}

/**
Index representing the current intersection.
*/
@objc public var intersectionIndex: Int = 0

/**
The current intersection the user will travel through.
The step must contain `intersectionsIncludingUpcomingManeuverIntersection` otherwise this property will be `nil`.
*/
@objc public var currentIntersection: Intersection? {
guard let intersections = intersectionsIncludingUpcomingManeuverIntersection, intersections.startIndex..<intersections.endIndex ~= intersectionIndex else {
return nil
}

return intersections[intersectionIndex]
}

/**
Returns an array of the calculated distances from the current intersection to the next intersection on the current step.
*/
@objc public var intersectionDistances = [CLLocationDistance]()

/**
The distance in meters the user is to the next intersection they will pass through.
*/
Expand Down
14 changes: 14 additions & 0 deletions MapboxNavigation/NavigationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ public class NavigationViewController: UIViewController {
*/
@objc public var annotatesSpokenInstructions = false

/**
A Boolean value that indicates whether the dark style should apply when a route controller enters a tunnel.
*/
@objc public var usesNightStyleInsideTunnels: Bool = false

let progressBar = ProgressBar()
var styleManager: StyleManager!

Expand Down Expand Up @@ -406,6 +411,15 @@ public class NavigationViewController: UIViewController {
let secondsRemaining = routeProgress.currentLegProgress.currentStepProgress.durationRemaining

mapViewController?.notifyDidChange(routeProgress: routeProgress, location: location, secondsRemaining: secondsRemaining)

if usesNightStyleInsideTunnels, let currentIntersection = routeProgress.currentLegProgress.currentStepProgress.currentIntersection,
let classes = currentIntersection.outletRoadClasses {
if classes.contains(.tunnel) {
styleManager.applyStyle(type:.nightStyle)
} else {
styleManager.timeOfDayChanged()
}
}

progressBar.setProgress(routeProgress.currentLegProgress.userHasArrivedAtWaypoint ? 1 : CGFloat(routeProgress.fractionTraveled), animated: true)
}
Expand Down
30 changes: 21 additions & 9 deletions MapboxNavigation/StyleManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,22 @@ open class StyleManager: NSObject {
resetTimeOfDayTimer()
}

func applyStyle(type styleType: StyleType) {
guard currentStyleType != styleType else { return }

NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(timeOfDayChanged), object: nil)

for style in styles {
if style.styleType == styleType {
style.apply()
currentStyleType = styleType
delegate?.styleManager?(self, didApply: style)
}
}

forceRefreshAppearance()
}

func applyStyle() {
guard let location = delegate?.locationFor(styleManager: self) else {
// We can't calculate sunset or sunrise w/o a location so just apply the first style
Expand All @@ -116,14 +132,7 @@ open class StyleManager: NSObject {
}

let styleTypeForTimeOfDay = styleType(for: location)

for style in styles {
if style.styleType == styleTypeForTimeOfDay {
style.apply()
currentStyleType = style.styleType
delegate?.styleManager?(self, didApply: style)
}
}
applyStyle(type: styleTypeForTimeOfDay)
}

func styleType(for location: CLLocation) -> StyleType {
Expand All @@ -144,7 +153,10 @@ open class StyleManager: NSObject {
}

applyStyle()

forceRefreshAppearance()
}

func forceRefreshAppearance() {
for window in UIApplication.shared.windows {
for view in window.subviews {
view.removeFromSuperview()
Expand Down

0 comments on commit 2acbe46

Please sign in to comment.