logo of company

Fourth Set: Nice, Easy Mapping

Steven Turnbull

September 5, 2024

Mapping made easy!

In a previous post I outlined how we can take a set of addresses scraped from Tennis NZs website and geocode them to get latitude and longitude coordinates. I’ve tried out a bunch of different techniques to analyse this dataset, including drive isodistances and point density mapping

In this post, I’ll be testing out a really easy way to make a map based on a set of coordinates, inspired by this LinkedIn post by Isaac Bain. In this post, Isaac shows how we can use the rcityviews package to take a set of coordinates and feed them into the rcityviews::cityview() function to return a nice map.

Lets take the first 6 tennis club addresses of set we scraped earlier.

Code
library(here)
library(dplyr)
library(reactable)
df <- read.csv(here("inputs","tennis","tennis_coords.csv"))

#We know the geocoding failed on some addresses, so we'll exclude those
df_clean <- df |>
  filter(!is.na(latitude) | !is.na(longitude)) |>
  head()

df_clean |> 
  reactable(
    bordered = TRUE,
    highlight = TRUE
  ) 

Then, it’s super straight forward to make a map! Here’s the code for a single address. Simply use the new_city function to set the centre location of our map to our desired coordinates, and then use the cityview function to render the image. the rcityviews package does all of the hard work of connecting to OpenStreetMap and pulling the map data.

Code
library(rcityviews)

 # Create a new city object
city <- new_city(
  name = df$name[1],
  country = "New Zealand",
  lat = df$latitude[1],
  long = df$longitude[1]
)

p <- cityview(
  name = city,
  zoom = 4, #we'll set the zoom a bit closer so we can see the courts. 
  license = FALSE,
  theme = 'modern',
  filename=here("example_nice_map.png")
)

print(p)

Example nice map. Hopefully we can see the tennis courts dead centre.

And here’s the code for running through our set of addresses. We can set our own style for the maps manually.

Code
# set theme for map appearance
myTheme <- list(
  colors = list(
   "background" = "#e6ddd6",
      "water" = "#656c7c",
      "landuse" = "#7c9c6b",
      "contours" = "#e6ddd6",
      "streets" = "#fafafa",
      "rails" = c("#fafafa", "#e6ddd6"),
      "buildings" = "#eb3e20",
      "text" = "#000000",
      "waterlines" = "#656c7c"
  ),
  font = list(
    "family" = "Imbue",
      "face" = "plain",
      "scale" = 3
  ),
  size = list(
    borders = list(
      contours = 0.15,
      water = 0.4,
      canal = 0.5,
      river = 0.6
    ),
    streets = list(
      path = 0.2,
      residential = 0.3,
      structure = 0.35,
      tertiary = 0.4,
      secondary = 0.5,
      primary = 0.6,
      motorway = 0.8,
      rails = 0.65,
      runway = 3
    )
  )
)

# Loop through each tennis club address
for (i in 1:nrow(df_clean)) {
  # Extract tennis club details
  name <- df_clean$name[i]
  lat <- df_clean$latitude[i]
  long <- df_clean$longitude[i]

  # Create a new city object
  city <- new_city(
    name = name,
    country = "New Zealand",
    lat = lat,
    long = long
    )

# Produce the cityview
  p <- cityview(
    name = city,
    zoom = 4,
    license = FALSE,
    theme = myTheme
    )
  
  output_filename <- here('inputs','tennis','maps',paste0(name,".png"))

  ggsave(
    filename = output_filename,
    plot = p,
    height = 500,
    width = 500,
    units = "mm",
    dpi = 300
    )
}

And here’s the result!

A very easy to use library that has awesome options for styling the maps!