Filter weather alerts by category

Filter weather alerts by category

This example demonstrates how to filter the data displayed by the alerts weather layer by alert category. The available alert categories are listed in the categories object, which includes the category title and the VTEC codes associated with each category.

The VTEC codes and their associated alerts are listed at https://www.xweather.com/docs/maps/reference/alert-types (opens in a new tab).

For more details on how to filter raster and vector layer data, see the filtering data documentation.

filter-alerts.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>MapsGL SDK - Filter weather alerts by category</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Filter weather alerts based on alert category in real-time.">
 
    <link href="https://api.mapbox.com/mapbox-gl-js/v2.8.0/mapbox-gl.css" rel="stylesheet" />
    <script defer src="https://api.mapbox.com/mapbox-gl-js/v2.8.0/mapbox-gl.js"></script>
 
    <link href="https://cdn.aerisapi.com/sdk/js/mapsgl/latest/aerisweather.mapsgl.css" rel="stylesheet" />
    <script defer src="https://cdn.aerisapi.com/sdk/js/mapsgl/latest/aerisweather.mapsgl.js"></script>
    
 
    <style>
    body, html {
        margin: 0;
        padding: 0;
    }
    #map {
        height: 100vh;
        width: 100%;
    }
    #controls {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        gap: 8px;
        position: absolute;
        top: 10px;
        left: 10px;
        z-index: 1;
        background: rgba(255, 255, 255, 0.8);
        padding: 10px;
        border-radius: 5px;
        font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
        font-size: 12px;
    }
    #controls h3 {
        margin: 0 0 6px;
        font-size: 14px;
    }
    </style>
 
</head>
<body>
    <div id="map"></div>
    <div id="controls">
        <h3>Alert Category</h3>
        <select id="category">
            <option value="all" selected>All</option>
        </select>
    </div>
 
    <script>
        window.addEventListener('load', () => {
 
            mapboxgl.accessToken = 'MAPBOX_TOKEN';
            const map = new mapboxgl.Map({
                container: document.getElementById('map'),
                style: 'mapbox://styles/mapbox/light-v9',
                center: [-93, 40],
                zoom: 3
            });
 
            const account = new aerisweather.mapsgl.Account('CLIENT_ID', 'CLIENT_SECRET');
            const controller = new aerisweather.mapsgl.MapboxMapController(map, { account });
 
            // Configure the different alert categories and their associated VTEC codes
            // The available VTEC codes and their alerts are listed at https://www.xweather.com/docs/maps/reference/alert-types
            const categories = {
                severe: {
                    title: 'Severe',
                    filter: ['in', 'VTEC', 'SV.W', 'TO.W', 'FF.W', 'MA.W', 'FF.A', 'MA.A', 'TO.A', 'SV.A', 'AW.TS.MN', 
                        'AW.TS.MD', 'AW.TS.SV', 'AW.TS.EX']
                },
                fire: {
                    title: 'Fire',
                    filter: ['in', 'VTEC', 'FW.A', 'FRW', 'RFD', 'FW.W', 'AW.FR.MN', 'AW.FR.MD', 'AW.FR.SV', 'AW.FR.EX']
                },
                flood: {
                    title: 'Flood',
                    filter: ['in', 'VTEC', 'FL.Y', 'FL.A', 'FL.W', 'FL.S', 'FA.W', 'FA.A', 'FF.A', 'FF.W', 'RA.W', 'AW.RA,MN', 
                        'AW.RA.MD', 'AW.RA.SV', 'AW.RA.EX', 'AW.FL.MN', 'AW.FL.MD', 'AW.FL.SV', 'AW.FL.EX', 'AW.RF.MN', 
                        'AW.RF.MD', 'AW.RF.SV', 'AW.RF.EX']
                },
                heat: {
                    title: 'Heat',
                    filter: ['in', 'VTEC', 'EH.A', 'EH.W', 'HT.Y', 'HT.W', 'AW.HT.MN', 'AW.HT.MD', 'AW.HT.SV', 'AW.HT.EX']
                },
                wind: {
                    title: 'Wind',
                    filter: ['in', 'VTEC', 'BW.Y', 'EW.W', 'HW.W', 'HW.A', 'HF.W', 'HF.A', 'LW.Y', 'SI.Y', 'WI.Y', 'WI.W', 
                        'AW.WI.MN', 'AW.WI.MD', 'AW.WI.SV', 'AW.WI.EX']
                },
                tropical: {
                    title: 'Tropical',
                    filter: ['in', 'VTEC', 'TC.S', 'TR.S', 'TR.W', 'TR.A', 'HF.W', 'HF.A', 'HU.S', 'HU.W', 'HU.A']
                },
                winter: {
                    title: 'Winter',
                    filter: ['in', 'VTEC', 'AR.W', 'AVW', 'AVA', 'AV.Y', 'BZ.W', 'BS.Y', 'EC.W', 'EC.A', 'ZL.Y', 'ZF.Y', 'ZR.W', 
                        'ZY.Y', 'UP.W', 'UP.A', 'IS.W', 'LE.W', 'LW.Y', 'SQ.W', 'SQ.A', 'SB.Y', 'SN.W', 'WC.Y', 'WC.W', 'WC.A', 
                        'WS.W', 'WS.A', 'LE.A', 'BZ.A', 'WW.Y', 'LE.Y', 'ZR.Y', 'AW.SI.MN', 'AW.SI.MD', 'AW.SI.SV', 'AW.SI.EX', 
                        'AW.AV.MN', 'AW.AV.MD', 'AW.AV.SV', 'AW.AV.EX', 'AW.LT.MN', 'AW.LT.MD', 'AW.LT.SV', 'AW.LT.EX']
                },
                freeze: {
                    title: 'Freeze',
                    filter: ['in', 'VTEC', 'FE.W', 'FZ.W', 'FZ.A', 'HZ.W', 'HZ.A', 'AW.LT.MN', 'AW.LT.MD', 'AW.LT.SV', 'AW.LT.EX']
                }
            }
 
            // Add the categories to the select dropdown
            const categorySelect = document.querySelector('#category');
            Object.keys(categories).forEach((key) => {
                const option = document.createElement('option');
                option.value = key;
                option.textContent = categories[key].title;
                categorySelect.appendChild(option);
            });
 
            // Layer filters can only be applied when the layer is created, so we need to remove and re-add the 
            // `alerts` layer when the category changes
            const showAlerts = (category) => {
                controller.removeWeatherLayer('alerts');
                controller.addWeatherLayer('alerts', {
                    filter: category === 'all' ? [] : categories[category].filter
                });
            }
            
            controller.on('load', () => {
 
                // Update the alerts layer when the category changes
                categorySelect.addEventListener('change', (e) => {
                    showAlerts(e.target.value);
                });
 
                // Show all alerts by default
                showAlerts(categorySelect.value);
 
            });
        });
 
    </script>
</body>
</html>