diff --git a/28Nov_BluePlanet/28-blue-planet.qmd b/28Nov_BluePlanet/28-blue-planet.qmd
new file mode 100644
index 0000000..8185890
--- /dev/null
+++ b/28Nov_BluePlanet/28-blue-planet.qmd
@@ -0,0 +1,179 @@
+---
+title: "20. OSM: OSM data in CRiSp"
+author: "Claudiu Forgaci"
+date: "2024-11-19"
+format:
+ html: default
+ pdf: default
+---
+
+### 0. Load packages
+
+```{r}
+pkgs <- c("tidyverse", "sf", "pak", "sysfonts", "showtext", "ggtext", "scales",
+ "osmdata", "magick", "grid", "rnaturalearth", "rnaturalearthdata")
+missing_pkgs <- pkgs[!(pkgs %in% installed.packages()[, "Package"])]
+if (length(missing_pkgs)) install.packages(missing_pkgs)
+lapply(pkgs, library, character.only = TRUE)
+```
+
+```{r}
+rbanism_logo <- image_read('../rbanism_logo_white.png')
+colored_rbanism_logo <- image_colorize(rbanism_logo, opacity = 100, color = "#155294")
+image_write(colored_rbanism_logo, "img/colored_rbanism_logo.png")
+```
+
+### 1. Get world map and capitals data
+
+```{r osm-data}
+world <- ne_countries(scale = "medium", returnclass = "sf")
+capitals <- ne_download(scale = "medium", type = "populated_places", category = "cultural", returnclass = "sf")
+capitals <- capitals |>
+ filter(POP_MIN > 0 & FEATURECLA == "Admin-0 capital") |>
+ select(name = NAME, latitude = LATITUDE, longitude = LONGITUDE, pop = POP_MIN, geom = geometry)
+```
+
+### 2. Get rivers from OSM
+
+```{r}
+river_data_list <- list()
+
+for (i in 1:nrow(capitals)) {
+ bbox <- st_bbox(capitals[i, ])
+ bbox_expanded <- c(xmin = bbox["xmin"] - 0.1, ymin = bbox["ymin"] - 0.1,
+ xmax = bbox["xmax"] + 0.1, ymax = bbox["ymax"] + 0.1)
+
+ river_data <- opq(bbox_expanded) |>
+ add_osm_feature(key = "waterway", value = "river") |>
+ osmdata_sf()
+
+ if (!is.null(river_data$osm_lines)) {
+ river_data_list[[capitals$name[i]]] <- river_data$osm_lines
+ }
+}
+
+standardize_sf <- function(sf_object, template) {
+ missing_cols <- setdiff(names(template), names(sf_object))
+ for (col in missing_cols) sf_object[[col]] <- NA
+ sf_object <- sf_object[, names(template)]
+}
+
+template <- river_data_list[[1]][1, ]
+river_data_list <- lapply(river_data_list, \(river) {
+ if (!is.null(river)) {standardize_sf(river, template)} else {NULL}
+})
+
+river_data_list <- river_data_list[!sapply(river_data_list, is.null)]
+
+rivers <- do.call(rbind, river_data_list)
+```
+
+### 3. Calculate river orientation
+
+```{r}
+calculate_orientation <- function(linestring) {
+ coords <- st_coordinates(linestring)
+ lm_fit <- lm(coords[,2] ~ coords[,1])
+ atan(coef(lm_fit)[2]) * 180 / pi
+}
+
+rivers <- rivers |>
+ rowwise() |>
+ mutate(orientation = calculate_orientation(geometry))
+
+capital_river_dist <- st_distance(capitals, rivers)
+nearest_rivers <- apply(capital_river_dist, 1, which.min)
+capitals$ro <- rivers$orientation[nearest_rivers]
+```
+
+### 4. Create the plot
+
+```{r base-plot}
+scaling_factor <- 1000
+world <- st_transform(world, crs = 3857)
+capitals <- st_transform(capitals, crs = 3857)
+lat_min <- -60 * 111320
+lat_max <- 100 * 111320
+
+p <- ggplot() +
+ geom_sf(data = world, fill = "#155294", color = NA) +
+ geom_sf(data = capitals, aes(size = pop), shape = 21, fill = "#29d1ff", color = "#29d1ff", alpha = 0.8) +
+ geom_segment(
+ data = capitals |> filter(!is.na(ro)),
+ aes(
+ x = st_coordinates(geom)[,1] - cos(ro * pi / 180) * sqrt(pop) * scaling_factor / 2,
+ y = st_coordinates(geom)[,2] - sin(ro * pi / 180) * sqrt(pop) * scaling_factor / 2,
+ xend = st_coordinates(geom)[,1] + cos(ro * pi / 180) * sqrt(pop) * scaling_factor / 2,
+ yend = st_coordinates(geom)[,2] + sin(ro * pi / 180) * sqrt(pop) * scaling_factor / 2
+ ),
+ color = "#ff5b29",
+ alpha = 0.8,
+ show.legend = TRUE
+ ) +
+ geom_segment(
+ aes(x = 0, y = 0, xend = 1, yend = 1),
+ color = "#ff5b29",
+ linetype = "solid",
+ inherit.aes = FALSE,
+ show.legend = TRUE
+ ) +
+ scale_size(
+ range = c(1, 10),
+ labels = label_number(scale = 1e-6, suffix = " mil.", accuracy = 0.1)
+ ) +
+ coord_sf(crs = st_crs(3857),
+ ylim = c(lat_min, lat_max)) +
+ labs(
+ title = "World Capitals with River Orientations",
+ # size = "Population& River Orientation",
+ size = NULL,
+ color = "River Orientation"
+ ) +
+ guides(color = guide_legend(override.aes = list(linetype = "solid")))
+```
+
+### 5. Style the map
+
+#### 5.1 Add custom fonts
+
+```{r plot-styling}
+font_add_google("Montserrat", "m")
+showtext_auto()
+```
+
+#### 5.2 Plot your map
+
+```{r plot}
+p_styled <- p +
+ theme_void() +
+ theme(
+ plot.background = element_rect(fill = "#d8e1f0", color = NA),
+ plot.margin = margin(45, 10, 45, 10),
+ legend.position = "bottom",
+ legend.box = "horizontal",
+ legend.title = element_text(size = 13, family = "m", color = "#155294"),
+ legend.text = element_text(size = 13, family = "m", color = "#155294"),
+ plot.title = element_text(size = 34, family = "m", color = "#155294",
+ face = "bold", lineheight = 1),
+ plot.subtitle = element_markdown(size = 13, family = "m", color = "#155294"),
+ plot.caption = element_text(size = 16, family = "m", color = "#155294",
+ hjust = 0, lineheight = 0.4),
+ legend.key.height = unit(1, "cm"),
+ legend.key.width = unit(1, "cm")) +
+ labs(title = "World Capitals with River Orientations",
+ subtitle = "Population& River Orientation",
+ caption = "Data: OpenStreetMap, NaturalEarth\nAuthor: Claudiu Forgaci")
+
+p_styled
+```
+
+```{r}
+p_styled <- cowplot::ggdraw(p_styled) +
+ cowplot::draw_image(colored_rbanism_logo, x = 0.85, y = 0.77, width = 0.09, height = 0.09, hjust = 0, vjust = 0)
+```
+
+```{r}
+output_file <- "output/28Nov_BluePlanet.png"
+ggsave(filename = output_file, plot = p_styled, device = "png",
+ width = 6, height = 6, dpi = 300)
+```
diff --git a/28Nov_BluePlanet/carbon.png b/28Nov_BluePlanet/carbon.png
new file mode 100644
index 0000000..026d2f7
Binary files /dev/null and b/28Nov_BluePlanet/carbon.png differ
diff --git a/28Nov_BluePlanet/img/colored_rbanism_logo.png b/28Nov_BluePlanet/img/colored_rbanism_logo.png
new file mode 100644
index 0000000..0b9c3bf
Binary files /dev/null and b/28Nov_BluePlanet/img/colored_rbanism_logo.png differ
diff --git a/28Nov_BluePlanet/output/28Nov_BluePlanet.png b/28Nov_BluePlanet/output/28Nov_BluePlanet.png
new file mode 100644
index 0000000..10dd5f6
Binary files /dev/null and b/28Nov_BluePlanet/output/28Nov_BluePlanet.png differ