Managing Map Data Sources

A weather map can display a variety of different weather data sources at once, such as radar, satellite, earthquakes and storm cells. You can complete control over which data sources appear on your weather map and can add or remove them at any time.

Data Source Types

There are three primary data types for a weather map: raster/tile, point and shape:

  • tile: A raster image or tile layer, such as radar or temperatures.
  • vector: Vector point, polyline and/or polygon data, such as storm reports and convective outlooks.
  • geojson: A vector layer that uses data provided in valid GeoJSON format.
  • text: Data values are rendered as text labels, such as observation elements like temperature or wind speeds.

Using Layer Codes

The interactive weather map has built-in support for automatically creating and managing the various data sources associated with supported layer codes. These layer codes correspond to those currently offered through the AerisWeather Mapping Platform (AMP).

However, point and shape layers are rendered using data from the AerisWeather API instead of AMP raster imagery which considerably reduces the number of map units consumed by your weather map. For example, stormcells and stormreports layers will use API data instead of AMP imagery on a weather map.

Data Source Types for Layer Codes

The following tables indicate which layer codes are rendered as point, shape or text layers using API data. All other layer codes will use AerisWeather Mapping Platform (AMP) raster layers:

Layer Type
air-quality vector
convective vector
drought-monitor vector
earthquakes vector
fires vector
fire-outlook vector
observations text
records vector
river-observations vector
stormcells vector
stormreports vector
tropical-cyclones vector

You can override the default data source type used for a particular layer code by providing a different value for type in the layer options when calling addLayer():

map.addLayer('stormcells', {
    type: 'tile'
});

The above would then render stormcells using the AMP raster tile layer instead of requesting data from the AerisWeather API and rendering the result as markers. The downside to rendering point data as raster tiles is they will not be interactive, meaning you won’t be able to select a marker to reveal the callout with additional details for that item.

Adding Layers

To add a layer to your map, just use addLayer():

map.addLayer('radar');

You can also add multiple layers at once using addLayers():

map.addLayers(['satellite','radar','stormreports']);

When adding layers with their code, you can also provide additional configuration options for the layer as the second parameter to addLayer(). This should be an object containing values for one or all of the following options depending on the type of layer you’re adding (e.g. tile or vector).

Changing the Layer Type

For instance, if you wanted to show storm cells on the map using raster AMP layers instead of as a point data source, you can specify the type value to override the default source type to use:

map.addLayer('stormcells', {
    type: 'tile'
});

Note that not all layer codes support different content source types.

Adding Raster Layers

Raster layers are added to the map as tiles. By default, tile data is dependent upon the parent map’s current timeline position and will update as the timeline is scrubbed or animated. However, you can specify a specific date/time or time offset when adding a layer by providing custom configuration options.

Raster Layer Options

Option Type Description  
type string Type of content source to use if supported by the layer. Supports tile, point or shape.  
style RasterStyle Style configuration to use when rendering the layer on the map. Refer to the styling guide for more details and configuration options.  
time Date or number The timestamp to use for the source data, either as a Date or Epoch time in milliseconds. This value will be ignored if offset is also defined.  
offset number or string Time offset to use for the layer’s data. If an offset is defined, then the layer will only display data for that time interval regardless of the global timeline time interval and its animation will be disabled.  
alwaysShow boolean Whether this tile source should always be visible regardless of past or future state. Default value is false.  
animation AnimationOptions Animation options for the layer. Not all options will be used for a specific layer since its animation is managed by the global map timeline.  

Controlling Raster Layer Order

Some raster tile layers should always appear above or below other layers. When adding layers using addLayer() without a custom RasterStyle configuration, the layer will always be added on top of all other layers. However, you may want the layer to be inserted at a particular index or at the bottom of the stack.

To control the order in which the layer will be inserted, include a custom RasterStyle with your call to addLayer() that specifies the desired z-index of the layer. If the specified z-index value is higher than the total number of layers currently on the map, then the layer will be added to the top of the stack instead.

map.addLayer('satellite', {
    style: {
        zIndex: 1
    }
});

Some third-party mapping libraries allow you to insert layers relative to the map’s own layers, such as Mapbox GL. If you’re using one of these mapping strategies, you can also specify which layer your weather layer should be inserted under. For instance, the following would add the satellite layer underneath the Mapbox layer whose identifier is national_parks:

map.addLayer('satellite', {
    style: {
        belowLayer: 'national_park'
    }
});

You can also change a layer’s stacking order after it’s been added to the map by using either bringLayerToFront(), sendLayerToBack(), or setLayerOrder():

// sends the existing satellite layer behind all other weather layers
map.sendLayerToBack('satellite');

// brings the existing radar layer above all other weather layers
map.bringLayerToFront('radar');

// move the existing alerts layer to third position in the stack of existing weather layers
// z-index positions are zero-based, meaning `0` is the bottom position
map.setLayerOrder('alerts', 2);

Note that using any of the above methods for changing layer ordering will not also add the layer to the map if it does not exist. They only affect existing weather layers. You will still need to add the layer beforehand using addLayer() or the map’s initial configuration.

Using AMP Valid Times

By default, our AerisWeather Mapping Platform (AMP) will automatically redirect requests to the appropriate valid time for the dataset. However, you may need to access the valid times directly in your own applications, such as performing animations for exact valid times in the dataset.

The layerInfo instance on InteractiveMap provides a validTimes property that you can use for fetching the valid times associated with a specific AMP layer. This is just an instance of LayerTimes that provides two methods for fetching a layer’s valid times: times() and timesInRange().

You can fetch the latest valid times for a layer:

map.layerInfo.validTimes.times('radar', 20).then((times) => {
    // do something with times...
});

Or, you can fetch the valid times within a specific date range:

const from = map.timeline.startDate();
const to = map.timeline.endDate();
map.layerInfo.validTimes.timesInRange('radar', from, to, 300).then((times) => {
    // do something with times...
});

If you want to ensure only valid times are using during a layer’s animation, you can also force that layer’s datasource animation to use a static set of times you provide:

const source = app.map.getSourceForLayer('radar');
if (source && source.animation) {
    const from = map.timeline.startDate();
    const to = map.timeline.endDate();
    
    // set the layer's animation intervals to exact valid times instead of auto-calculating
    app.map.layerInfo.validTimes.timesInRange('radar', from, to, 300).then((times) => {
        const intervals = 10;
        const every = Math.ceil(times.length / intervals);
        source.animation.setTimes(times, every);
    });

    // get the actual time for each interval during animation playback, such as displaying 
    // in the interface alongside the layer control
    source.animation.on('advance:image', (e) => {
        const { time } = e.data || {};
        console.log(new Date(time));
    });
}

Note, however, you will need to use the above code each time you need to update the layer’s animation data, such as when map data refreshes or the global timeline range changes.

If you want to revert a layer’s animation to use the default method of auto-calculating interval times, just set the animation times to a null value:

const source = app.map.getSourceForLayer('radar');
if (source && source.animation) {
    source.animation.setTimes(null);
}

Adding Vector Layers

Vector layers are added to the map as markers and/or polylines and polygons. By default, a vector layer will request data from its configured source based on the global timeline’s date range. However, you can configure different behavior using the various layer data options described below.

Vector Layer Options

Option Type Description  
type string Type of content source to use, if supported by the layer. Supports tile, point or shape.  
style VectorStyle Style configuration to use when rendering the layer on the map. Refer to the styling guide for more details and configuration options.  
data object Provides the data-related configuration options for the layer.  
data.request object Request options for vector layers.  
data.request.endpoint string API endpoint to use for the request.  
data.request.action string API action to use for the request. Default value is within for point content sources and search for shape content sources.  
data.request.parameters object Defines the request parameters to use when requesting data for the layer.  
data.url string or Function The URL string to request data from for the data source. Value may be a function that receives information about the map, such as current coordinate bounds, to format a URL string before returning.  
data.items array An array of records to display on the map. If this value is provided, then data will not be requested from a remote source.  
data.properties object Data key-path configuration for property values.  
data.properties.id string Property key path to use for each object’s identifier.  
data.properties.root string Key path to the root of the node containing the array of data elements (e.g. features). If not provided, then the root node is assumed to contain the array of data elements.  
data.properties.category string Property key path to use for an object’s category or grouping, if any.  
data.properties.timestamp string Defines the key path of the property to use for a model object’s time value.  
data.properties.value string Defines the key path of the property to use for a model object’s displayed value.  
data.properties.points string or string[] Property key path that contains the point/coordinate data for the layer. This value can also be an array of key paths, in which case the points will be combined when rendering the data source’s points on the map.  
data.properties.path string Property key path to use for the object’s coordinate path that defines the shape. If the value of this property is an array, then multiple paths will be rendered on the map for the model.  
data.formatter Function An optional formatter function that can be used to format layer data before being processed for rendering on the map. This function receives the entire dataset loaded for the layer and should return the formatted data to use when rendering map elements.  
data.coordinate Function A function that returns the geographical coordinate based on the model object.  
data.geometry Function A function that returns the shape’s GeoJSON geometry based on the model object.  
data.reversedCoords boolean A Boolean indicating whether the data’s coordinate arrays are reversed from the GeoJSON standard (e.g. [lat, lon] instead of the default of [lon, lat]).  
animation AnimationOptions Animation options for the layer. Not all options will be used for a specific layer since its animation is managed by the global map timeline.  
refresh number Data auto-update interval, in seconds. Default value is 0, which disables auto-updating.  

Changing the Request Parameters

Since point, shape and text data sources request their data from the AerisWeather API instead of rendering static raster imagery, it uses an ApiRequest object to setup and perform the request internally.

Each layer will setup the default request parameters to use for its request, but you can also override these default values when you add these layers to the map. Just provide your custom API request parameters as an object assigned to the request.parameters property of your layer options object:

map.addLayer('stormcells', {
    data: {
        request: {
            parameters: {
                filter: 'tornado'
            }
        }
    }
});

Note You will not be able to override certain API request parameters for point, shape and text data sources since they are controlled by the visible map bounds and timeline start and end range. These parameters include: from, to, p, and limit.

Adding Text Layers

For text layers, such as observations, you also need to provide the property key paths that correspond to the time and the value you want to display from the data returned by an API request. You specify these key paths using the time and value properties within the request.property object of your layer options object when adding a layer.

For instance, the following will display the current temperature as text using the value key path of periods.ob.tempF whose valid time is defined by the property at key path periods.ob.timestamp for each object in the API response:

map.addLayer('observations', {
    data: {
        properties: {
            timestamp: 'periods.ob.timestamp',
            value: 'periods.ob.tempF'
        }
    }
});

The time key path should always be the same value regardless of the value for value. To change the value that gets rendered to the map, just use a different key path for value:

map.addLayer('observations', {
    data: {
        properties: {
            timestamp: 'periods.ob.timestamp',
            value: 'periods.ob.windSpeedMPH'
        }
    }
});

The value property also accepts a callback function that can be used to format and return the value that gets rendered on the map instead of using a key path. This callback will receive the model’s data as an argument, allowing you to access the complete model data when formatting the label’s value for the map.

The following configuration would render a stormreports layer for only snow-related reports as text instead of points and outputs the snow total value to the map:

map.addLayer('stormreports', {
    type: 'text',
    data: {
        request: {
            parameters: {
                filter: 'snow'
            }
        },
        properties: {
            timestamp: 'report.timestamp',
            value: (data) => {
                const { report: { detail: { snowIN: val }}} = data;
                if (val) {
                    return val.toFixed(1);
                }
                return null;
            }
        }
    }
});

Removing Layers

Removing layers from the map is similar to adding them. To remove a layer from your map, just use removeLayer():

map.removeLayer('radar');

You can also remove multiple layers at once using removeLayers():

map.removeLayers(['satellite','stormreports']);

Last modified: February 05, 2021