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.

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 the Aeris Maps Platform (AMP). 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.interactive('#ia-map', {
    layers: 'stormcells,drought-monitor',
    styles: {
        stormcells: {
            svg: {
                fill: {
                    color: '#ff0000'
                },
                stroke: {
                    color: '#ffffff',
                    width: 2
                }
            }
        },
        'drought-monitor': {
            fill: {
                color: '#ff2400'
            },
            stroke: {
                color: '#ffffff',
                width: 1
            }
        }
    }
}).then(map => {
    // do stuff with the map instance...
});

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 the Aeris Maps Platform (AMP), 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:

map.addLayer('temperatures', {
    style: {
        opacity: 0.8,
        blur: 2
    }
});

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

Stying 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 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.

Refer to the MarkerStyle type documentation for 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 a image URL to use for retina devices (when supported by the active mapping strategy):

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

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

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

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:

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

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

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 or custom SVG path. Then just provide the stroke, fill and/or text options:

map.addLayer('stormreports', {
    style: {
        svg: {
            type: 'circle',
            fill: {
                color: '#ffcccc'
            },
            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.

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

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

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

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

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: {
        svg: {
            type: 'text',
            text: {
                value: 'Cell',
                color: '#ff0000',
                size: 14,
                style: 'bold'
            }
        },
        size: [50, 14]
    }
});

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: {
        svg: {
            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]
    }
});

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 a style object 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:

map.addLayer('drought-monitor', {
    style: {
        fill: {
            color: '#ff2400'
        },
        stroke: {
            color: '#ffffff',
            width: 1
        }
    }
});

Refer to the VectorStyle 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 to 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:

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

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

        // 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: {
                type: 'circle',
                fill: {
                    color: type ? colors[type.toLowerCase()] : colors.default
                },
                stroke: {
                    color: '#ffffff',
                    width: 2
                }
            },
            size: [12, 12]
        };
    }
});

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:

map.addLayer('convective-outlook', {
    style: (data) => {

        // dictionary that associates a color for each category
        const colors = {
            default: '#000000',
            general: '#b3e6b1',
            marginal: '#6cbd69',
            slight: '#f4f964',
            enhanced: '#e0b767',
            moderate: '#e0686a',
            high: '#fe59ff'
        };  

        // 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
            }
        };
    }
});