Styling a Weather Map

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

Note: Any updates to the map, such as changing the viewport, starting the animation, and/or adding and removing layers, must occur after the map has been fully initialized and loaded. Therefore, you’ll need to perform these changes within an event handler on the map’s ready event.

Overriding Default Styles

A weather map instance is already configured with default styles for all point and shape data sources based on the standard categories and colors used within AerisWeather Maps. However, you can override these groups and styles by setting your custom style provider object for a particular layer code on your weather map instance.

The easiest way to override the default styles is to include them in your map’s configuration options at instantiation within a styles property, which should be an object containing style options keyed by layer code:

aeris.views().then((views) => {
    const map = new views.InteractiveMap('#map', {
        center: {
            lat: 38,
            lon: -120
        },
        zoom: 5,
        layers: 'earthquakes,drought-monitor',
        styles: {
            earthquakes: {
                marker: {
                    svg: {
                        shape: {
                            fill: {
                                color: '#ff0000'
                            },
                            stroke: {
                                color: '#ffffff',
                                width: 2
                            }
                        }
                    }
                }
            },
            'drought-monitor': {
                polygon: {
                    fill: {
                        color: '#c98b33'
                    },
                    stroke: {
                        color: '#ffffff',
                        width: 1
                    }
                }
            }
        }
    });
});
Interactive map with custom point and shape styles

Alternatively, you can set the styles when adding them to the map. Review the examples below for more information about styling various weather data sources.

Styling Raster/Tile Data

Raster layers can be styled using one of the many advanced image features available within AerisWeather Maps, such as adding blend modes and filters.

To do so, provide an object of options as the second parameter to your weather map’s addLayer method and include a styleproperty containing your style settings:

// add temperatures layer with water regions removed
map.addLayer('temperatures,water-flat:blend(dst-out)', {
    style: {
        opacity: 0.8,
        blur: 2
    }
});
Interactive map with custom raster layer styling

A raster style supports the following options:

Option Type Description
opacity number Opacity of the layer on the map.
format string The file extension format to use for Maps image requests. Default is png.
zIndex number The z-index to apply to the layer when rendering on the map.
belowLayer string String identifier under which the raster layer will be inserted. This is only available for third-party mapping libraries that support it (only Mapbox GL currently).
blur number Amount to blur the image.
blendMode number Blend mode to apply to the image.

Refer to the RasterStyle type documentation for additional information regarding which style options are supported and their descriptions.

Styling Point Data

Weather-related markers can be represented on a weather map using a raster or SVG image, HTML, or a dynamically-rendered SVG circle, rectangle or custom path. By default all annotations are circular SVG shapes with both a fill and stroke color.

Similar to raster and tile data, point data sources are styled by providing a style.marker object in your options when adding a layer to the weather map. Depending on your desired outcome, you then need to provide an icon, html, or svg property on your style object which will be used for rendering it on the map.

A point/marker style supports the following options:

Option Type Description
className string Style class name to add to the marker’s DOM element when supported.
html string HTML content to use when rendering the icon.
icon object Provides the icon options for the style. Refer to the Icon Markers section for the list of supported options.
svg object Provides the options for rendering the icon as an SVG element. Refer to the SVG Markers section for the list of supported options.
size number[] Size of the icon as [width, height], e.g. [20, 15]
callout function xxxxx
skip boolean If true, then the marker(s) associated with the style will not be rendered to the map.

Refer to the MarkerStyle type documentation for additional information regarding which style options are supported and their descriptions.

Icon Markers

When using icon or image marker styles, you need to provide a URL to the image file for the marker at minimum within your style’s icon property. This file can either be a raster image (PNG or JPEG), or it can be an SVG file. When using raster images for markers, you’ll likely want to use a higher-resolution image for retina devices. So, also include an image URL to use for retina devices (when supported by the active mapping strategy).

An icon configuration supports the following options:

Option Type Description
url string The URL to the icon image (absolute or relative to the script path).
retinaUrl string URL to a retina-sized version of the icon image. If not provided, the url icon path will be used for retina devices.
anchor number[] The point coordinates of the tip of the icon (relative to the top-left corner) as [x, y], e.g. [-5, 0].

The following will use a standard and retina PNG for the marker’s icon:

map.addLayer('fires', {
    style: {
        marker: {
            icon: {
                url: '/img/docs/js/map/marker-fire.png',
                retinaUrl: '/img/docs/js/map/marker-fire@2x.png'
            }
        }
    }
});

Or, you can provide SVG image files for your icons:

map.addLayer('fires', {
    style: {
        marker: {
            icon: {
                url: '/img/docs/js/map/marker-fire.svg'
            },
            size: [30, 30]
        }
    }
});
Interactive map with custom point layer styling using images

HTML Markers

If you want to render custom HTML inside your markers, you simply need to provide the html property on your style object with the HTML content string:

// marker is styled using the .marker-quake CSS selector
map.addLayer('earthquakes', {
    style: {
        marker: {
            html: '<div class="marker-quake">Quake</div>'
        }
    }
});

Then you can use CSS to further customize the styling of the content within the marker.

Interactive map with custom point layer styling with HTML

Note that your selected mapping strategy may or may not support custom HTML in a marker element. Refer to the documentation for your third-party mapping library to determine if HTML is supported in markers.

SVG Markers

The easiest and quickest method to customize weather markers on your map is to render them as SVG elements based on your options. You can configure your marker to render the SVG as a circle, rectangle, text, image, or custom SVG path. Then just provide the stroke, fill and/or text options.

An SVG configuration supports the following primary options where any or all options can be provided:

Option Type Description
shape object Provides the shape style configuration to display with the marker. See the supported shape options.
image object Provides the image style configuration to display with for the marker. See the supported image options.
text object or object[] Provides the text or series of text elements to display with the marker. See the supported text options.

SVG Shape Options

The following options are available when styling shapes to be used in an SVG marker:

Option Type Description
type string Determines the type of shape to render. Supports circle, rect, or path. Default value is circle.
stroke object Shape stroke style options.
stroke.color string Stroke color.
stroke.opacity number Stroke opacity.
stroke.width number Stroke width in pixels.
stroke.lineCap string Defines the shape to be used at the end of the stroke. Supports butt, round, or square.
stroke.lineJoin string Defines the shape to be used at the corners of the stroke. Supports miter, round, bevel, miter-clip, or arcs.
stroke.dashArray string Defines the stroke dash pattern.
stroke.dashOffset string Defines the distance into the dash pattern to start the dash.
fill object Shape fill style options.
fill.color string Fill color.
fill.opacity number Fill opacity.
fill.rule string Defines how the inside of a shape is determined. Supports nonzero or evenodd.
smoothing string Amount to simplify the shape path on each zoom level. More smoothing means better performance and a smoother appearance, where less means a more accurate representation. This option is not supported for all third-party mapping strategies.
path string Defines the shape of the path for SVG elements.
viewBox string Defines the position and dimension, in user space, of the SVG viewport. Only used when path is specified.
position string or { x: number, y: number } Position of the shape relative to the marker container. Supports an anchor string for relative positioning, or an { x, y } point for absolute positioning.
translate { x: number, y: number } Position translation amount in the x and y axes.
transform string Defines a list of transform definitions that are applied to the element.

SVG Image Options

The following options are available when styling images to be used in an SVG marker:

Option Type Description
url string Image URL path.
size number[] Size of the image as [width, height], e.g. [20, 15]
position string or { x: number, y: number } Position of the image relative to the marker container. Supports an anchor string for relative positioning, or an { x, y } point for absolute positioning.
translate { x: number, y: number } Position translation amount in the x and y axes.
transform string Defines a list of transform definitions that are applied to the element.

SVG Text Options

The following options are available when styling text to be used in an SVG marker:

Option Type Description
value number, string Text value to display.
anchor start | middle | end Determines the text container alignment relative to its position.
size number Font size.
style number Font style, e.g. normal or bold.
color string Text color.
padding [x: number, y: number] Amount of padding to insert around the text, where x is the amount of horizontal padding and y is the amount of vertical padding.
autosize boolean Whether to automatically size the marker based on the width and height of the text. Default is true.
position string or { x: number, y: number } Position of the image relative to the marker container. Supports an anchor string for relative positioning, or an { x, y } point for absolute positioning.
translate { x: number, y: number } Position translation amount in the x and y axes.
transform string Defines a list of transform definitions that are applied to the element.

The following style configuration will render markers as a 14x14 pixel circle with a yellow fill and white two pixel stroke:

map.addLayer('stormreports', {
    style: {
        marker: {
            svg: {
                shape: {
                    type: 'circle',
                    fill: {
                        color: '#ffcc00'
                    },
                    stroke: {
                        color: '#ffffff',
                        width: 2
                    }
                }
            },
            size: [14, 14]
        }
    }
});

Note that you also must provide a size value, which is an array containing the width and height values in pixels you want your marker to be rendered at. The above configuration would render a filled red circle with a 2px white stroke.

Interactive map with custom point layer styling using SVG

If you don’t want a stroke or a fill, then simply leave those values out of your object:

map.addLayer('stormreports', {
    style: {
        marker: {
            svg: {
                shape: {
                    type: 'circle',
                    fill: {
                        color: '#7101df'
                    }
                }
            },
            size: [14, 14]
        }
    }
});

Maybe you want to use a rectangle instead of a square:

map.addLayer('stormreports', {
    style: {
        marker: {
            svg: {
                shape: {
                    type: 'rect',
                    fill: {
                        color: '#7101df'
                    },
                    stroke: {
                        color: '#ffffff',
                        width: 2
                    }
                }
            },
            size: [14, 14]
        }
    }
});
Interactive map with custom point layer styling using SVG rectangles

Alternatively, you can render SVG text for your marker by using the text property, which may require yo to adjust your size property to prevent the text from being cropped:

map.addLayer('stormreports', {
    style: {
        marker: {
            svg: {
                text: {
                    value: 'Cell',
                    color: '#ff0000',
                    size: 12,
                    style: 'bold'
                }
            },
            size: [50, 14]
        }
    }
});
Interactive map with custom point layer styling using text labels

You can also combine shapes and text to create a shield element for your markers, which is useful if you want to display text values over a colored background based on the data values. By default, each SVG element will be sized to fit the text within it, including any padding as defined by svg.text.padding:

map.addLayer('stormreports', {
    style: {
        marker: {
            svg: {
                shape: {
                    type: 'rect',
                    fill: {
                        color: '#7101df'
                    },
                    stroke: {
                        color: '#ffffff',
                        width: 2
                    },
                    radius: 3
                },
                text: {
                    value: 'Cell',
                    color: '#ffffff',
                    size: 12,
                    style: 'bold',
                    padding: [4, 2]
                }
            },
            size: [50, 14]
        }
    }
});
Interactive map with custom point layer styling using shapes and text labels

Custom SVG Paths

If you want even more customization options or provide more complex geometries for your markers, you can also provide a custom SVG path string to your style object. For instance, the following will render a red plus symbol for each storm report:

map.addLayer('stormreports', {
    style: {
        marker: {
            svg: {
                shape: {
                    type: 'path',
                    fill: {
                        color: '#ff0000'
                    },
                    path: 'M2 1 h1 v1 h1 v1 h-1 v1 h-1 v-1 h-1 v-1 h1 z'
                },
                viewBox: '0 0 5 5'
            },
            size: [20, 20]
        }
    }
});
Interactive map with custom point layer styling using custom SVG paths

Styling Shape Data

Styling shape data sources, such as polygons and polylines, can be done by providing the necessary stroke and fill style options when adding the layer to the map.

Similar to the other data source types, shape data sources are styled by providing style.polygon and/or style.polyline object(s) in your options when adding a layer to the weather map. Within this style object, simply provide the stroke and fill properties with your particular values. Note that only stroke options will be used for polyline styles:

map.addLayer('drought-monitor', {
    style: {
        polygon: {
            fill: {
                color: '#ff2400'
            },
            stroke: {
                color: '#ffffff',
                width: 1
            }
        }
    }
});
Interactive map with custom shape layer styling

Refer to the ShapeStyle type documentation for information regarding which style options are supported and their descriptions.

Data-Specific Styles

Oftentimes, point and shape data sources are rendered on the map differently based on specific values from the data they represent. For instance, earthquake markers would be rendered with different colors and sizes based on the magnitude values, or convective outlook polygons are rendered based on their category.

Up until now, we’ve been customizing data source styling using a static configuration, meaning all objects for that source will be rendered the same. Fortunately, the SDK also supports dynamic styling that allows you to return a style configuration based on the underlying model data that the object represents.

To use this feature, you’ll need to provide a callback function block instead of a regular object for your style property which will receive the associated model data as an argument. Then, this function needs to return the style configuration to use for that object on the map. The style object can be any of the types supported by that data source type.

For example, the following is the default style configuration for storm cells, which are rendered based on their traits, such as hail, rotating or tornadic:

// dictionary that associates a color for each category
const colors = {
    default: '#000000',
    general: '#2ed300',
    hail: '#ebe100',
    rotating: '#f17200',
    tornado: '#ff2600'
};

map.addLayer('stormcells', {
    style: {
        marker: (data) => {

            // get the type property value from the passed in model data
            const { traits: { type }} = data;

            // return the style configuration for this storm cell marker
            return {
                svg: {
                    shape: {
                        type: 'circle',
                        fill: {
                            color: type ? colors[type.toLowerCase()] : colors.default
                        },
                        stroke: {
                            color: '#ffffff',
                            width: 2
                        }
                    }
                },
                size: [12, 12]
            };
        }
    }
});
Interactive map with custom point layer styling based on data values

You can see in this example each storm cell marker is filled using a color based on the cell’s type code. We could take this a step further and use different sizes based on these codes as well by adding additional logic.

You can do something similar for shape data sources, such as convective outlooks:

// dictionary that associates a color for each category
const colors = {
    default: '#000000',
    general: '#b3e6b1',
    marginal: '#6cbd69',
    slight: '#f4f964',
    enhanced: '#e0b767',
    moderate: '#e0686a',
    high: '#fe59ff'
};
        
map.addLayer('convective-outlook', {
    style: {
        polygon: (data) => {

            // get the type property value from the passed in model data
            const { details: { risk: { type }}} = data;

            // return the style configuration for this storm cell marker
            return {
                fill: {
                    color: type ? colors[type.toLowerCase()] : colors.default,
                    opacity: 0.7
                }
            };
        }
    }
});

Last modified: August 20, 2021