Map Legends

Legends for weather data sources are managed using the AWFLegendView class, which automatically renders legends based on layer types that are added and removed. You add and remove legends by layer type codes using the methods addLegendForLayerType: and removeLegendForLayerType: respectively.

Typically you will only want to display legends for weather layers that are currently active on your weather map:

ObjectiveC
Swift
[self.weatherMap addSourceForLayerType:AWFMapLayerTemperatures];
[self.legendView addLegendForLayerType:AWFMapLayerTemperatures];
weatherMap.addSource(forLayerType: .temperatures)
legendView.addLegend(forLayerType: .temperatures)

And then you'll want to remove the legend when removing its associated source from the map:

ObjectiveC
Swift
[self.weatherMap removeSourceForLayerType:AWFMapLayerTemperatures];
[self.legendView removeLegendForLayerType:AWFMapLayerTemperatures];
weatherMap.removeSource(forLayerType: .temperatures)
legendView.removeLegend(forLayerType: .temperatures)

An easier approach would be to adopt the AWFWeatherMapDelegate protocol and implement the delegate methods that will notify you when weather layers are added and/or removed from the map:

ObjectiveC
Swift
#pragma mark - AWFWeatherMapDelegate

- (void)weatherMap:(AWFWeatherMap *)weatherMap didAddLayerForType:(nonnull AWFMapLayer)layerType {
    [self.legendView addLegendForLayerType:layerType];
}
    
- (void)weatherMap:(AWFWeatherMap *)weatherMap didRemoveLayerForType:(nonnull AWFMapLayer)layerType {
    [self.legendView removeLegendForLayerType:layerType];
}
extension ViewController: AWFWeatherMapDelegate {

    func weatherMap(_ weatherMap: AWFWeatherMap, didAddLayerForType layerType: AWFMapLayer) {
        legendView.addLegend(forLayerType: layerType)
    }
    
    func weatherMap(_ weatherMap: AWFWeatherMap, didRemoveLayerForType layerType: AWFMapLayer) {
        legendView.removeLegend(forLayerType: layerType)
    }
}

When legends are added or removed to the legend view, its intrinsicContentSize will be invalidated to account for the new size. So you may need to adjust its positioning whether or not you are using AutoLayout in your project.

Note that if you are using or subclassing AWFWeatherMapViewController, then the legend view and weather map delegate methods are already implemented for you and you don't have to worry about creating your own instance or managing the legends. By default, the legend view is pinned to the top of the view and will expand down accordingly as legends are added and removed. The legend view is laid out in the view using AutoLayout, so if you wish to adjust its positioning within your own project, you'll need to deactivate and remove the layout constraints already associated with it.

Laying Out AWFLegendView

As mentioned above, if you are using or subclassing AWFWeatherMapViewController, then the legend view and associated weather map delegate methods are already implemented for you. Furthermore, layout and positioning of the legend view is automatically handled and pinned to the top of the view controller's view using AutoLayout.

However, if you are instantiating AWFLegendView outside of AWFWeatherMapViewController in your custom implementation, you will need to set up the necessary constraints for positioning and laying out your legend view. At a minimum, you need to provide the top or bottom layout constraint for your legend view. AWFLegendView will automatically adjust its height to account for the active legend items as needed by invalidating its intrinsicContentSize for AutoLayout.

Other than the top or bottom constraint, you also need to provide the horizontal layout constraints, which can be the left, right and or width constraints.

The following would pin the legend view to the bottom of its parent view and to the left and right edges:

ObjectiveC
Swift
self.legendView.translatesAutoresizingMaskIntoConstraints = NO;

[NSLayoutConstraint activateConstraints:@[
    [self.legendView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
    [self.legendView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor],
    [self.legendView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor]
]];
legendView.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
    legendView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
    legendView.leftAnchor.constraint(equalTo: view.leftAnchor),
    legendView.rightAnchor.constraint(equalTo: view.rightAnchor)
])

Due to the auto-sizing nature of the legend view, it is not recommended to set or update the view's frame property directly to configure its layout.

Styling Legends

All legends are rendered dynamically at runtime and cached for the duration of the session. Their styling is implemented in much of the same way as the legend generator for AMP for raster, point and shape data sources.

All raster AerisWeather Maps (AMP) data sources derive their legend styles from the default color configuration used within AMP and the legend generator and thus cannot be modified.

All point and shape data sources derive their styles from annotation and polygon styles configured on a weather map's style. Therefore, if you provide a custom style for one of these layer types and/or its category groupings, such as earthquakes or storm reports, then those styles will also be reflected in the legends for those layers.

You can adjust text label and positioning for your legends via the AWFLegendView instance. Review the legend view class documentation for the complete list of properties and methods available.

Last modified: November 03, 2020