Skip to content
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

Add the ability to show specific route leg with color overriding #2833

Merged
merged 6 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* `NavigationMapView.highlightBuildings(at:in3D:)` was renamed to `NavigationMapView.highlightBuildings(at:in3D:completion:)`. ([#2827](https://github.com/mapbox/mapbox-navigation-ios/pull/2827))
* Added the `NavigationMapView.showsCongestionForAlternativeRoutes` property to show congestion levels with different colors on alternative route lines. ([#2887](https://github.com/mapbox/mapbox-navigation-ios/pull/2887))
* Added the `NavigationMapView.navigationMapView(_:didAdd:)` and `NavigationViewController.navigationViewController(_:didAdd:)` delegate methods, which will be called whenever final destination `PointAnnotation` is added to `NavigationMapView` or `NavigationViewController` respectively. ([#2961](https://github.com/mapbox/mapbox-navigation-ios/pull/2961))
* Added the ability to show specific route leg with color overriding. When specifying the `legIndex` in `NavigationMapView.show(_:legIndex:)`, the route line for the specific route leg would show congestion colors, while other route legs would show `NavigationMapView.routeCasingColor` by default. If not specified, all the route legs would show congestion colors. During turn-by-turn navigation, the default specified route leg is the current route leg. The route leg colors could be overridden by `NavigationMapView.routeCasingColor` and the congestion colors. ([#2833](https://github.com/mapbox/mapbox-navigation-ios/pull/2833))

### Location tracking

Expand Down
32 changes: 20 additions & 12 deletions Sources/MapboxNavigation/NavigationMapView+VanishingRouteLine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ extension NavigationMapView {

let newFractionTraveled = self.preFractionTraveled + traveledDifference * timePassedInMilliseconds.truncatingRemainder(dividingBy: 1000) / 1000

let congestionSegments = routeProgress.route.congestionFeatures(roadClassesWithOverriddenCongestionLevels: self.roadClassesWithOverriddenCongestionLevels)
let congestionSegments = routeProgress.route.congestionFeatures(legIndex: self.currentLegIndex, roadClassesWithOverriddenCongestionLevels: self.roadClassesWithOverriddenCongestionLevels)
let mainRouteLayerGradient = self.routeLineGradient(congestionSegments,
fractionTraveled: newFractionTraveled)
self.mapView.style.updateLayer(id: mainRouteLayerIdentifier, type: LineLayer.self) { (lineLayer) in
Expand All @@ -231,8 +231,12 @@ extension NavigationMapView {
var minimumSegment: (Double, UIColor) = (Double.greatestFiniteMagnitude, .clear)

for (index, feature) in congestionFeatures.enumerated() {
var associatedFeatureColor = routeCasingColor
let congestionLevel = feature.properties?[CongestionAttribute] as? String
let associatedCongestionColor = congestionColor(for: congestionLevel, isMain: isMain)
if let isCurrentLeg = feature.properties?[CurrentLegAttribute] as? Bool, isCurrentLeg {
associatedFeatureColor = congestionColor(for: congestionLevel, isMain: isMain)
}

let lineString = feature.geometry.value as? LineString
guard let distance = lineString?.distance() else { return gradientStops }

Expand All @@ -242,10 +246,10 @@ extension NavigationMapView {
let segmentEndPercentTraveled = CGFloat(distanceTraveled / routeDistance)
let currentGradientStop = Double(segmentEndPercentTraveled.nextDown)
if currentGradientStop >= fractionTraveled {
gradientStops[currentGradientStop] = associatedCongestionColor
gradientStops[currentGradientStop] = associatedFeatureColor

if currentGradientStop < minimumSegment.0 {
minimumSegment = (currentGradientStop, associatedCongestionColor)
minimumSegment = (currentGradientStop, associatedFeatureColor)
}

if index + 1 < congestionFeatures.count {
Expand All @@ -264,10 +268,10 @@ extension NavigationMapView {

if index == congestionFeatures.endIndex - 1 {
let lastGradientStop: Double = 1.0
gradientStops[lastGradientStop] = associatedCongestionColor
gradientStops[lastGradientStop] = associatedFeatureColor

if lastGradientStop < minimumSegment.0 {
minimumSegment = (lastGradientStop, associatedCongestionColor)
minimumSegment = (lastGradientStop, associatedFeatureColor)
}

continue
Expand All @@ -277,10 +281,10 @@ extension NavigationMapView {

if Double(segmentStartPercentTraveled.nextUp) >= fractionTraveled {
let currentGradientStop = Double(segmentStartPercentTraveled.nextUp)
gradientStops[currentGradientStop] = associatedCongestionColor
gradientStops[currentGradientStop] = associatedFeatureColor

if currentGradientStop < minimumSegment.0 {
minimumSegment = (currentGradientStop, associatedCongestionColor)
minimumSegment = (currentGradientStop, associatedFeatureColor)
}
}

Expand All @@ -289,16 +293,20 @@ extension NavigationMapView {
let segmentEndPercentTraveled = CGFloat(distanceTraveled / routeDistance)
if Double(segmentEndPercentTraveled.nextDown) >= fractionTraveled {
let currentGradientStop = Double(segmentEndPercentTraveled.nextDown)
gradientStops[currentGradientStop] = associatedCongestionColor
gradientStops[currentGradientStop] = associatedFeatureColor

if currentGradientStop < minimumSegment.0 {
minimumSegment = (currentGradientStop, associatedCongestionColor)
minimumSegment = (currentGradientStop, associatedFeatureColor)
}
}

if index + 1 < congestionFeatures.count && Double(segmentEndPercentTraveled.nextUp) >= fractionTraveled {
let currentGradientStop = Double(segmentEndPercentTraveled.nextUp)
let currentColor = congestionColor(for: congestionFeatures[index + 1].properties?["congestion"] as? String, isMain: isMain)
let nextCongestionLevel = congestionFeatures[index + 1].properties?[CongestionAttribute] as? String
var currentColor = routeCasingColor
if let isCurrentLeg = congestionFeatures[index + 1].properties?[CurrentLegAttribute] as? Bool, isCurrentLeg {
currentColor = congestionColor(for: nextCongestionLevel, isMain: isMain)
}
gradientStops[currentGradientStop] = currentColor

if currentGradientStop < minimumSegment.0 {
Expand Down
12 changes: 7 additions & 5 deletions Sources/MapboxNavigation/NavigationMapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ open class NavigationMapView: UIView {
var fractionTraveled: Double = 0.0
var preFractionTraveled: Double = 0.0
var vanishingRouteLineUpdateTimer: Timer? = nil
var currentLegIndex: Int?

var showsRoute: Bool {
get {
Expand Down Expand Up @@ -393,19 +394,19 @@ open class NavigationMapView: UIView {
- parameter routes: List of `Route` objects, which will be shown on `MapView`.
- parameter legIndex: Index, which will be used to highlight specific `RouteLeg` on main route.
*/
// TODO: Add ability to handle legIndex.
public func show(_ routes: [Route], legIndex: Int = 0) {
public func show(_ routes: [Route], legIndex: Int? = nil) {
removeRoutes()

self.routes = routes
currentLegIndex = legIndex

var parentLayerIdentifier: String? = nil
for (index, route) in routes.enumerated() {
if index == 0, routeLineTracksTraversal {
initPrimaryRoutePoints(route: route)
}

parentLayerIdentifier = addRouteLayer(route, below: parentLayerIdentifier, isMainRoute: index == 0)
parentLayerIdentifier = addRouteLayer(route, below: parentLayerIdentifier, isMainRoute: index == 0, legIndex: legIndex)
parentLayerIdentifier = addRouteCasingLayer(route, below: parentLayerIdentifier, isMainRoute: index == 0)
}
}
Expand Down Expand Up @@ -436,7 +437,7 @@ open class NavigationMapView: UIView {
updateUserCourseView(CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude))
}

@discardableResult func addRouteLayer(_ route: Route, below parentLayerIndentifier: String? = nil, isMainRoute: Bool = true) -> String? {
@discardableResult func addRouteLayer(_ route: Route, below parentLayerIndentifier: String? = nil, isMainRoute: Bool = true, legIndex: Int? = nil) -> String? {
guard let shape = route.shape else { return nil }

let geoJSONSource = self.geoJSONSource(delegate?.navigationMapView(self, casingShapeFor: route) ?? shape)
Expand All @@ -458,7 +459,8 @@ open class NavigationMapView: UIView {

// TODO: Verify that `isAlternativeRoute` parameter usage is needed.
if isMainRoute {
let gradientStops = routeLineGradient(route.congestionFeatures(roadClassesWithOverriddenCongestionLevels: roadClassesWithOverriddenCongestionLevels),
let congestionFeatures = route.congestionFeatures(legIndex: legIndex, roadClassesWithOverriddenCongestionLevels: roadClassesWithOverriddenCongestionLevels)
let gradientStops = routeLineGradient(congestionFeatures,
fractionTraveled: routeLineTracksTraversal ? fractionTraveled : 0.0)
lineLayer?.paint?.lineGradient = .expression((Expression.routeLineGradientExpression(gradientStops)))
} else {
Expand Down
4 changes: 2 additions & 2 deletions Sources/MapboxNavigation/Route.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ extension Route {
feature.properties = [
CongestionAttribute: String(describing: congestionSegment.1),
"isAlternativeRoute": isAlternativeRoute,
CurrentLegAttribute: (legIndex != nil) ? index == legIndex : index == 0
CurrentLegAttribute: (legIndex != nil) ? index == legIndex : true
]

return feature
Expand All @@ -80,7 +80,7 @@ extension Route {
var feature = Feature(LineString(shape.coordinates))
feature.properties = [
"isAlternativeRoute": isAlternativeRoute,
CurrentLegAttribute: (legIndex != nil) ? index == legIndex : index == 0
CurrentLegAttribute: (legIndex != nil) ? index == legIndex : true
]
legFeatures = [feature]
}
Expand Down