Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

Add traffic to existing style #64

Closed
1ec5 opened this issue Feb 14, 2017 · 8 comments
Closed

Add traffic to existing style #64

1ec5 opened this issue Feb 14, 2017 · 8 comments

Comments

@1ec5
Copy link
Contributor

1ec5 commented Feb 14, 2017

It’s straightforward enough to create a new style based on the Traffic Day or Traffic Night style in Studio, but if a developer wants to offer a toggleable traffic overlay, they need to write a nontrivial (but not excessive) amount of code using the runtime styling API.

The proposed example would show how to add traffic lines based on the Mapbox Traffic v1 source to an existing style using the runtime styling API. It would hard-code colors and line widths, but the developer would be free to adjust them as desired – we could even throw in some #colorLiterals in the Swift version to make the color scheme easier to tweak.

To ensure that the lines sit beneath any labels and shields in the style, we could hard-code a style layer name, put in a <#placeholder#> for that layer name, or have the developer dynamically search for the topmost layer that isn’t a symbol style layer:

for layer in style.layers.reversed() {
    if !(layer is MGLSymbolStyleLayer) {
        style.insertLayer(line, above: layer)
        // …
        break
    }
}

Along these lines, we might want to make it easy for the developer to toggle traffic lines on and off. We could similarly hard-code a list of layer identifiers, or the developer could search for relevant layers dynamically, demonstrating another aspect of the runtime styling API:

var trafficSource = style.sources
    .flatMap { $0 as? MGLVectorSource }
    .filter { $0.URL == URL(string: "mapbox://mapbox.mapbox-traffic-v1") }
    .first

for layer in style.layers {
    if let layer = layer as? MGLForegroundStyleLayer,
        layer.sourceIdentifier == trafficSource.identifier {
        layer.isVisible = showsTraffic
    }
}

/cc @friedbunny @bsudekum @mtirwin

@pveugen
Copy link

pveugen commented Feb 14, 2017

@frederoni worked on this two weeks ago and has an example to share.

@frederoni
Copy link

frederoni commented Feb 15, 2017

Yep! Here's a quick and dirty example in Objective-C

- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style
{
    NSURL *url = [[NSURL alloc] initWithString:@"mapbox://mapbox.mapbox-traffic-v1"];
    MGLVectorSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"mapbox-traffic-v1" configurationURL:url];
    [mapView.style addSource:source];
    
    MGLLineStyleLayer *streetLayer = (MGLLineStyleLayer *)[self.mapView.style layerWithIdentifier:@"road-street"];
    MGLLineStyleLayer *topRoadLayer = nil;
    for (MGLStyleLayer *layer in mapView.style.layers.reverseObjectEnumerator) {
        if ([layer isKindOfClass:[MGLLineStyleLayer class]]) {
            topRoadLayer = (MGLLineStyleLayer *)layer;
            break;
        }
    }
    
    UIColor *greenColor = [UIColor colorWithRed:88.0/255.0 green:195.0/255.0 blue:35.0/255.0 alpha:1];
    UIColor *yellowColor = [UIColor colorWithRed:242.0/255.0 green:185.0/255.0 blue:15.0/255.0 alpha:1];
    UIColor *redColor = [UIColor colorWithRed:204.0/255.0 green:0 blue:0 alpha:1];
    
    NSArray<NSDictionary *> *layers = @[@{@"congestion": @"low",
                                          @"color": greenColor},
                                        @{@"congestion": @"moderate",
                                          @"color": greenColor},
                                        @{@"congestion": @"heavy",
                                          @"color": yellowColor},
                                        @{@"congestion": @"severe",
                                          @"color": redColor}];
    
    for (NSDictionary *layer in layers) {
        UIColor *color = layer[@"color"];
        NSString *congestion = layer[@"congestion"];
        NSString *layerIdentifier = [NSString stringWithFormat:@"traffic-%@", congestion];
        MGLLineStyleLayer *trafficLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:layerIdentifier source:source];
        trafficLayer.sourceLayerIdentifier = @"traffic";
        trafficLayer.lineWidth = streetLayer.lineWidth;
        trafficLayer.lineCap = streetLayer.lineCap;
        trafficLayer.lineJoin = streetLayer.lineJoin;
        trafficLayer.lineColor = [MGLStyleConstantValue valueWithRawValue:color];
        trafficLayer.predicate = [NSPredicate predicateWithFormat:@"congestion == %@", congestion];
        [mapView.style insertLayer:trafficLayer aboveLayer:topRoadLayer];
    }
}

@bsudekum
Copy link

What do you think about adding this to native?

@1ec5
Copy link
Contributor Author

1ec5 commented Feb 15, 2017

What do you think about adding this to native?

That would be feasible – mapbox/mapbox-gl-native#8071 – although an example would still be helpful in the short term.

@1ec5
Copy link
Contributor Author

1ec5 commented Feb 15, 2017

mapbox/mapbox-gl-js#4274 is the GL JS equivalent to this issue, by the way.

@frederoni, would you mind creating a PR with the code in #64 (comment)? Once v3.5.0 is released, we can also condense the example a bit using a source function (DDS). (Who knows, maybe mapbox/mapbox-gl-native#6442 will land by then and we’ll be able to interpolate the color stops for a gradient effect!)

@jmkiley
Copy link
Contributor

jmkiley commented Sep 22, 2017

Since the traffic plugin is now available in https://github.com/mapbox/mapbox-plugins-ios, we could add an example that shows how to toggle traffic.

@1ec5
Copy link
Contributor Author

1ec5 commented Aug 29, 2018

mapbox/mapbox-navigation-ios#1614 demonstrates adding incidents to any style. I think an example of adding traffic and incidents at runtime could be useful to developers who are unable to use the plugin or Studio to accomplish the same thing for whatever reason.

/ref mapbox/mapbox-plugins-ios#22

@captainbarbosa
Copy link
Contributor

I'm going to argue that this example would be better suited for https://github.com/mapbox/navigation-ios-examples/, and therefore close this issue. If anyone would like to make a case for this belonging in this project, please re-open this issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants