library("tidyverse")
library("R.utils")
library("httr")
library("sf")
library("stars")
library("rayshader")
Overview
This is the 3D Italy’s Population Density Map made with the instruction provided by Milos Agathon: Milos Makes Maps
tutorial:
- https://www.youtube.com/watch?v=qTDf5VVnjMM
- https://github.com/milos-agathon/making-crisp-spike-maps-with-r/blob/main/R/create-spike-map-in-r.r
Download and unzip kontur
data:
<-
url "https://geodata-eu-central-1-kontur-public.s3.amazonaws.com/kontur_datasets/kontur_population_IT_20220630.gpkg.gz"
<- "italy-population.gpkg.gz"
file_name
<- function() {
get_population_data <- httr::GET(
res
url,write_disk(file_name),
progress()
)
::gunzip(file_name, remove = F)
R.utils
}
get_population_data()
<- gsub(".gz", "", file_name)
load_file_name <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0" crsLONGLAT
<- function() {
get_population_data <- sf::st_read(
pop_df
load_file_name|>
) ::st_transform(crs = crsLONGLAT)
sf
}
<- get_population_data()
pop_sf
head(pop_sf)
First raw image:
ggplot() +
geom_sf(
data = pop_sf,
color = "grey10", fill = "grey10"
)
# ggsave("raw.png")
Make it a raster
<- sf::st_bbox(pop_sf)
bb
<- function() {
get_raster_size <- sf::st_distance(
height ::st_point(c(bb[["xmin"]], bb[["ymin"]])),
sf::st_point(c(bb[["xmin"]], bb[["ymax"]]))
sf
)<- sf::st_distance(
width ::st_point(c(bb[["xmin"]], bb[["ymin"]])),
sf::st_point(c(bb[["xmax"]], bb[["ymin"]]))
sf
)
if (height > width) {
<- 1
height_ratio <- width / height
width_ratio else {
} <- 1
width_ratio <- height / width
height_ratio
}
return(list(width_ratio, height_ratio))
}<- get_raster_size()[[1]]
width_ratio <- get_raster_size()[[2]]
height_ratio
<- 3000
size <- round((size * width_ratio), 0)
width <- round((size * height_ratio), 0)
height
<- function() {
get_population_raster <- stars::st_rasterize(
pop_rast |>
pop_sf ::select(population, geom),
dplyrnx = width, ny = height
)
return(pop_rast)
}
<- get_population_raster() pop_rast
Second raw image this time as a raster:
plot(pop_rast)
# ggsave("raw2.png")
<- pop_rast |>
pop_mat as("Raster") |>
::raster_to_matrix() rayshader
<- rev(c(
cols "#0b1354", "#283680",
"#6853a9", "#c863b3"
))
<- grDevices::colorRampPalette(cols)(256) texture
Create the initial 3D object
|>
pop_mat ::height_shade(texture = texture) |>
rayshader::plot_3d(
rayshaderheightmap = pop_mat,
solid = F,
soliddepth = 0,
zscale = 15,
shadowdepth = 0,
shadow_darkness = .95,
windowsize = c(800, 800),
phi = 65,
zoom = .65,
theta = -30,
background = "white"
)
Adjust the view after building the window object
::render_camera(phi = 75, zoom = .7, theta = 0)
rayshader
::render_highquality(
rayshaderfilename = "italy_population_2022.png",
preview = T,
light = T,
lightdirection = 225,
lightaltitude = 60,
lightintensity = 400,
interactive = F,
width = width, height = height
)