nst-guide / web

Mapping website for National Scenic Trails

Home Page:https://nst.guide

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to load cached terrain data

kylebarron opened this issue · comments

You can get the existing already-loaded tiles from a map with:

map.style.sourceCaches["terrain-rgb"]._tiles[205673580].dem.data
  • map is the map object (InteractiveMap.getMap() from react-map-gl)
  • style contains everything loaded for the current map style, including map tile data, fonts, sprites, etc
  • sourceCaches is an object where the keys are the ids of loaded sources and the values hold cached data. This even contains data for sources added on top of the style (any that are rendered by Mapbox GL JS), e.g. for me I see the Halfmile track and National Parks boundaries, since I'm using Mapbox GL to render those, while other layers that are rendered by Deck.GL aren't shown because Mapbox isn't aware of them
  • 'terrain-rgb' is the id I give to the Terrain RGB tiles in the style JSON that I'm using for the hillshade
  • _tiles has lower-level data about each tile in the cache. From inspection, I see 4 objects, which would make it seem like those 4 are the 4 that are currently shown in the viewport.
  • 205673580 is one of the four id's in the cache. I'm not sure how this id is formed, but it's probably related to the tile's xyz position. This tile has z=12, x=675, y=1569 (which is found in tileID.canonical.{x,y,z}). It looks like the definition of the tile ID is here. Also of interest here is .neighboringTiles, which is an array of 8 objects, the 8 tiles that touch the current tile. Note that again, these tiles use the same ID numbering system as above.
  • dem an object with information about the tiles, namely its pixel dimensions and "stride", here 512 and 514 respectively
  • data, an array with 264196 UInt32 values. 264196 is 514^2, so presumably this includes one pixel on each side that's backfilled with the neighboring tile.

An example value of the data array is 4279282433. That in hex is FF10AB01. I'm not sure why but this is backwards: ABGR instead of RGBA?? so A=FF, B=10, G=AB, R=01, so in decimal, R=1, G=171, B=16, so:

height = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)
height = 932.8 meters or 3060 feet

That matches up with the contour lines in the area.

So a general process for getting the DEM of the entire current viewport is:

  1. Determine which xyz tiles intersect the current viewport at the desired zoom level. I.e. even when zoomed out, you could theoretically request the terrain tiles at zoom 12, the max zoom, but that would probably take a lot of requests. If you request the tiles for the existing zoom level, it's more likely that they'll be in the existing cache.
  2. Find the tileID for the desired xyz tiles to check if they're in the cache.
  3. If not in cache, request those xyz tiles specifically.
  4. Use loaded DEM