Last active
December 2, 2022 22:23
-
-
Save mschnetzer/3c9e1fe4e0c5f04123033d9d689e75b9 to your computer and use it in GitHub Desktop.
Vienna's buildings by construction periods (https://twitter.com/matschnetzer/status/1598586751190278146)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
librarian::shelf(tidyverse, sf, ows4R, httr, msthemes, osmdata, RColorBrewer, ggtext, showtext) | |
# Add Google fonts | |
font_add_google(name = "Bodoni Moda", family = "bodoni") | |
font_add_google(name = "Roboto Slab", family = "roboto-slab") | |
font_add_google(name = "Roboto Slab", family = "roboto-slab-thin", regular.wt = 300, bold.wt = 500) | |
showtext_auto() | |
# Define map boundaries | |
bb <- c(16.3151, 48.1856, 16.4087, 48.2279) | |
stephansdom <- c(16.37317, 48.20852) | |
# OSM background (streets, rivers, buildings) | |
wienbg <- opq(bbox = bb) |> | |
add_osm_feature(key = 'highway', value = c("primary","secondary","tertiary")) |> | |
osmdata_sf() | |
wienbgsf <- wienbg$osm_lines |> st_transform(crs = 4326) | |
wienwater <- opq(bbox = bb) |> | |
add_osm_feature(key = 'natural', value = "water") |> | |
osmdata_sf() | |
wienwatersf <- wienwater$osm_multipolygons |> st_transform(crs = 4326) | |
wienbuild <- opq(bbox = bb) |> | |
add_osm_feature(key = 'building') |> | |
osmdata_sf() | |
wienbuildsf <- wienbuild$osm_polygons |> st_transform(crs = 4326) | |
# Create circle shape with a 2km radius | |
circle <- tibble(lat = stephansdom[1], long = stephansdom[2]) |> | |
st_as_sf(coords = c("lat", "long"), crs = 4326) |> | |
st_transform(crs = 6384) |> st_buffer(dist = 2000) |> st_transform(crs = 4326) | |
# Map data from WFS (Stadt Wien) | |
wfs_wien <- "https://data.wien.gv.at/daten/geo" | |
wien_client <- WFSClient$new(wfs_wien, serviceVersion = "1.0.0") | |
wien_client$getFeatureTypes(pretty = TRUE) | |
url <- parse_url(wfs_wien) | |
url$query <- list(service = "WFS", | |
version = "1.1.0", | |
request = "GetFeature", | |
typeName = "ogdwien:BAUPERIODEDETAILOGD", | |
SRS = "EPSG:4326", | |
BBOX = paste0(paste0(bb,collapse=","),",EPSG:4326")) | |
request <- build_url(url) | |
wien_map <- read_sf(request) |> st_set_crs(31256) |> st_transform(crs = 4326) | |
# Edit messy data and fix construction periods | |
wien_map <- wien_map |> | |
mutate(periode = case_when( | |
OBJ_STR2_TXT == "vor 1848" ~ "1781-1848", | |
OBJ_STR2_TXT == "1848 -1918" ~ "1884-1918", | |
OBJ_STR2_TXT == "1884-1918" ~ "1884-1918", | |
OBJ_STR2_TXT == "1919 - 1945" ~ "1919-1945", | |
OBJ_STR2_TXT == "nach 1945" ~ "1946-1976", | |
OBJ_STR_TXT == "Keine Angabe" ~ NA_character_, | |
OBJ_STR_TXT == "Vor 1848" ~ "1781-1848", | |
OBJ_STR_TXT == "Vor 1683" ~ "before 1683", | |
OBJ_STR_TXT == "Nach 1976" ~ "after 1976", | |
OBJ_STR_TXT == "1848-1918" ~ "1884-1918", # data coding error | |
TRUE ~ OBJ_STR_TXT), | |
periode = factor(periode, levels = c("before 1683","1683-1740","1741-1780","1781-1848","1849-1859","1860-1883","1884-1918","1919-1945","1946-1976","after 1976"))) | |
# Cropping data with circle | |
street_crop <- wienbgsf |> st_intersection(circle) | |
water_crop <- wienwatersf |> st_intersection(circle) | |
base_crop <- wienbuildsf |> st_intersection(circle) | |
wien_crop <- wien_map |> | |
filter(st_geometry_type(SHAPE) %in% c("POLYGON","MULTIPOLYGON")) |> | |
st_intersection(circle) | |
# Final clean-up in the data | |
# Get rid of duplicates, keep observation with highest frequency of building period | |
wien_crop <- wien_crop |> filter(!is.na(periode)) |> | |
group_by(OBJECTID) |> add_count(periode) |> | |
group_by(OBJECTID) |> slice_max(n, n=1, with_ties = F) | |
# Draw plot | |
wienplot <- ggplot() + | |
geom_sf(data = base_crop, fill = "gray20", size = NA, color = NA, alpha = 0.7) + | |
geom_sf(data = water_crop, fill = "lightblue", size = 0.2) + | |
geom_sf(data = street_crop, color = "gray85", size = 0.2, alpha = 0.8) + | |
geom_sf(data = wien_crop |> filter(!is.na(periode)), aes(fill = periode), color = NA) + | |
scale_fill_manual(name = "Year of construction", | |
values = colorRampPalette(brewer.pal(11, "Spectral"))(10), | |
guide = guide_legend(keywidth = unit(0.3,"lines"), title.position = "left", title.hjust = 0)) + | |
labs(title = "Vienna", caption = "Source: Stadt Wien, OpenStreetMaps. Figure: @matschnetzer", | |
subtitle = "This map shows the city center of the Austrian capital by construction periods. Parts of the center were built even<br><b style='color:#9E0142'>before the Battle of Vienna in 1683</b> after the imperial city had been besieged by the Ottoman Empire for two months.<br>Many important buildings of the Ringstraße were constructed in the <b style='color:#F1F9A9'>'Gründerzeit' era between 1860 and 1883</b>.<br>Only a few buildings in the inner city were built <b style='color:#5E4FA2'>after 1976</b>.") + | |
theme_ms(grid = F, dark = T, alttf = T) + | |
theme(axis.text = element_blank(), | |
plot.title = element_text(hjust = 0.5, size = 110, family = "bodoni", margin = margin(b = 0.3, unit = "cm")), | |
plot.subtitle = element_markdown(size = 25, family = "roboto-slab-thin", lineheight=0.4), | |
plot.caption = element_text(size = 20, family = "roboto-slab", hjust = 1), | |
plot.caption.position = "plot", | |
legend.title = element_text(size = 25, family = "roboto-slab", angle = 90, margin = margin(r=-5, unit = "pt")), | |
legend.text = element_text(size = 25, family = "roboto-slab"), | |
plot.background = element_rect(fill="black")) | |
ggsave(wienplot, filename = "wienplot.png", dpi = 320, width = 7, height = 6) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment