# Define the packages to be used
<- c("tidyverse", "sf", "osmdata",
packages "geojsonR", "httr2", "stringr",
"lubridate", "magick", "magrittr",
"grid", "extrafont")
# Function to check if packages are installed and load them
<- function(pkgs) {
load_packages # Check for missing packages
<- pkgs[!(pkgs %in% installed.packages()[, "Package"])]
missing_pkgs
# Install missing packages
if (length(missing_pkgs)) {
install.packages(missing_pkgs)
}
# Load all packages
lapply(pkgs, library, character.only = TRUE)
}
# Load the packages
load_packages(packages)
loadfonts(device = "postscript")
#30DMC_15Nov_MyData
15 November. Data: my data.
“Map something personal. Map data from your own life—this could be places you’ve traveled, your daily routine, or any other personal touch.”
1. Package Installation and Loading
2. Import personal data, city backgrounds & Rbanism logo
# Personal data
# https://www.google.com/maps/d/edit?mid=1u_XNZO2eSg8vmpIPjjkHy2nDyPEiuhGa&usp=sharing
<- read_csv("MyData.csv") %>%
mydata mutate(long = word(word(word(geometry, 2, sep="\\("), 1, sep="\\)"), 1, sep="\\ "),
lat = word(word(word(geometry, 2, sep="\\("), 1, sep="\\)"), 2, sep="\\ "),
date = dmy(time))
Rows: 45 Columns: 2
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): geometry, time
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Direction de l'Urbanisme - Ville de Paris, Opendata Paris, Open Database License (ODbL) https://opendata.paris.fr/explore/dataset/quartier_paris/export/?disjunctive.c_ar&location=12,48.85889,2.34692&basemap=jawg.streets
<- st_read("quartier_paris.geojson") paris_WGS84
Reading layer `quartier_paris' from data source
`/Users/ccottineau/GitHub/30DayMapChallenge2024/15Nov_MyData/quartier_paris.geojson'
using driver `GeoJSON'
Simple feature collection with 80 features and 11 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 2.224078 ymin: 48.81558 xmax: 2.469761 ymax: 48.90216
Geodetic CRS: WGS 84
<- 27572
paris_crs
<- paris_WGS84 %>%
paris_metric st_transform(.,crs=paris_crs)
# Greater London Authority, Ordnance Survey data with © Crown copyright https://data.london.gov.uk/dataset/statistical-gis-boundary-files-london
<- st_read("London_Ward.shp") london_metric
Reading layer `London_Ward' from data source
`/Users/ccottineau/GitHub/30DayMapChallenge2024/15Nov_MyData/London_Ward.shp'
using driver `ESRI Shapefile'
Simple feature collection with 657 features and 6 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 503568.2 ymin: 155850.8 xmax: 561957.5 ymax: 200933.9
Projected CRS: OSGB36 / British National Grid
<- 27700
london_crs
<- london_metric %>%
london_WGS84 st_transform(.,crs=4326)
# Download Rbanism logo
<- image_read('https://rbanism.org/assets/imgs/about/vi_l.jpg') rbanism_logo
3. One function to filter, crop and map data
<- function(city){
city_flash_map
if(city == "Paris"){
<- paris_metric
city_metric <- paris_WGS84
city_WGS84 <- paris_crs
city_crs <- "Direction de l'Urbanisme - Ville de Paris, Opendata Paris ODbL"
source
}
if(city == "London"){
<- london_metric
city_metric <- london_WGS84
city_WGS84 <- london_crs
city_crs <- "Greater London Authority, Ordnance Survey w/ © Crown copyright"
source
}
<- sf::st_bbox(city_WGS84)
bbWGS
### Filter my data to city
<- st_as_sf(mydata, coords = c("long","lat")) %>%
mydata_sf st_set_crs(4326) %>%
st_transform(.,crs=city_crs) %>%
st_intersection(city_metric, .)
<- mydata_sf %>%
mydata_sf mutate(days = as.numeric(max(mydata_sf$date) - date))
### Import OSM data
# Metro
<- opq(bbox = bbWGS) %>%
x add_osm_feature(key = 'railway', value = "subway") %>%
osmdata_sf()
# Waterways
<- opq(bbox = bbWGS) %>%
y add_osm_feature(key = 'waterway') %>%
osmdata_sf()
# Green spaces
<- opq(bbox = bbWGS) %>%
z add_osm_feature(key = 'leisure', value="park") %>%
osmdata_sf()
### Crop OSM features to city extent
<- x$osm_lines %>%
metrolines st_transform(.,crs=city_crs) %>%
st_intersection(city_metric, .)
<- y$osm_lines %>%
water st_transform(.,crs=city_crs) %>%
st_intersection(city_metric, .) %>%
filter(waterway %in% c("canal", "river"))
<- z$osm_polygons %>%
green st_transform(.,crs=city_crs) %>%
st_intersection(city_metric, .)
## Plot the result
ggplot() +
geom_sf(data = city_metric, fill=alpha("grey", 0.8), colour = "white") +
geom_sf(data = water, colour=alpha("#93278F",0.7), aes(linewidth=waterway)) +
scale_discrete_manual("linewidth", values = c(1,2))+
# geom_sf(data = metrolines, aes(colour=ref)) +
geom_sf(data = green, fill="#00A99D", colour = "white", linewidth = 0) +
geom_sf(data = mydata_sf, aes(colour = days), size=3) +
coord_sf(datum = st_crs(city_crs)) +
scale_colour_gradient(low = "white", high = "#F7931E",
na.value = NA, name="# Days since \n earliest flash") +
ggtitle(paste0("15Nov. My Data \n",
" flashes during the first COVID lockdown")) +
city, ylab("")+
xlab(paste0("#30DayMapChallenge. Clémentine Cottineau-Mugadza, 2024. Personal data.\n Map background: ", source, ".")) +
guides(linewidth = "none") +
theme_minimal() +
theme(axis.text=element_text(size=6, family="Courier"),
plot.title=element_text(size=12, family="Courier"),
axis.title=element_text(size=8, family="Courier"),
legend.text=element_text(size=8, family="Courier"),
legend.title=element_text(size=10, family="Courier"))
}
4. Pick a city and make a map
Paris
city_flash_map("Paris")
grid.raster(rbanism_logo,
x = 0.9, y=0.9,
width = unit(100, "points"))
ggsave(filename = "Paris.png",
width = 8, height = 8, dpi = 300)
London
city_flash_map("London")
grid.raster(rbanism_logo,
x = 0.9, y=0.9,
width = unit(100, "points"))
ggsave(filename = "London.png",
width = 8, height = 8, dpi = 300)