Skip to main content

Tiles: Map Tiles API

The Tiles API is a standard of the Open Geospatial Consortium (OGC).

OGC API - Tiles specifies a standard for Web APIs that provide tiles of geospatial information.

References

These are links to the OGC standards and websites:

This implementation provides an implementation of the OGC API - Tiles Core conformance class, allowing users to access map tiles given a dataset and projection.

Activating Tiles for Arraylake Datasets

The Tiles API can be activated using the Arraylake command line interface (CLI)

al compute enable {org} tiles
note

Arraylake currently only supports enabling Tiles on an organization-wide basis. This is subject to change in future releases.

The Tiles service works best when datasets are compliant with CF Conventions, particularly around coordinates. Specifically it looks for the CRS in a grid_mapping variable (or falls back to a variable named spatial_ref or crs if a grid mapping variable is not detected). If neither of these are present, we assume the CRS to be EPSG:4326. If a project CRS is detected, we search for projected X and Y coordinates (those with the standard_name attribute set as projection_x_coordinate and projection_y_coordinate). If a geographic CRS is detected, we search for search for latitude and longitude coordinate variables (those with standard_name attribute set as latitude or longitude or units attribute with degrees_north and degrees_east). If these attributes are present, we attempt to make a best guess using the names of the coordinate variables present. We strongly recommend you annotate your dataset explicitly by adding a grid mapping variable, and the associate coordinate variables with the right standard_name and units attributes.

Building Queries

The root url for accessing the Tiles endpoint is

https://compute.earthmover.io/v1/services/tiles/{org}/{repo}/{branch|commit|tag}/{path/to/group}/tiles

Where

  • {org} is the name of your Arraylake organization
  • {repo} is the name of the Repo
  • {branch|commit|tag} is the branch, commit, or tag within the Repo to use to fulfill the request
  • {path/to/group} is the path to group within the Repo that contains an xarray Dataset

We will refer to this as the {base_url}.

Tileset Metadata Query

Metadata about the available tilesets can be retrieved using the following query:

{base_url}/

The response will contain metadata about the available tilesets for this dataset, including all available tile matrices, styles, variables, and dimensions. Here is an example query and response for the aifs-outputs dataset:

curl https://compute.earthmover.io/v1/services/tiles/earthmover-public/aifs-outputs/main/2025-03-30/06z/tiles/
Response

This response is heavily truncated for brevity.

{
"tilesets": [
{
"title": "Dataset - CDB1GlobalGrid",
"description": "Tiles for Dataset in CDB1GlobalGrid projection",
"dataType": "map",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"tileMatrixSetURI": "http://www.opengis.net/def/tilematrixset/OGC/1.0/CDB1GlobalGrid",
"links": [
{
"href": "./CDB1GlobalGrid",
"rel": "self",
"type": "application/json",
"title": "Tileset metadata for CDB1GlobalGrid"
},
{
"href": "/tileMatrixSets/CDB1GlobalGrid",
"rel": "http://www.opengis.net/def/rel/ogc/1.0/tiling-scheme",
"type": "application/json",
"title": "Definition of CDB1GlobalGrid"
}
],
"tileMatrixSetLimits": [
{
"tileMatrix": "0",
"minTileRow": 0,
"maxTileRow": 0,
"minTileCol": 0,
"maxTileCol": 0
},
{
"tileMatrix": "1",
"minTileRow": 0,
"maxTileRow": 1,
"minTileCol": 0,
"maxTileCol": 1
},
...,
{
"tileMatrix": "18",
"minTileRow": 0,
"maxTileRow": 262143,
"minTileCol": 0,
"maxTileCol": 262143
}
],
"layers": [
{
"id": "100u",
"title": "100u",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=100u",
"rel": "item",
"type": "image/png",
"title": "Tiles for 100u",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "100v",
"title": "100v",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=100v",
"rel": "item",
"type": "image/png",
"title": "Tiles for 100v",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "ro",
"title": "ro",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=ro",
"rel": "item",
"type": "image/png",
"title": "Tiles for ro",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "10u",
"title": "10u",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=10u",
"rel": "item",
"type": "image/png",
"title": "Tiles for 10u",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "10v",
"title": "10v",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=10v",
"rel": "item",
"type": "image/png",
"title": "Tiles for 10v",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "sf",
"title": "sf",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=sf",
"rel": "item",
"type": "image/png",
"title": "Tiles for sf",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "2d",
"title": "2d",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=2d",
"rel": "item",
"type": "image/png",
"title": "Tiles for 2d",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "2t",
"title": "2t",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=2t",
"rel": "item",
"type": "image/png",
"title": "Tiles for 2t",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "skt",
"title": "skt",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=skt",
"rel": "item",
"type": "image/png",
"title": "Tiles for skt",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "cp",
"title": "cp",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=cp",
"rel": "item",
"type": "image/png",
"title": "Tiles for cp",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "hcc",
"title": "hcc",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=hcc",
"rel": "item",
"type": "image/png",
"title": "Tiles for hcc",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "sp",
"title": "sp",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=sp",
"rel": "item",
"type": "image/png",
"title": "Tiles for sp",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "lcc",
"title": "lcc",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=lcc",
"rel": "item",
"type": "image/png",
"title": "Tiles for lcc",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "ssrd",
"title": "ssrd",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=ssrd",
"rel": "item",
"type": "image/png",
"title": "Tiles for ssrd",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "mcc",
"title": "mcc",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=mcc",
"rel": "item",
"type": "image/png",
"title": "Tiles for mcc",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "stl1",
"title": "stl1",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=stl1",
"rel": "item",
"type": "image/png",
"title": "Tiles for stl1",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "msl",
"title": "msl",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=msl",
"rel": "item",
"type": "image/png",
"title": "Tiles for msl",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "stl2",
"title": "stl2",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=stl2",
"rel": "item",
"type": "image/png",
"title": "Tiles for stl2",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "strd",
"title": "strd",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=strd",
"rel": "item",
"type": "image/png",
"title": "Tiles for strd",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "swvl1",
"title": "swvl1",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=swvl1",
"rel": "item",
"type": "image/png",
"title": "Tiles for swvl1",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "tcc",
"title": "tcc",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=tcc",
"rel": "item",
"type": "image/png",
"title": "Tiles for tcc",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "swvl2",
"title": "swvl2",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=swvl2",
"rel": "item",
"type": "image/png",
"title": "Tiles for swvl2",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "tcw",
"title": "tcw",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=tcw",
"rel": "item",
"type": "image/png",
"title": "Tiles for tcw",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "tp",
"title": "tp",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
"boundingBox": {
"lowerLeft": [0, -90],
"upperRight": [360, 90],
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
},
"links": [
{
"href": "./CDB1GlobalGrid/{tileMatrix}/{tileRow}/{tileCol}?variables=tp",
"rel": "item",
"type": "image/png",
"title": "Tiles for tp",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
}
],
"mediaTypes": [
"image/png",
"image/jpeg"
],
"styles": [
{
"id": "raster/default",
"title": "Raster - Default (Viridis)",
"description": "Default raster rendering (alias for viridis)"
},
{
"id": "raster/Accent",
"title": "Raster - Accent",
"description": "Raster rendering using Accent colormap"
},
...,
{
"id": "raster/winter",
"title": "Raster - Winter",
"description": "Raster rendering using winter colormap"
}
]
},
{
"title": "Dataset - CanadianNAD83_LCC",
"description": "Tiles for Dataset in CanadianNAD83_LCC projection",
"dataType": "map",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"tileMatrixSetURI": "http://www.opengis.net/def/tilematrixset/OGC/1.0/CanadianNAD83_LCC",
"links": [
{
"href": "./CanadianNAD83_LCC",
"rel": "self",
"type": "application/json",
"title": "Tileset metadata for CanadianNAD83_LCC"
},
{
"href": "/tileMatrixSets/CanadianNAD83_LCC",
"rel": "http://www.opengis.net/def/rel/ogc/1.0/tiling-scheme",
"type": "application/json",
"title": "Definition of CanadianNAD83_LCC"
}
],
"tileMatrixSetLimits": [
{
"tileMatrix": "0",
"minTileRow": 0,
"maxTileRow": 0,
"minTileCol": 0,
"maxTileCol": 0
},
{
"tileMatrix": "1",
"minTileRow": 0,
"maxTileRow": 1,
"minTileCol": 0,
"maxTileCol": 1
},
{
"tileMatrix": "2",
"minTileRow": 0,
"maxTileRow": 3,
"minTileCol": 0,
"maxTileCol": 3
},
{
"tileMatrix": "3",
"minTileRow": 0,
"maxTileRow": 7,
"minTileCol": 0,
"maxTileCol": 7
},
{
"tileMatrix": "4",
"minTileRow": 0,
"maxTileRow": 15,
"minTileCol": 0,
"maxTileCol": 15
},
{
"tileMatrix": "5",
"minTileRow": 0,
"maxTileRow": 31,
"minTileCol": 0,
"maxTileCol": 31
},
{
"tileMatrix": "6",
"minTileRow": 0,
"maxTileRow": 63,
"minTileCol": 0,
"maxTileCol": 63
},
{
"tileMatrix": "7",
"minTileRow": 0,
"maxTileRow": 127,
"minTileCol": 0,
"maxTileCol": 127
},
{
"tileMatrix": "8",
"minTileRow": 0,
"maxTileRow": 255,
"minTileCol": 0,
"maxTileCol": 255
},
{
"tileMatrix": "9",
"minTileRow": 0,
"maxTileRow": 511,
"minTileCol": 0,
"maxTileCol": 511
},
{
"tileMatrix": "10",
"minTileRow": 0,
"maxTileRow": 1023,
"minTileCol": 0,
"maxTileCol": 1023
},
{
"tileMatrix": "11",
"minTileRow": 0,
"maxTileRow": 2047,
"minTileCol": 0,
"maxTileCol": 2047
},
{
"tileMatrix": "12",
"minTileRow": 0,
"maxTileRow": 4095,
"minTileCol": 0,
"maxTileCol": 4095
},
{
"tileMatrix": "13",
"minTileRow": 0,
"maxTileRow": 8191,
"minTileCol": 0,
"maxTileCol": 8191
},
{
"tileMatrix": "14",
"minTileRow": 0,
"maxTileRow": 16383,
"minTileCol": 0,
"maxTileCol": 16383
},
{
"tileMatrix": "15",
"minTileRow": 0,
"maxTileRow": 32767,
"minTileCol": 0,
"maxTileCol": 32767
},
{
"tileMatrix": "16",
"minTileRow": 0,
"maxTileRow": 65535,
"minTileCol": 0,
"maxTileCol": 65535
},
{
"tileMatrix": "17",
"minTileRow": 0,
"maxTileRow": 131071,
"minTileCol": 0,
"maxTileCol": 131071
},
{
"tileMatrix": "18",
"minTileRow": 0,
"maxTileRow": 262143,
"minTileCol": 0,
"maxTileCol": 262143
}
],
"layers": [
{
"id": "100u",
"title": "100u",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=100u",
"rel": "item",
"type": "image/png",
"title": "Tiles for 100u",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "100v",
"title": "100v",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=100v",
"rel": "item",
"type": "image/png",
"title": "Tiles for 100v",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "ro",
"title": "ro",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=ro",
"rel": "item",
"type": "image/png",
"title": "Tiles for ro",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "10u",
"title": "10u",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=10u",
"rel": "item",
"type": "image/png",
"title": "Tiles for 10u",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "10v",
"title": "10v",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=10v",
"rel": "item",
"type": "image/png",
"title": "Tiles for 10v",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "sf",
"title": "sf",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=sf",
"rel": "item",
"type": "image/png",
"title": "Tiles for sf",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "2d",
"title": "2d",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=2d",
"rel": "item",
"type": "image/png",
"title": "Tiles for 2d",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "2t",
"title": "2t",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=2t",
"rel": "item",
"type": "image/png",
"title": "Tiles for 2t",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "skt",
"title": "skt",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=skt",
"rel": "item",
"type": "image/png",
"title": "Tiles for skt",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "cp",
"title": "cp",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=cp",
"rel": "item",
"type": "image/png",
"title": "Tiles for cp",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
{
"id": "hcc",
"title": "hcc",
"description": "",
"dataType": "coverage",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978",
"boundingBox": {
"lowerLeft": [0, -4622774.39843718],
"upperRight": [119882454.235076, 4654175.26434244],
"crs": "http://www.opengis.net/def/crs/EPSG/0/3978"
},
"links": [
{
"href": "./CanadianNAD83_LCC/{tileMatrix}/{tileRow}/{tileCol}?variables=hcc",
"rel": "item",
"type": "image/png",
"title": "Tiles for hcc",
"templated": true
}
],
"extents": {
"valid_time": {
"interval": [
"2025-03-30T12:00:00Z",
"2025-04-01T06:00:00Z"
],
"resolution": "PT6H",
"default": "2025-03-30T12:00:00Z"
}
}
},
...
]
}

Tile Matrix Metadata Query

Metadata about the available tile matrices can be retrieved using the following query:

{base_url}/{tile_matrix}/

The response will contain metadata about the available tile matrices for this tileset. Here is an example query and response for the GFS dataset and the WebMercatorQuad tile matrix:

curl https://compute.earthmover.io/v1/services/tiles/earthmover-public/noaa-gfs-forecast/main/tiles/WebMercatorQuad/
Response:

The full styles have been truncated for brevity.

    {
"title": "Dataset - WebMercatorQuad",
"tileMatrixSetURI": "http://www.opengis.net/def/tilematrixset/OGC/1.0/WebMercatorQuad",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"dataType": "map",
"links": [
{
"href": "./WebMercatorQuad/{tileMatrix}/{tileRow}/{tileCol}",
"rel": "item",
"type": "image/png",
"title": "Tile",
"templated": true
},
{
"href": "/tileMatrixSets/WebMercatorQuad",
"rel": "http://www.opengis.net/def/rel/ogc/1.0/tiling-scheme",
"type": "application/json",
"title": "Definition of WebMercatorQuad"
}
],
"styles": [
{
"id": "raster/default",
"title": "Raster - Default (Viridis)",
"description": "Default raster rendering (alias for viridis)"
},
...,
{
"id": "raster/viridis",
"title": "Raster - Viridis",
"description": "Raster rendering using viridis colormap"
},
{
"id": "raster/winter",
"title": "Raster - Winter",
"description": "Raster rendering using winter colormap"
}
],
"attributes": {
"dataset_attrs": {
"description": "GFS data ingested for forecasting demo",
"_xpublish_id": "earthmover-public/noaa-gfs-forecast/main"
},
"variable_attrs": {
"gust": {
"GRIB_paramId": 260065,
"GRIB_dataType": "fc",
"GRIB_numberOfPoints": 1038240,
"GRIB_typeOfLevel": "surface",
"GRIB_stepUnits": 1,
"GRIB_stepType": "instant",
"GRIB_gridType": "regular_ll",
"GRIB_uvRelativeToGrid": 0,
"GRIB_NV": 0,
"GRIB_Nx": 1440,
"GRIB_Ny": 721,
"GRIB_cfName": "unknown",
"GRIB_cfVarName": "gust",
"GRIB_gridDefinitionDescription": "Latitude/longitude. Also called equidistant cylindrical, or Plate Carree",
"GRIB_iDirectionIncrementInDegrees": 0.25,
"GRIB_iScansNegatively": 0,
"GRIB_jDirectionIncrementInDegrees": 0.25,
"GRIB_jPointsAreConsecutive": 0,
"GRIB_jScansPositively": 0,
"GRIB_latitudeOfFirstGridPointInDegrees": 90,
"GRIB_latitudeOfLastGridPointInDegrees": -90,
"GRIB_longitudeOfFirstGridPointInDegrees": 0,
"GRIB_longitudeOfLastGridPointInDegrees": 359.75,
"GRIB_missingValue": 3.4028234663852886e+38,
"GRIB_name": "Wind speed (gust)",
"GRIB_parameterName": "Wind speed (gust)",
"GRIB_parameterUnits": "m s-1",
"GRIB_shapeOfTheEarth": 6,
"GRIB_shortName": "gust",
"GRIB_stepRange": "0",
"GRIB_units": "m s**-1",
"long_name": "Wind speed (gust)",
"units": "m s**-1",
"standard_name": "unknown",
"grid_mapping": "gribfile_projection"
},
"t2m": {
"GRIB_paramId": 167,
"GRIB_dataType": "fc",
"GRIB_numberOfPoints": 1038240,
"GRIB_typeOfLevel": "heightAboveGround",
"GRIB_stepUnits": 1,
"GRIB_stepType": "instant",
"GRIB_gridType": "regular_ll",
"GRIB_uvRelativeToGrid": 0,
"GRIB_NV": 0,
"GRIB_Nx": 1440,
"GRIB_Ny": 721,
"GRIB_cfName": "air_temperature",
"GRIB_cfVarName": "t2m",
"GRIB_gridDefinitionDescription": "Latitude/longitude. Also called equidistant cylindrical, or Plate Carree",
"GRIB_iDirectionIncrementInDegrees": 0.25,
"GRIB_iScansNegatively": 0,
"GRIB_jDirectionIncrementInDegrees": 0.25,
"GRIB_jPointsAreConsecutive": 0,
"GRIB_jScansPositively": 0,
"GRIB_latitudeOfFirstGridPointInDegrees": 90,
"GRIB_latitudeOfLastGridPointInDegrees": -90,
"GRIB_longitudeOfFirstGridPointInDegrees": 0,
"GRIB_longitudeOfLastGridPointInDegrees": 359.75,
"GRIB_missingValue": 3.4028234663852886e+38,
"GRIB_name": "2 metre temperature",
"GRIB_parameterName": "Temperature",
"GRIB_parameterUnits": "K",
"GRIB_shapeOfTheEarth": 6,
"GRIB_shortName": "2t",
"GRIB_stepRange": "0",
"GRIB_units": "K",
"long_name": "2 metre temperature",
"units": "K",
"standard_name": "air_temperature",
"grid_mapping": "gribfile_projection"
},
"tcc": {
"GRIB_paramId": 228164,
"GRIB_dataType": "fc",
"GRIB_numberOfPoints": 1038240,
"GRIB_typeOfLevel": "atmosphere",
"GRIB_stepUnits": 1,
"GRIB_stepType": "instant",
"GRIB_gridType": "regular_ll",
"GRIB_uvRelativeToGrid": 0,
"GRIB_NV": 0,
"GRIB_Nx": 1440,
"GRIB_Ny": 721,
"GRIB_cfName": "unknown",
"GRIB_cfVarName": "tcc",
"GRIB_gridDefinitionDescription": "Latitude/longitude. Also called equidistant cylindrical, or Plate Carree",
"GRIB_iDirectionIncrementInDegrees": 0.25,
"GRIB_iScansNegatively": 0,
"GRIB_jDirectionIncrementInDegrees": 0.25,
"GRIB_jPointsAreConsecutive": 0,
"GRIB_jScansPositively": 0,
"GRIB_latitudeOfFirstGridPointInDegrees": 90,
"GRIB_latitudeOfLastGridPointInDegrees": -90,
"GRIB_longitudeOfFirstGridPointInDegrees": 0,
"GRIB_longitudeOfLastGridPointInDegrees": 359.75,
"GRIB_missingValue": 3.4028234663852886e+38,
"GRIB_name": "Total Cloud Cover",
"GRIB_parameterName": "Total cloud cover",
"GRIB_parameterUnits": "%",
"GRIB_shapeOfTheEarth": 6,
"GRIB_shortName": "tcc",
"GRIB_stepRange": "0",
"GRIB_units": "%",
"long_name": "Total Cloud Cover",
"units": "%",
"standard_name": "unknown",
"grid_mapping": "gribfile_projection"
},
"prate": {
"GRIB_paramId": 3059,
"GRIB_dataType": "fc",
"GRIB_numberOfPoints": 1038240,
"GRIB_typeOfLevel": "surface",
"GRIB_stepUnits": 1,
"GRIB_stepType": "instant",
"GRIB_gridType": "regular_ll",
"GRIB_uvRelativeToGrid": 0,
"GRIB_NV": 0,
"GRIB_Nx": 1440,
"GRIB_Ny": 721,
"GRIB_cfName": "unknown",
"GRIB_cfVarName": "prate",
"GRIB_gridDefinitionDescription": "Latitude/longitude. Also called equidistant cylindrical, or Plate Carree",
"GRIB_iDirectionIncrementInDegrees": 0.25,
"GRIB_iScansNegatively": 0,
"GRIB_jDirectionIncrementInDegrees": 0.25,
"GRIB_jPointsAreConsecutive": 0,
"GRIB_jScansPositively": 0,
"GRIB_latitudeOfFirstGridPointInDegrees": 90,
"GRIB_latitudeOfLastGridPointInDegrees": -90,
"GRIB_longitudeOfFirstGridPointInDegrees": 0,
"GRIB_longitudeOfLastGridPointInDegrees": 359.75,
"GRIB_missingValue": 3.4028234663852886e+38,
"GRIB_name": "Precipitation rate",
"GRIB_parameterName": "Precipitation rate",
"GRIB_parameterUnits": "kg m-2 s-1",
"GRIB_shapeOfTheEarth": 6,
"GRIB_shortName": "prate",
"GRIB_stepRange": "0",
"GRIB_units": "kg m**-2 s**-1",
"long_name": "Precipitation rate",
"units": "kg m**-2 s**-1",
"standard_name": "unknown",
"grid_mapping": "gribfile_projection"
},
"r2": {
"GRIB_paramId": 260242,
"GRIB_dataType": "fc",
"GRIB_numberOfPoints": 1038240,
"GRIB_typeOfLevel": "heightAboveGround",
"GRIB_stepUnits": 1,
"GRIB_stepType": "instant",
"GRIB_gridType": "regular_ll",
"GRIB_uvRelativeToGrid": 0,
"GRIB_NV": 0,
"GRIB_Nx": 1440,
"GRIB_Ny": 721,
"GRIB_cfName": "relative_humidity",
"GRIB_cfVarName": "r2",
"GRIB_gridDefinitionDescription": "Latitude/longitude. Also called equidistant cylindrical, or Plate Carree",
"GRIB_iDirectionIncrementInDegrees": 0.25,
"GRIB_iScansNegatively": 0,
"GRIB_jDirectionIncrementInDegrees": 0.25,
"GRIB_jPointsAreConsecutive": 0,
"GRIB_jScansPositively": 0,
"GRIB_latitudeOfFirstGridPointInDegrees": 90,
"GRIB_latitudeOfLastGridPointInDegrees": -90,
"GRIB_longitudeOfFirstGridPointInDegrees": 0,
"GRIB_longitudeOfLastGridPointInDegrees": 359.75,
"GRIB_missingValue": 3.4028234663852886e+38,
"GRIB_name": "2 metre relative humidity",
"GRIB_parameterName": "Relative humidity",
"GRIB_parameterUnits": "%",
"GRIB_shapeOfTheEarth": 6,
"GRIB_shortName": "2r",
"GRIB_stepRange": "0",
"GRIB_units": "%",
"long_name": "2 metre relative humidity",
"units": "%",
"standard_name": "relative_humidity",
"grid_mapping": "gribfile_projection"
}
}
}
}

Tile Query

This is the core functionality of the service, accessing specific map tiles for a given dataset and projection. Use the following schema:

{base_url}/{tile_matrix}/{z}/{y}/{x}?variables={variable1}&colorscalerange={min},{max}&style={style}&width={width}&height={height}&f=image/png&some_dimension=some_value

The parameters are as follows:

  • {tile_matrix} is the name of the tile matrix to use, usually this will be WebMercatorQuad for web map usage.
  • {z} is the zoom level of the tile
  • {y} is the y coordinate of the tile
  • {x} is the x coordinate of the tile
  • variables is the name of the variable to visualize. For raster style this must be a single variable name and is required.
  • style is the name of the style to use for the tile. Styles are defined as {style_name}/{style_variant}. For example, when using the raster style, variants are matplotlib colormaps. So we can specify the turbo colormap as raster/turbo.
  • colorscalerange is the comma separated minimum and maximum value of the color scale. This is required if valid_min and valid_max are not available as attributes of the queried variable, otherwise it is optional.
  • width is the width of the tile in pixels, this must be a multiple of 256. This is required.
  • height is the height of the tile in pixels, this must be a multiple of 256. This is required.
  • f is the format of the tile. This defaults to image/png if not specified.

Many datasets will have other dimensions such as time, level or band that must be subset to visualize a spatial slice of data. When this is the case, if a dimension is not specified, then the first value of the dimension will be used by default. To specify the dimension value to query, use the some_dimension=some_value syntax. For example, to query a dataset with a time dimension add time=2022-01-01T00:00:00 as a query parameter.

Here is an example tile query for the gust variable from the GFS dataset:

curl https://compute.earthmover.io/v1/services/tiles/earthmover-public/noaa-gfs-forecast/main/tiles/WebMercatorQuad/1/1/1?variables=gust&colorscalerange=0,40&width=512&height=512

GFS Gust Tile

tilejson Query

TileJSON is an open standard for representing map metadata.

To make integration with other tools easier, a tilejson query can be used to retrieve the information about a tileset needed to integrate with web mapping tools such as Mapbox. Use the following schema to generate a tilejson query:

{base_url}/{tile_matrix}/tilejson.json?variables={variable1}&colorscalerange={min},{max}&style={style}&width={width}&height={height}&some_dimension=some_value

The tilejson query is similar to the tile query but returns a JSON object instead of an image. See the Tile Query for the available query parameters, which can be used in the tilejson query.

Here is an example tilejson query for the gust variable from the GFS dataset:

curl https://compute.earthmover.io/v1/services/tiles/earthmover-public/noaa-gfs-forecast/main/tiles/WebMercatorQuad/tilejson.json?variables=gust&colorscalerange=0,40&width=512&height=512

Notice how the service returns minzoom, this allows Flux to let the framework know which tile requests can be satisfied. For relatively high-resolution data, Flux will return appropriately higher zoom levels for minzoom. maxzoom is always the highest zoom level supported by the Tileset as defined in the OGC Tiles standard.

Response
{
"tilejson": "3.0.0",
"tiles": [
"http://compute.earthmover.io/v1/services/tiles/earthmover-public/noaa-gfs-forecast/main/tiles/WebMercatorQuad/{z}/{y}/{x}?variables=gust&style=raster/default&width=512&height=512&f=png"
],
"bounds": [0, -90, 360, 90],
"description": "GFS data ingested for forecasting demo",
"maxzoom": 24,
"minzoom": 0,
"name": "Dataset",
"scheme": "xyz"
}

Legend Query

The legend endpoint returns color scale information for a dataset variable, matching the styling parameters used in tile requests. It supports two output formats: an image (PNG) suitable for embedding in maps, or JSON for building custom legend UI.

{base_url}/tiles/legend?variables={variable}&colorscalerange={min},{max}&style={style}&f={format}&some_dimension=some_value

The parameters are as follows:

  • variables is the name of the variable to generate a legend for. This must match the variable used in the corresponding tile request.
  • style is the style used for rendering, in {style_name}/{style_variant} format (e.g. raster/viridis). Must match the style used in the tile request.
  • colorscalerange is the comma-separated minimum and maximum value of the color scale. Must match the value used in the tile request.
  • belowmincolor is the color to use for values below the minimum of the color scale.
  • abovemaxcolor is the color to use for values above the maximum of the color scale.
  • f controls the output format. Use image/png (default) for a PNG colorbar image, or application/json to receive structured legend data.
  • vertical (image format only) controls colorbar orientation. Defaults to true (vertical).
  • width / height (image format only) set the image dimensions. Defaults are 100×300 for vertical, 400×100 for horizontal.
  • background_color (image format only) sets the background color of the legend image. Accepts transparent, named colors, or hex values.
  • text_color (image format only) sets the color of tick labels and the axis label.
  • label overrides the auto-generated axis label.
  • show_label (image format only) toggles display of the axis label. Defaults to true.

As with tile requests, additional dimension parameters (e.g. time=2022-01-01T00:00:00) can be passed to select a specific slice of the data.

Here are example legend queries for the temperature_2m variable from the GFS dataset.

Image format (f=image/png default)

curl "https://compute.earthmover.io/v1/services/tiles/earthmover-public/noaa-gfs-forecast/main/tiles/legend?variables=temperature_2m&colorscalerange=-30,40&vertical=false"

GFS Temperature Legend

JSON format (f=application/json)

curl "https://compute.earthmover.io/v1/services/tiles/earthmover-public/noaa-gfs-forecast/main/tiles/legend?variables=temperature_2m&colorscalerange=-30,40&f=application/json"
JSON Response (continuous variable)
{
"type": "continuous",
"label": "2 metre temperature",
"units": "°C",
"variant": "default",
"colorscalerange": [-30, 40],
"stops": [
{ "value": -30.0, "color": "#440154" },
{ "value": -29.725, "color": "#450558" },
"..."
],
"abovemaxcolor": null,
"belowmincolor": null
}
JSON Response (discrete/flag variable)

For variables with flag_values and flag_meanings attributes, the legend endpoint returns a discrete response instead:

{
"type": "discrete",
"label": "Land Cover Class",
"units": null,
"items": [
{ "value": 0, "label": "Water", "color": "#1f77b4" },
{ "value": 1, "label": "Forest", "color": "#2ca02c" }
]
}

Integrating with Tools

MapLibre/Mapbox

You can visualize raster tiles in MapLibre (or Mapbox) using by adding a raster source and layer and the tilejson endpoint.

Code
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Flux Tiles Example (MapLibre)</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link href='https://unpkg.com/maplibre-gl@5.9.0/dist/maplibre-gl.css' rel='stylesheet'>
<script src='https://unpkg.com/maplibre-gl@5.9.0/dist/maplibre-gl.js'></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
zoom: 2,
center: [0, 0],
});

map.on('style.load', () => {
map.setProjection({
type: 'globe'
});
map.addSource('gfs-gust-source', {
'type': 'raster',
'url': 'https://compute.earthmover.io/v1/services/tiles/earthmover-public/noaa-gfs-forecast/main/tiles/WebMercatorQuad/tilejson.json?variables=gust&colorscalerange=0,40&width=512&height=512',
'tileSize': 512
});
map.addLayer(
{
'id': 'gfs-gust-layer',
'type': 'raster',
'source': 'gfs-gust-source',
'paint': {}
}
);
});
</script>

</body>
</html>

QGIS

warning

QGIS does not fully support a standards-compliant Tiles layer (upstream issue), so a very specific set of steps is required to get this working. Notably using the menu Layer > Add Layer > New XYZ Layer does not appear to work.

QGIS can be used to visualize raster tiles using an XYZ layer.

  1. Right-Click on XYZ Tiles in the Browser (left sidebar by default) and add a "New Connection".
  2. In the URL box, use the following URL: https://compute.earthmover.io/v1/services/tiles/earthmover-public/noaa-gfs-forecast/main/tiles/WebMercatorQuad/{z}/{y}/{x}?variables=gust&colorscalerange=0,40&width=512&height=512
  3. If your service is not Public, you can also configure Basic Authentication at this step. For convenience, you can also save Basic Authentication credentials in QGIS permanently; these credentials can then be reused for different datasets.
  4. This new XYZ connection can now be added to the project.

Jupyter Notebooks

At the moment, Jupyter notebook plugins for displaying slippy maps do not allow explicitly specify Authorization headers so they only work with public services.

from ipyleaflet import Map, TileLayer

url = (
"https://compute.earthmover.io/v1/services/tiles/"
"earthmover-public/noaa-gfs-forecast/"
"main/solar/tiles/"
"WebMercatorQuad/{z}/{y}/{x}?"
"variables=gust&colorscalerange=0,40&width=512&height=512"
)
m = Map(center=(-21.05, -48.25), zoom=0)
wms = TileLayer(url=url, show_loading=True)
m.add(wms)
m