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

Navigation with waypoints, can't change leg color anymore in 1.0.0 #2678

Closed
abouroubi opened this issue Oct 5, 2020 · 16 comments
Closed

Navigation with waypoints, can't change leg color anymore in 1.0.0 #2678

abouroubi opened this issue Oct 5, 2020 · 16 comments
Assignees
Labels
bug Something isn’t working UI Work related to visual components, Android Auto, Camera, 3D, voice, etc.
Milestone

Comments

@abouroubi
Copy link

Mapbox Navigation SDK version: 1.0.0

I was using the SDK version 1.0.0-alpha1, I'm starting navigation with 3 waypoints each time, with the 1.0.0-alpha1, if I wanted to change the color of the current leg, and diffenrentiate it to otehr legs I used this code, and it worked:

self.mapView?.routeCasingColor = #colorLiteral(red: 0.337254902, green: 0.6588235294, blue: 0.9843137255, alpha: 0.1)
self.mapView?.trafficUnknownColor  = #colorLiteral(red: 0.3384324702, green: 0.6636026477, blue: 0.9891712385, alpha: 0.2964898768)

The first line controled the color of the remaining legs, and the second line was the color of the current active leg (where the user is).

After updating to 1.0.0, this doesn't work anymore, the whole route have the second color.

@1ec5
Copy link
Contributor

1ec5 commented Oct 5, 2020

Possibly related: #2595.

@1ec5
Copy link
Contributor

1ec5 commented Oct 5, 2020

As discussed in #2377 (comment), the new NavigationViewController.routeLineTracksTraversal property’s implementation seems to have required removing the styling of inactive legs as translucent lines.

@1ec5 1ec5 added bug Something isn’t working Regression UI Work related to visual components, Android Auto, Camera, 3D, voice, etc. labels Oct 5, 2020
@abouroubi
Copy link
Author

Sorry but I don't really understand, you decided that NavigationViewController.routeLineTracksTraversal is a more important feature than the customization of the inactive legs so you removed it ?

@1ec5
Copy link
Contributor

1ec5 commented Oct 5, 2020

No, it seems to have been an oversight. We’re tracking this issue as a regression. In fact, we were planning on introducing an explicit option to give different routes and legs different colors in a future minor release, something more explicit than how routeCasingColor and trafficUnknownColor happened to combine to produce that effect in previous releases. But fixing the regression is important.

Once #2623 lands, there will be a workaround in the form of specifying a different polyline feature for each leg, but until then, I don’t know of a straightforward workaround.

@abouroubi
Copy link
Author

abouroubi commented Oct 5, 2020

I get it, thank you.

Can you provide me with some explanation on how to specify a polyline feature for each leg ? So i can implement it when #2623 will land

@abouroubi
Copy link
Author

Hi @1ec5 ,
Can you please help me with this issue ? I'm still trying to figure out how I can change the color of the current leg, but I couldn't find a solution.

Some help will be appreciated

@1ec5
Copy link
Contributor

1ec5 commented Feb 17, 2021

Now that #2623 has landed, you can implement NavigationMapViewDelegate.navigationMapView(_:simplifiedShapeFor:) to return a different MGLPolylineFeature for each leg of the route. The current leg would have the isCurrentLeg attribute set to true. Then, in your implementation of NavigationMapViewDelegate.navigationMapView(_:mainRouteStyleLayerWithIdentifier:), you’d return a style layer whose lineOpacity property is set to an expression similar to this:

line.lineOpacity = NSExpression(forConditional:
NSPredicate(format: "isAlternateRoute == true"),
trueExpression: NSExpression(forConstantValue: 1),
falseExpression: NSExpression(forConditional: NSPredicate(format: "isCurrentLeg == true"),
trueExpression: NSExpression(forConstantValue: 1),
falseExpression: NSExpression(forConstantValue: 0)))

This issue essentially tracks bringing back that lineOpacity expression by integrating it into the line gradient. But hopefully this workaround gets you past the issue in the meantime.

/ref #2377 (comment)

@abouroubi
Copy link
Author

abouroubi commented Feb 18, 2021

Hi @1ec5 unfortunately this doesn't work.

I tried with this code:

    func navigationViewController(_ navigationViewController: NavigationViewController, mainRouteStyleLayerWithIdentifier identifier: String, source: MGLSource) -> MGLStyleLayer? {
        
        print(source)
        
        let line = MGLLineStyleLayer(identifier: identifier, source: source)
        line.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", MBRouteLineWidthByZoomLevel)
        line.lineOpacity = NSExpression(forConditional: NSPredicate(format: "isCurrentLeg == true"),
                                                                      trueExpression: NSExpression(forConstantValue: 1),
                                                                      falseExpression: NSExpression(forConstantValue: 0))
        line.lineColor = NSExpression(format: "TERNARY(isAlternateRoute == true, %@, MGL_MATCH(congestion, 'low' , %@, 'moderate', %@, 'heavy', %@, 'severe', %@, %@))", self.mapView?.routeAlternateColor as! CVarArg, self.mapView?.trafficLowColor as! CVarArg, self.mapView?.trafficModerateColor as! CVarArg, self.mapView?.trafficHeavyColor as! CVarArg, self.mapView?.trafficSevereColor as! CVarArg, self.mapView?.trafficUnknownColor as! CVarArg)
        line.lineJoin = NSExpression(forConstantValue: "round")
        
        return line
        
    }

But this is called only once with the whole navigation route, not for each leg.

Concerning the implementation of NavigationMapViewDelegate.navigationMapView(_:simplifiedShapeFor:), if I do it I override the default implementation called here:

let mainRouteCasingShape = navigationMapViewDelegate?.navigationMapView(self, simplifiedShapeFor: route) ??

And because the delegate don't have the legIndex as a parameter, I can't manually set the attribute of "isCurrentLeg".

@1ec5
Copy link
Contributor

1ec5 commented Feb 18, 2021

You’re right, I don’t think there’s a suitable workaround at this time. I’m recommending to the team that we prioritize a fix for the original regression by integrating the old leg-based coloring feature into the line gradient so that the deemphasized legs will work regardless of the routeLineTracksTraversal property.

@1ec5 1ec5 added this to the v2.0.0 milestone Feb 18, 2021
@abouroubi
Copy link
Author

Thank you @1ec5

@truburt truburt modified the milestones: v2.0.0, v2.0.0 (Public Preview), v2.0.0 (Public Preview) (iOS) Feb 26, 2021
@azarovalex azarovalex self-assigned this Mar 23, 2021
@truburt truburt added wip and removed wip labels Apr 2, 2021
@azarovalex
Copy link
Contributor

Currently is blocked by PR #2833. We can return to this ticket after this PR lands.

@ShanMa1991
Copy link
Contributor

@azarovalex #2833 is merged now. We could start working on this issue.

@azarovalex
Copy link
Contributor

@abouroubi You can now use NavigationMapView.show(_:, legIndex:) function to color only a specific leg of your route.
If you don't specify the leg Index, the whole route would be colored in congestion color. But if you specify the leg index, only the specified legIndex will be colored in the congestion color, while other legs will be colored in the routeCasingColor.
So, in your case the code will look like this:

self.mapView?.routeCasingColor = #colorLiteral(red: 0.337254902, green: 0.6588235294, blue: 0.9843137255, alpha: 0.1)
self.mapView?.trafficUnknownColor  = #colorLiteral(red: 0.3384324702, green: 0.6636026477, blue: 0.9891712385, alpha: 0.2964898768)
self.mapView?.show([route], legIndex: 1)

You can call NavigationMapView.show(_:, legIndex:) function with new legIndex value after arriving at each waypoint, so only the current leg will be colored.
This new behavior will be available in the v2.0.0-beta.8 release next week. I think we can close this issue for now, because this solves your initial request.
Feel free to ping me if you have any additional questions.

@abouroubi
Copy link
Author

Thanks @azarovalex , I'll check it as soon as it's available.

@abouroubi
Copy link
Author

Hello @azarovalex
Sorry for the delay, but the solution that you gave me doesn't work.

You can call NavigationMapView.show(_:, legIndex:) function with new legIndex value after arriving at each waypoint, so only the current leg will be colored.

I assume you are talking about this function to update the active leg index ?

func navigationViewController(_ navigationViewController: NavigationViewController, didArriveAt waypoint: Waypoint) -> Bool

Unfortunately the Waypoint object don't have the legIndex, so we can't now which is the current one, and we still miss the route array that is needed by the NavigationMapView.show(_:, legIndex:).

So it's still difficult to de-emphasize the inactive legs in the iOS Navigation SDK.
It would have been easier to use the Android implementation mentioned by @1ec5, it's clearer and easier to for developers to use and understand.

@ShanMa1991
Copy link
Contributor

Hi @abouroubi , the way to change the color of current leg is the same as before in the following ways:

  1. When the navigation session not started yet, if we just want to display the route on the map, we do something as in the following, the legIndex in the navigationMapView.show(_:legIndex:) is the leg you'd like to highlight with the trafficUnknownColor. If you want to highlight the route between the 2nd waypoint and the 3rd waypoint, then the leg index is 1, which starting from 0.
navigationMapView.routeCasingColor = UIColor.red
navigationMapView.trafficUnknownColor = UIColor.blue
navigationMapView.show([route], legIndex: 1)
  1. When the navigation session starts, the default current leg is the route line part that you drive on, which is between the passed waypoint and the upcoming waypoint. To specify the route leg color, you just set the properties of the navigationViewController.navigationMapView before you present it like the following. So the current route leg you're driving on will display the trafficUnknownColor with congestion level, while all other legs that you're not driving on will all show the routeCasingColor.
navigationViewController.navigationMapView.routeCasingColor = UIColor.red
navigationViewController.navigationMapView.trafficUnknownColor = UIColor.blue

present(navigationViewController, animated: true) {
    self.navigationMapView?.removeFromSuperview()
    self.navigationMapView = nil
}

Tis pr provides some examples to show how it work with the color. I hope it's helpful to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn’t working UI Work related to visual components, Android Auto, Camera, 3D, voice, etc.
Projects
None yet
Development

No branches or pull requests

5 participants