Styling a Weather Map

Aside from choosing which mapping library to use for your weather map, you can also customize the styling of many data sources displayed on a map. Currently, annotations, polygons and polylines associated with a weather-related data source can contain custom styling.

Styling is configured and managed using an AWFWeatherMapStyle object and is assigned to a weather map's style property. A weather map style instance will hold the various style specifications for overlays, annotations and polygons and already has default styles setup for all supported data sources and layer types.

All style specifications are subclasses of AWFMapItemStyle, which provides common style properties shared across annotation and polygon styles.

Styling Raster Data

Since raster data is provided as pre-rendered imagery from Aeris Maps (AMP), the SDK doesn't currently provide a way to customize these layers beyond using the advanced features available with AMP. Refer to the Using AMP Features guide for more information on how to adjust the appearance of these raster layers.

Styling Annotations

Weather-related annotations can be represented on a weather map by a circular point or an image and their styles are controlled by AWFAnnotationStyle. By default all annotations are circular points with both a fill and stroke color. When you initializes an new annotation style you can specify these values to override the defaults:

AWFAnnotationStyle *earthquakeStyle = [AWFAnnotationStyle styleWithRadius:12.0 fillColor:[UIColor greenColor] strokeColor:[UIColor whiteColor] strokeWidth:2.0];
let earthquakeStyle = AWFAnnotationStyle(radius: 12.0, fill: .green, stroke: .white, strokeWidth: 2.0)

Most mapping libraries, such as Apple's MapKit or Google Maps, allow you to represent annotations on a map as a custom image rather than a generic marker. You can use images for your weather-related annotations as well by setting the image property on your annotation style:

earthquakeStyle.image = [UIImage imageNamed:@"quake_minor.png"];
// determines whether or not the point should be drawn under the image
earthquakeStyle.showsPoint = NO;
earthquakeStyle.image = UIImage(named: "quake_minor")
// determine whether or not the point should be drawn under the image
earthquakeStyle.showsPoint = false

You can also define presentation and dismissal animations that are applied to an annotation's associated view when the annotation is added or removed from the map. For instance, the following would apply a pop animation to an earthquake annotation when it is added to the map:

CABasicAnimation *scaleOutAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleOutAnimation.duration = 0.3f;
scaleOutAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)];
scaleOutAnimation.removedOnCompletion = YES;
scaleOutAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

earthquakeStyle.inAnimation = scaleOutAnimation;
earthquakeStyle.shouldAnimate = YES;
let scaleOutAnimation = CABasicAnimation(keyPath: "transform")
scaleOutAnimation.duration = 0.3
scaleOutAnimation.toValue = NSValue(caTransform3D: CATransform3DMakeScale(1.2, 1.2, 1.0))
scaleOutAnimation.isRemovedOnCompletion = true
scaleOutAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

earthquakeStyle.inAnimation = scaleOutAnimation
earthquakeStyle.shouldAnimate = true

Annotations do not have a default presentation or dismissal animation defined.

Styling Polygons

Polygons associated with a shape data source are styled similarly to annotations but using an AWFPolygonStyle object. This style object provides the fill and stroke styles to apply to the polygon when rendered on the map:

AWFPolygonStyle *warningStyle = [AWFPolygonStyle style];
warningStyle.fillColor = nil;
warningStyle.strokeColor = [UIColor redColor];
warningStyle.strokeWidth = 2.0;
let warningStyle = AWFPolygonStyle()
warningStyle.fillColor = nil
warningStyle.strokeColor = .red
warningStyle.strokeWidth = 2.0

Style Groups

For many point and polygon data sources, their data is oftentimes grouped into categories based on their properties. For instance, earthquakes are grouped by their magnitude, whereas storm reports are grouped based on their types (e.g. rain, tornado, snow, etc).

To handle these different categories when displaying the data on a map, the SDK supports an AWFGroupedStyle object. A grouped style object is a style specification for a single layer type that contains a set of individual style objects associated with category keys for that layer type. Each category's style can then have a different style than the others, such as a different point color or size, or entirely different image.

This is the method used for defining the default styles for most of the point and shape data sources on a weather map. Check out our grouped style example to find out how we setup the default earthquakes style based on earthquake magnitude using this grouped style method.

Overriding Default Styles

The default weather map style already provides default styles and style groups for all supported point and shape data sources, but you may want to customize these styles to better fit within the context of your own project.

You easily override the default styles and provide your own customizations using the setStyle:forLayerType: method on the weather map style instance, providing your custom style object and the layer type code to associate the style with. For instance, the following would update the map style to use an 18-point red circle for all earthquakes:

AWFAnnotationStyle *earthquakeStyle = [AWFAnnotationStyle styleWithRadius:18.0 fillColor:[UIColor redColor] strokeColor:[UIColor whiteColor] strokeWidth:2.0];
[self.weatherMap.style setStyle:earthquakeStyle forLayerType:AWFMapLayerEarthquakes];
let earthquakeStyle = AWFAnnotationStyle(radius: 18, fill: .red, stroke: .white, strokeWidth: 2)
weatherMap.style.setStyle(earthquakeStyle, forLayerType: .earthquakes)

You can also just tweak the properties on the current style by first returning the currently assigned style from a weather map and changing its properties. Note, however, that this method may return an instance of AWFGroupedStyle or subclass of AWFMapItemStyle, so you'll need to check the type before trying to access its properties:

id style = [self.weatherMap.style styleForLayerType:AWFMapLayerEarthquakes];
if ([style isKindOfClass:[AWFAnnotationStyle class]]) {
    AWFAnnotationStyle *annotationStyle = (AWFAnnotationStyle *)style;
    // change the style properties...
} else if ([style isKindOfClass:[AWFGroupedStyle class]]) {
    AWFGroupedStyle *groupedStyle = (AWFGroupedStyle *)style;
    // change the individual style instances within the group...
}
let style = weatherMap.style.style(forLayerType: .earthquakes)
if let annotationStyle = style as? AWFAnnotationStyle {
    // change the style properties...
} else if let groupedStyle = style as? AWFGroupedStyle {
    // change the individual style instances within the group...
}

If an assigned style is a grouped style instance, you can access the individual styles based on the category identifiers associated with that layer using styleForIdentifier::

AWFAnnotationStyle *majorStyle = [groupedStyle styleForIdentifier:AWFEarthquakeAnnotationTypeMajor];
let majorStyle = groupedStyle.style(forIdentifier: AWFEarthquakeAnnotationType.major.rawValue)

The AWFGroupedStyle class offers several other useful methods when working with category-based styling, such as returning the style for an AWFWeatherObject instance or controlling the labels displayed for the layer's legend when applicable. Refer to the documentation for AWFGroupedStyle for the complete list of available properties and methods.

Last modified: May 22, 2018