Terrain Viewer

Dataset indexes and release-hosted assets

The elevation datasets the library streams from other people's buckets, the index each one needs (an upstream VRT, a VRT built here and kept on a GitHub release, a small committed ledger, or none), their resolution, extent and size, how to open the same indexes in QGIS or GDAL, and the releases that hold what the repository does not

The terrain library streams most of its datasets straight from the bucket of whoever publishes them: nothing is re-hosted. What a dataset needs in order to be streamed is an index, something that says which file covers which ground. This page lists the indexes the library relies on, where each one lives, and how heavy it is. Every one of them is plain GDAL material, so the same URL opens in QGIS, gdalinfo or titiler.

Four kinds of index

KindWhenWhere it livesExamples
Upstream VRTThe publisher ships a VRT over its COGsTheir bucketOpenTopography's global and regional mosaics
Hosted VRTOne CRS, thousands of COGs, no VRT upstreamThe dataset-indexes release, served by this site at /vrt/Scotland LiDAR
Hosted footprintsWhere a provider has data, as GeoJSON for the coverage overlaysSame release, served at /coverage/Bing, Google and Esri 3D, FLAI, OpenTopography
Committed ledgerMany CRS, so no single VRT can exist; a small list of what covers wherepublic/ in the repositoryOpen Buildings 2.5D (80 KB)
NoneThe file address follows from the coordinatesNowhereGEM-15

The last two are read by a per-tile router rather than as one VRT, see Cell-routed sources.

The datasets

All of these are read in the browser by the app's own readers (vrt://, see VRT Mosaic Protocol): range requests against the publisher's bucket, reprojection with proj4, no server in between. titiler is an option for each (the source's "always via titiler" switch, or the global COG protocol setting), never a requirement, with two exceptions noted in the last column. Open one in the app with ?terrainSourceA=<id>.

DatasetLibrary idResolutionExtentIndexSourcesReader
Copernicus GLO-30 DSMcustom-global-cop3030 mGlobal, 90°S to 84°NUpstream VRT, 11.7 MB26 475Browser
NASADEMcustom-global-nasadem30 m56°S to 61°NUpstream VRT, 6.5 MB14 520Browser
SRTM GL1custom-global-srtm-gl130 m56°S to 60°NUpstream VRT, 6.2 MB14 280Browser
JAXA AW3D30custom-global-aw3d3030 m82°S to 82°NUpstream VRT, 10.1 MB23 997Browser
GEDTM30 (OpenGeoHub)custom-gedtm30-vrt30 mGlobal, 65°S to 85°NUpstream VRT, 1 KB1Browser
EU DTM (OpenGeoHub)custom-eu-dtm3030 mEurope, ETRS89 LAEAUpstream VRT, 2 KB1Browser
SRTM15+ V2.6, with bathymetrycustom-global-srtm15plus15″, about 450 mPole to poleUpstream VRT, 41 KB91Browser
Google GEM-15 DTMcustom-global-gem15-dtm15 m60°S to 84°N, minus Russia, China, Mongolia, GreenlandNone (cell address)13 485 cellsBrowser
Google GEM-15 DSMcustom-global-gem15-dsm15 mSameNone (cell address)13 485 cellsBrowser, slow (5-band files); titiler by choice
Google Open Buildings 2.5D, 2016 to 2023custom-global-openbuildings-<year>0.5 mGlobal South, 57°S to 38°NCommitted ledger, 80 KB for all yearsAbout 620 000 COGs a year in 150 manifestsBrowser only
Scotland LiDAR DTMcustom-uk-scotland-dtm0.5 mScotland, 54.5°N to 60.2°NHosted VRT, 3.8 MB7 300Browser
Scotland LiDAR DSMcustom-uk-scotland-dsm0.5 mSameHosted VRT, 3.8 MB7 360Browser
Scotland LiDAR, every campaigncustom-uk-scotland-dtm-all, -dsm-all0.5 to 1 mSameHosted VRT, 4.9 MB each9 600titiler (files without overviews)

The 30 m global models are not interchangeable, which is why several are listed. SRTM GL1 is the Shuttle radar mission of February 2000 as first released. NASADEM is NASA's 2020 reprocessing of the same radar data: better phase unwrapping, ICESat control points, voids filled from ASTER and AW3D30, so it is the cleaner picture of the year 2000. GLO-30 is a different radar a decade later (TanDEM-X, 2011 to 2015) and AW3D30 is optical stereo (ALOS, 2006 to 2011). Differencing any two shows either real change or the sensors disagreeing. The coarser 90 m editions (COP90, SRTM GL3) are left out: the same data, resampled.

Scotland: a VRT built once, served from a release

Scotland's open LiDAR (Scottish Remote Sensing Portal, OGL v3) is about 9 600 gridded Float32 COGs per product (DTM and DSM) on an open S3 bucket with CORS and Range: the LiDAR phases 1 to 6 of 2011-2022 (1 m for phases 1 and 2, 0.5 m after), the National LiDAR Programme 2021-2024 (1 km tiles at 0.5 m, 5 994 of them), Orkney 2023 and the Outer Hebrides 2019. The portal's WCS is disabled and its WMS is 8-bit, so a VRT is the only way to the raw heights. There is no listing of extents and the phase 1 files are irregular (a 10 km square can be a 6 000 × 3 000 strip), so docs/scripts/build-scotland-vrt.mjs reads every file's header once, 24 in flight, about five minutes a product, and writes one VRT per product in EPSG:27700 at 0.5 m with the newest campaign painted last.

Files without overviews (phases 1 and 2, all of Orkney, 56 NLP files) are a problem for the in-browser reader, which refuses a tile that would decode more than 8 Mpx of one file, so the script writes two VRTs per product: scotland-dtm-overviews.vrt for the browser, scotland-dtm.vrt with every file for titiler.

Asset on dataset-indexesSizeSourcesRaster
scotland-dtm.vrt4.9 MB9 604716 042 × 1 245 728 px at 0.5 m, EPSG:27700
scotland-dtm-overviews.vrt3.8 MB7 305Same grid
scotland-dsm.vrt5.0 MB9 684Same grid
scotland-dsm-overviews.vrt3.8 MB7 360Same grid

pnpm build fetches the files datasets.lock.json names from that release into public/vrt/, and Vite copies them into the build, so the library entries read them from this site: a release asset itself sends no CORS header, the site does, and titiler reads the site too. Any future index too large to commit goes the same way: build once, pnpm datasets:push <file>, commit the lock.

The same indexes in QGIS and GDAL

A VRT over remote COGs is a GDAL dataset. Add it in QGIS as a raster layer with the protocol HTTP(S) and the URL, or on the command line with /vsicurl/:

gdalinfo /vsicurl/https://terrain-viewer.iconem.com/vrt/scotland-dtm.vrt
gdalinfo /vsicurl/https://opentopography.s3.sdsc.edu/raster/COP30/COP30_hh.vrt
# a window of Glasgow as a GeoTIFF, 1 m
gdal_translate -projwin 255000 668000 262000 662000 -tr 1 1 /vsicurl/https://terrain-viewer.iconem.com/vrt/scotland-dtm.vrt glasgow.tif

GEM-15 and Open Buildings have no single file to point GDAL at. A GEM-15 cell is a plain COG (/vsicurl/https://storage.googleapis.com/climate-and-sustainability/gem-15/p40_p0/w5s45/dtm/zall/mosaic.tif), and gdalbuildvrt over the cells of one UTM zone makes a local mosaic.

CRS definitions

A VRT names its CRS, usually as an EPSG code, and the reader needs a proj4 definition for it. Three sources answer, in order: a small table of the codes the library uses where the datum shift matters (British National Grid, Lambert-93, LAEA Europe, RD New and a few more, with their Helmert parameters) and the UTM zones, which follow from the code; then the whole EPSG registry as WKT2, bundled with the app as a 309 KB gzipped file (@developmentseed/epsg), loaded on first need, so an unusual code works offline and in the desktop app; then epsg.io. The table exists because of two traps: epsg.io's string for EPSG:27700 names a grid-shift file proj4js cannot load (every transform came back undefined, the Scotland VRTs drew nothing), and a WKT2 definition carries no datum shift, which proj4js makes up for only for the datums it knows by name (RD New lands 169 m off without its Helmert parameters).

Releases that hold what the repository does not

The built indexes sit on the dataset-indexes release, 17 MB, with the coverage footprints, 6 MB; the build fetches both. The other releases (desktop bundles, docs screenshots, slide decks, demo screencasts, UX flow captures), who writes each and who reads it, are on Releases.

On this page