An isochrone showing the time it takes to drive to New Delhi IGI Airport from different parts of India’s National Capital Region
Maps
India
Geocomputation
Haryana
Interactive
Author
Aditya Dahiya
Published
October 4, 2024
Isochrones are lines on a map that connect points where travel time from a specific location is the same. In the context of my map, the isochrones represent driving distances at 10-minute intervals, starting from 10 minutes and extending up to 60 minutes from New Delhi Indira Gandhi International (IGI) Airport Terminal 3. This visualization helps users understand how far they can travel within specific time frames under normal traffic conditions. The map was created using open-source data from OpenRouteService, and the methodology and code were inspired by the work of Milos Popovic, whose detailed tutorial and code are available on GitHub and through his video tutorial.
How I made this graphic?
Loading required libraries, data import & creating custom functions
Code
library(openrouteservice) # Get catchment areas in sf formatlibrary(leaflet) # Interactive Mapslibrary(tidyverse) # Data Wrangling & ggplot2# library(maptiles) # Get map data rasters for backgroundlibrary(sf) # for SF objects in ggplot2# library(tidyterra) # Use maptiles with ggplot2# library(fontawesome) # Icons display in ggplot2# library(ggtext) # Markdown text support for ggplot2# library(showtext) # Display fonts in ggplot2# Mapping travel catchment areas by Milos Popovic 2023/10/10# Video Link: https://www.youtube.com/watch?v=UNGzJrx8VrE# Code: https://github.com/milos-agathon/isochrone_maps# Install the Open Route Service R-package# remotes::install_github(# "GIScience/openrouteservice-r"# )# Getting the main parameters# Seeing the available kinds of modes of travel# openrouteservice::ors_profile()# api_key <- "" # API key from https://openrouteservice.org/# Coordinates of IGI Airport Terminal 3, New Delhi, Indiacoords <-data.frame(lon =77.0857630708,lat =28.5554206018,image ="https://cdn-icons-png.flaticon.com/512/7720/7720736.png" )# Getting the Iso-chrones data from OpenRouteService# car_delhi <- openrouteservice::ors_isochrones(# locations = coords,# profile = "driving-car",# range = 3600,# interval = 600,# api_key = api_key,# output = "sf"# )# write_rds(car_delhi, here::here("data", "delhi_isochrone.rds"))# Check the size fo the data fetched# object.size(car_delhi) |> print(units = "Kb")# For purpose of rendering this page, I have used # downloaded datacar_delhi <-read_rds(here::here("data", "delhi_isochrone.rds"))
Visualization Parameters
Code
# Font for titlesfont_add_google("Teko",family ="title_font") # Font for the captionfont_add_google("Saira Extra Condensed",family ="caption_font") # Font for plot textfont_add_google("Teko",family ="body_font") showtext_auto()# Background Colourbg_col <-"white"# Colour for the texttext_col <-"grey5"# Colour for highlighted texttext_hil <-"grey10"# Define Base Text Sizebts <-120# Caption stuff for the plotsysfonts::font_add(family ="Font Awesome 6 Brands",regular = here::here("docs", "Font Awesome 6 Brands-Regular-400.otf"))github <-""github_username <-"aditya-dahiya"xtwitter <-""xtwitter_username <-"@adityadahiyaias"social_caption_1 <- glue::glue("<span style='font-family:\"Font Awesome 6 Brands\";'>{github};</span> <span style='color: {text_hil}'>{github_username} </span>")social_caption_2 <- glue::glue("<span style='font-family:\"Font Awesome 6 Brands\";'>{xtwitter};</span> <span style='color: {text_hil}'>{xtwitter_username}</span>")plot_title <-"Driving Time to Delhi's International Airport (Isochrones)"plot_caption <-paste0("**Data:** openrouteservice.org<br>","**Technique:** Milos Popovic<br>", "**Code:** ", social_caption_1, "**<br>Graphics:** ", social_caption_2 )rm(github, github_username, xtwitter, xtwitter_username, social_caption_1, social_caption_2)
Data Analysis and Wrangling
Code
# We need to intersect the bigger and smaller polygons so that # they dont overlap, and bigger polygons dont overshadowsf::sf_use_s2(F) # Turn off spherical geometrycar_delhi_cropped <- car_delhi |>mutate(mins =as_factor(value /60)) |>group_by(mins) |>st_intersection() |>ungroup()# Data needed to make a Static Graphic with ggplot2# car_delhi_merc <- sf::st_transform(# car_delhi_cropped,# 4326# )# # delhi_layer <- maptiles::get_tiles(# car_delhi_merc,# provider = "CartoDB.Positron",# zoom = 9# )# # object.size(delhi_layer) |> print(units = "Kb")# Data needed to make a Static Graphic with ggmap# library(ggmap)# Register your Stadia Maps key# stadia_maps_api_key# register_stadiamaps(stadia_maps_api_key, write = FALSE)# # background_tiles_bbox <- c(# left = 76.45,# right = 77.75,# top = 29.1,# bottom = 27.9# )# # stamen_tiles_10 <- ggmap::get_stadiamap(# background_tiles_bbox,# zoom = 10,# maptype = "stamen_toner"# )# # stamen_tiles_11 <- ggmap::get_stadiamap(# background_tiles_bbox,# zoom = 11,# maptype = "stamen_toner"# )# # mypal <- paletteer::paletteer_d("rcartocolor::Geyser")[c(1:3,5:7)]# # library(magick)# airport_icon <- magick::image_read("https://cdn-icons-png.flaticon.com/512/7720/7720736.png")# # airport_icon |> # image_background("transparent")