Air Quality and Pollen in areas and routes
Objective
Air Quality and Pollen APIs offer great opportunities to add more insights into a trip or map at any given location. There are two ways to consume the data available from those APIs: index as text or heatmap tiles as raster images.
While using the heatmap tiles APIs endpoints, you may face a couple of challenges while loading the individual raster tiles such as:
- how to load the tiles on a Google Map on the Web? (also to comply with the APIs Terms of use)
- how to manage the number of requests during the experience?
- how to read the tiles values?
Sample use cases
You will be presented sample use cases to try to answer the above questions.
- Air Quality & Pollen in an area: visualize heatmap tiles (current conditions) raster data inside one or multiple custom polygons.
- Air Quality & Pollen along route: visualize heatmap tiles (current conditions) raster data mapped on routes waypoints.
Implementation
You will discover what tiles are available and how they can be loaded in a Web experience. You will also see what can be done to manage the number of requests in a scenario where the tiles are loaded onto a map. Finally you will be presented how to read the tiles.
Available heatmap tiles by types
Air Quality API
- UAQI_RED_GREEN (UAQI, red-green palette): Universal Air Quality Index red-green palette.
- UAQI_INDIGO_PERSIAN (UAQI, indigo-persian palette): Universal Air Quality Index indigo-persian palette.
- PM25_INDIGO_PERSIAN: PM2.5 index indigo-persian palette.
- GBR_DEFRA: Daily Air Quality Index (UK) color palette.
- DEU_UBA: German Local Air Quality Index color palette.
- CAN_EC: Canadian Air Quality Health Index color palette.
- FRA_ATMO: France Air Quality Index color palette.
- US_AQI: US Air Quality Index color palette.
Pollen API
- TREE_UP: The heatmap type will represent a tree index graphical map.
- GRASS_UPI: The heatmap type will represent a grass index graphical map.
- WEED_UPI: The heatmap type will represent a weed index graphically map.
Display heatmap tiles in Web
Load the tiles and apply a vector mask to only display desired areas of the map's viewport.
Loading the tiles
- Use Maps JavaScript API to load the Google basemap and load deckgl library to prepare for loading raster tile images.
- Use deck.gl TileLayer to load Air Quality Heatmap tiles. This will display Google Maps basemap labels on top of heatmap tiles (unlike Maps JavaScript custom overlays)
import { TileLayer } from "deck.gl"; import { GoogleMapsOverlay } from "@deck.gl/google-maps"; // const TileLayer = deck.TileLayer; // const GoogleMapsOverlay = deck.GoogleMapsOverlay; // Initialize and add the map function initMap() { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 40, lng: -110 }, zoom: 4, }); const apiKey = 'YOUR_API_KEY'; const airqualityType = 'UAQI_RED_GREEN' // AirQuality API heatmap type const deckOverlay = new GoogleMapsOverlay({ layers: [ // Heatmap Tiles layer new TileLayer({ id: 'heatmap-tiles', data: 'https://airquality.googleapis.com/v1/mapTypes/'+ heatmapType + +'/heatmapTiles/{z}/{x}/{y}?key=' + apiKey, ... }) ], }); deckOverlay.setMap(map); } window.initMap = initMap;
Applying a vector Mask
You can visually hide or show any part of the heatmap tiles. Important: You will need to acquire the data that will be used to create the vector mask applied to the heatmap tiles.
- In an Area:
use deck.gl GeoJson to create a Mask over the Air Quality TileLayer.
The example below is using a multipolygon geojson of France
// geojson sample { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [[[[-54.111527,2.11427],...[-54.194491,2.163073]]]] }, "properties": { "name": "France" } }
Here is a reference for the deckgl implementation:
// Loaded layers in maps overlay const deckOverlay = new GoogleMapsOverlay({ layers: layers }); const MaskExtension = deck.MaskExtension; // or import extension ... // As part of object containing the different layers const layers = [ // Masking layer new GeoJsonLayer({ id: 'country-vector', operation: 'mask', data: "geojson.json", // <-- any custom geometry }) ... ... // Heatmap Tiles layer new TileLayer({ id: 'heatmap-tiles', maskId: 'country-vector', // <-- same as mask id extensions: [new MaskExtension()], // <-- enable mask extension ... }) ]
- Along a Route: Use deck.gl with its TripsLayer to create a Mask over the Air Quality TileLayer
Air Quality heatmap tile over a trip
Manage API requests and cost
While the browser’s default behavior is usually to cache all loaded tiles in local storage (within the same session) you can further optimize:
- Restrict the loading area: create a bounding box (in red) and assign it to the layer, only heatmap tiles (in blue) covering the bounding box will load at any given zoom level
Bounding Box (in red), Heatmap tiles (in blue)
// Heatmap Tile layer new TileLayer({ id: 'heatmap-tiles', extent: [minX, minY, maxX, maxY] // bounding box: southwest lat, southwest lng, northeast lat, northeast lng ... })
- Set visual display tile size to cover the entire viewport at any given zoom level; recommended: between 256 to 1024.
Important: APIs tiles remain at 256x256 resolution but visual display adjustment will allow you to increase/decrease the number of tiles requests to cover the entire map Viewport
(make sure it works with minZoom and maxZoom of the Google Map, ie:
tilesize:1024
will not load tiles at zoom 0 or 1).
Viewport with tiles 256x256 pixels vs 512x512 pixels
// Heatmap Tile layer new TileLayer({ id: 'heatmap-tiles', tilesize:256, // <-- change to 512 for instance ... })
Read pixel values
To display the corresponding value on a color scale
You can use Luma.gl library and its readPixelsToArray method upon an onClick event assigned as prop to the deck.gl layer.
Pixel value: rgba(128,0,0,255)
LOW HIGH
// Uint8Array pixel sample import { readPixelsToArray } from "@luma.gl/core"; ... // assign on the TileLayer new TileLayer({ id: 'heatmap-tiles', ... onClick: ({ bitmap, layer }) => { if (bitmap) { const pixel = readPixelsToArray(layer.props.image, { sourceX: bitmap.pixel[0], sourceY: bitmap.pixel[1], sourceWidth: 1, sourceHeight: 1 }); // console.log("color picked:"+ pixel); } } })
Conclusion
You discovered how Air Quality and Pollen heatmap tiles API endpoints can be:
- loaded on a Google Map in Web also making sure to be inline with the Terms of use
- optimized to match your use case
- read the tiles values
Next Actions
Suggested further reading:
Contributors
Principal authors:
Thomas Anglaret | Google Maps Platform Solutions Engineer