There are some slippy map tile
providers that can serve you tiles that represent Digital Elevation
Model (DEM) data, rather than map imagery. This is the kind of data you
want to make 3D maps with rayshader
or
quadmesh
. Mapbox have an API for DEM tiles called Mapbox
Terrain-RGB that we will use in this example.
Sign up for Mapbox and generate yourself an API access token. For my
testing I have used a ‘public’ token with styles:tiles
. Add
that API token to your .Renviron file (in your home directory) as:
MAPBOX_API_KEY=<YOUR REALLY LONG TOKEN HERE>
How many tiles?
library(slippymath)
tibrogargan<- c(xmin = 152.938485, ymin = -26.93345, xmax = 152.956467,
ymax = -26.921463)
slippymath::bbox_tile_query(tibrogargan)
#> x_min y_min x_max y_max y_dim x_dim total_tiles zoom
#> 1 3 2 3 2 1 1 1 2
#> 2 7 4 7 4 1 1 1 3
#> 3 14 9 14 9 1 1 1 4
#> 4 29 18 29 18 1 1 1 5
#> 5 59 36 59 36 1 1 1 6
#> 6 118 73 118 73 1 1 1 7
#> 7 236 147 236 147 1 1 1 8
#> 8 473 295 473 295 1 1 1 9
#> 9 947 591 947 591 1 1 1 10
#> 10 1894 1183 1894 1183 1 1 1 11
#> 11 3788 2366 3788 2366 1 1 1 12
#> 12 7576 4732 7576 4732 1 1 1 13
#> 13 15152 9464 15153 9465 2 2 4 14
#> 14 30304 18929 30306 18931 3 3 9 15
#> 15 60609 37859 60612 37862 4 4 16 16
#> 16 121219 75719 121225 75724 6 7 42 17
#> 17 242438 151439 242451 151449 11 14 154 18
It’s a small area so we don’t need a lot. 9 tiles as zoom 15 looks good. Let’s get the tile grid.
Now we’ll fetch the tiles from Mapbox.
library(glue)
library(purrr)
library(curl)
mapbox_query_string <-
paste0("https://api.mapbox.com/v4/mapbox.terrain-rgb/{zoom}/{x}/{y}.jpg90",
"?access_token=",
Sys.getenv("MAPBOX_API_KEY"))
tibro_tiles <-
pmap(.l = tibrogargan_grid$tiles,
zoom = tibrogargan_grid$zoom,
.f = function(x, y, zoom){
outfile <- glue("{x}_{y}.jpg")
curl_download(url = glue(mapbox_query_string),
destfile = outfile)
outfile
}
)
We composite the images to raster with compose_tile_grid
and view the raster:
tibrogargan_raster <- slippymath::compose_tile_grid(tibrogargan_grid, tibro_tiles)
raster::plot(tibrogargan_raster)
We see this mix of layers including a psychedelic blue-green RGB
landscape because in terrain-rgb
tiles, the RGB values to
provide additional precision to the elevation information. We’ll decode
this in the next section.
Mapbox provide a formula to decode the RGB values to elevation. This was implemented in the function below by Michael Sumner.
decode_elevation <- function(dat) {
height <- -10000 + ((dat[[1]] * 256 * 256 + dat[[2]] * 256 + dat[[3]]) * 0.1)
raster::projection(height) <- "+proj=merc +a=6378137 +b=6378137"
height
}
When we apply it to tibrogargan_raster
we get:
*ceramic - A
wrapper for quadmesh
+ slippymath
for making
3D surfaces textured with satellite tiles.