# Librarieslibrary(ggplot2)library(dplyr)library(sf)library(rvest)library(stringr)library(tibble)library(showtext)library(sysfonts)library(tidyterra)library(geodata)library(ggrepel)library(ggtext)library(ggbranding)library(cols4all)library(janitor)# Get Switzerland raster through raster packagech <-elevation_30s("CH")# Get shades using tidyterraslope <-terrain(ch, "slope", unit ="radians")aspect <-terrain(ch, "aspect", unit ="radians")hill <-shade(slope, aspect, 30, 270)# Scrape tallest structures data from Wikipediaurl <-"https://en.wikipedia.org/wiki/List_of_tallest_structures_in_Switzerland"page <-read_html(url)# Extract the tablebuildings_table <- page |>html_element("table.wikitable") |>html_table()# Clean and prepare databuildings <- buildings_table |>clean_names() |>mutate(# Extract numeric heightheight =str_replace(height, ",", "."),height_m =as.numeric(gsub("[^0-9.]", "", height)),# Extract year (first 4 digits)year =as.numeric(sub("^.*?(\\d{4}).*$", "\\1", year_built)),# Extract coordinates from the coordinates column# Pattern: extract decimal coordinates like "47.5717389°N 7.6869889°E"lat =as.numeric(sub(".*?([0-9.]+)°N.*", "\\1", coordinates)),lon =as.numeric(sub(".*?([0-9.]+)°E.*", "\\1", coordinates)),structure_type =case_when(str_detect(tolower(construction_type_2), "dam") ~"Dam",str_detect(tolower(construction_type_2), "bridge") ~"Bridge",str_detect(tolower(construction_type_2), "wind") ~"Wind Turbine",str_detect(tolower(construction_type_2), "tower|mast|pylon") ~"Tower",str_detect(tolower(construction_type_2),"skyscraper|highrise|building" ) ~"Building",str_detect(tolower(construction_type_2),"chimney|cooling|silo" ) ~"Industrial",str_detect(tolower(construction_type_2),"church|cathedral" ) ~"Religious",.default ="Other" ) ) |>filter(!is.na(height_m), !is.na(lat), !is.na(lon)) |># Convert to sf objectst_as_sf(coords =c("lon", "lat"), crs =4326)# Top 5 buildings by heighttop_buildings <- buildings |>slice_max(height_m, n =5) |>pull(construction_type)
# Fontsshowtext_auto()showtext_opts(dpi =600)font_add_google("Lato", "main")# brandingbranding <-branding(additional_text ="Data: Wikipedia | Day 06 - Dimensions of #30DayMapChallenge",github ="gnoblet",bluesky ="gnoblet.bsky.social",website ="guillaume-noblet.com",additional_text_color ="#2b2b2bff",text_color ="#2b2b2bff",icon_color ="#2b2b2bff",icon_size ="13pt",text_size ="13pt",additional_text_size ="13pt",text_family ='main',line_spacing =2L)title <-"Dams Dominate the Alpine Heights"subtitle <-paste0("From the Grande Dixence (285m, 1965) to the Mauvoisin Dam (250m, 1957), most of Switzerland's tallest structures are found in the mountains. Urban towers like Basel's Roche Tower (178m) pale in comparison to these Alpine giants.")# Mapp <-ggplot() +# Add elevation as raster/contour backgroundgeom_spatraster(data = hill) +scale_fill_gradient(low ="#fbfbfbff", high ="#6a6a6aff", na.value =NA) +# Buildings dotsgeom_sf(data = buildings,aes(size = height_m, color = structure_type),alpha =0.6,show.legend =TRUE ) +# Add building names for tallest onesgeom_text_repel(data = buildings |>slice_max(height_m, n =5),aes(label =paste0(construction_type, " (", height_m, "m)"),geometry = geometry ),family ="main",size =4.5,# nudge_y up for grand dixence dam and down for Trasmitter and Swisscomnudge_y =case_when(str_detect(top_buildings, "Grande Dixence") ~0.2,str_detect(top_buildings, "Transmitter|Swisscom") ~-0.2,.default =0 ),# nudge_x right for Monte Ceneri and Luzzone dam and left for othersnudge_x =ifelse(str_detect(top_buildings, "Monte Ceneri|Luzzone"),1,-0.8 ),color ="#000000",stat ="sf_coordinates",force =10,segment.curvature =-1e-20,bg.color ="white",bg.r =0.2 ) +# Colors from cols4all packagescale_color_discrete_c4a_cat("cols4all.area7d",name ="Structure Type",guide =guide_legend(override.aes =list(size =4)) ) +scale_size_continuous(range =c(1, 12),name ="Height (m)",guide =guide_legend(title.position ="top" ) ) +# no guide for fillguides(fill ="none") +# Increase y limits top and bottom to add title and caption# Based on ch bounding boxcoord_sf(ylim =c(st_bbox(ch)["ymin"] -0.2, st_bbox(ch)["ymax"] +0.4),xlim =c(st_bbox(ch)["xmin"], st_bbox(ch)["xmax"]) ) +# Add branding at the bottomgeom_richtext(aes(label = branding),x =5.8,y =st_bbox(ch)["ymin"] -0.1,fill =NA,label.color =NA,hjust =0,vjust =0.5, ) +# Add titlegeom_richtext(aes(label = title),x =5.8,y =st_bbox(ch)["ymax"] +0.3,fill =NA,label.color =NA,hjust =0,family ="main",fontface ="bold",size =8 ) +# Add subtitlegeom_textbox(aes(label = subtitle),x =5.8,y =st_bbox(ch)["ymax"] +0.2,hjust =0,family ="main",size =5.5,width =unit(0.95, "npc"),box.color =NA,fill =NA,vjust =1 ) +# Themetheme_void() +theme(text =element_text(family ="main", size =15),plot.background =element_rect(fill ="#f5f5f5", color =NA),panel.background =element_rect(fill ="#f5f5f5", color =NA),legend.position ="right",legend.background =element_rect(fill ="#f5f5f5", color ="#969696"),legend.title =element_text(color ="#2b2b2bff", face ="bold"),legend.text =element_text(color ="#2b2b2bff"),legend.margin =margin(t =0.5, r =0.8, unit ="cm") )# Saveggsave("day_06.png",plot = p,width =12,height =8,dpi =600)