Figure 3.4 Three twenty levels of web map hierarchy

code
R
extras

The code below retrieves an OSM tile from level 0 all the way down to level 19 for the latitude-longitude coordinates of the Broolyn Wind Turbine in Wellington.

Code
library(sf)
library(dplyr)
library(stringr)

# adapted from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#R
deg2num<-function(lat_deg, lon_deg, zoom){
  lat_rad <- lat_deg * pi /180
  n <- 2.0 ^ zoom
  xtile <- floor((lon_deg + 180.0) / 360.0 * n)
  ytile = floor((1 - (log(tan(lat_rad) + (1 / cos(lat_rad))) / pi)) / 2.0 * n)
  c(xtile, ytile)
}

lon <- 174.74526
lat <- -41.31087

tile_names <- c()
for (zoom in 0:19) {
  xy <- deg2num(lat, lon, zoom)
  tile_name <- str_glue("{zoom}/{xy[1]}/{xy[2]}")
  tile_names <- c(tile_names, tile_name)
  osm_tile_url <- str_glue("https://tile.openstreetmap.org/{tile_name}.png")
  download.file(osm_tile_url, str_glue("tiles/{zoom}.png"), mode = 'wb')
}
df <- data.frame(zoom = 0:19, tile_name = tile_names) |>
  mutate(left = zoom %% 5, bottom = 3 - zoom %/% 5, 
         right = left + 1, top = bottom + 1)

Here they all are (there is probably a better way to do this, but sometimes in R it’s easier just to write the code).

Code
library(png)

par(mai = rep(0, 4))
plot(1, xlim = c(0, 5), ylim = c(0, 4), xlab = "", ylab = "", 
     type = "n", asp = 1, axes = FALSE)

for (i in 1:20) {
  img <- readPNG(str_glue("tiles/{df$zoom[i]}.png"))
  rasterImage(img, df$left[i], df$bottom[i], df$right[i], df$top[i])
}
text(df$left + 0.01, df$bottom + 0.01, df$tile_name, adj = c(0, 0), cex = 0.75)

All tiles © OpenStreetMap contributors, data under the ODbL.

Code
# License (MIT)
#
# Copyright (c) 2023 David O'Sullivan
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to  permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

© 2023-24 David O’Sullivan