Welcome! This guide should be accompanied with the broadband mapping checklist to help broadband and MDA team members create consistent and beautiful maps.

In this guide, we will cover how to use R functions to follow the requirements listed in the checklist.

Load libraries and fonts

## Typical R packages needed for creating broadband maps

library(dplyr)
library(ggplot2)
library(cori.charts)
library(basemapR)
library(sf)
library(here)


## Load fonts

sysfonts::font_add_google("Lato") # For header text
sysfonts::font_add_google("Bitter") # For body text

# Ensures that any newly opened graphics devices will use 
# showtext to draw text at the appropriate density per inch
showtext::showtext_auto()
showtext::showtext_opts(dpi = 300)


## here package is helpful for file routing
# i_am specifies current location of this file within the project folder

# In this example, R is a subfolder within the main project folder
# which contains our R and Rmd files
i_am("R/broadband_mapping_guide.Rmd")

Load data

## Load map layers from local data directory

# Liberty, KS boundary file
liberty <- sf::st_read(here('data/liberty_boundaries.gpkg'))
## Reading layer `gistansmunicipal_areas' from data source 
##   `/Users/camdenblatchly/Desktop/code/bbmapstemplate/data/liberty_boundaries.gpkg' 
##   using driver `GPKG'
## Simple feature collection with 1 feature and 5 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -82.71711 ymin: 34.76187 xmax: -82.67043 ymax: 34.81887
## Geodetic CRS:  NAD83
# Identify the Coordinate Reference System for Liberty, KS boundary file
liberty_crs <- sf::st_crs(liberty)

cais <- readr::read_csv(here('data/liberty_cais.csv')) %>% 
  # Convert the lat lon into a spatial format and use the same CRS as Liberty 
  sf::st_as_sf(coords = c('lat', 'long'), crs = liberty_crs) %>%
  # Show only anchor institutions that fall within the Liberty boundary
  sf::st_filter(liberty)

# Load in roads data too
roads <- sf::st_read(here('data/rds_city.gpkg'))
## Reading layer `union' from data source 
##   `/Users/camdenblatchly/Desktop/code/bbmapstemplate/data/rds_city.gpkg' 
##   using driver `GPKG'
## Simple feature collection with 445 features and 73 fields
## Geometry type: MULTILINESTRING
## Dimension:     XYZ
## Bounding box:  xmin: 452490 ymin: 326160.4 xmax: 456662.1 ymax: 332380.7
## z_range:       zmin: 0 zmax: 0
## Projected CRS: NAD83 / South Carolina

Generate the bounding box

We use a bounding box or bbox when mapping in R to determine the map’s “window” (i.e., how much of the basemap to display). Bounding boxes are typically calculated using the largest boundary files that we are plotting. Since we want our maps to have a similar aspect ratio, we need to adjust the boundary to fit our desired aspect ratio. If we didn’t adjust the bounding box, the aspect ratio would align with that of the boundary we are plotting which may be too wide or tall.

In the example below, we calculate an initial bounding box using the boundary for Liberty, KS. We then pass this bounding box to the fit_bbox_to_aspect_ratio function from our cori.charts package to expand the bounding box to align with a 7:4 aspect ratio.

bbox <- sf::st_bbox(liberty) %>% 
  fit_bbox_to_aspect_ratio(target_aspect_ratio = 1.75)

Create the map

Maps in ggplot are built up layer by layer, starting with the basemap.

map <-  ggplot() +
  # Add our basemap
  base_map(
    bbox, # Our bbox determines what coordinates of basemap to display
    increase_zoom = 3, # Determines how detailed the basemap is. Usually 2 or 3 is decent.
    basemap = 'positron', # Default basemap style for Broadband mapping
    nolabels = FALSE # Hide labels (shop names, etc)
  ) +
  # Add in our boundary for Liberty, KS
  geom_sf(
    data = liberty,
    # Place boundaries should always have the following styling
    fill = cori_colors["Gray"],
    color = cori_colors["Nearly Black"], 
    linewidth = .5,
    alpha = .5
  ) +
  # Add in road outlines
  geom_sf(data = roads, color = "slategray", linewidth = .4) +
  # When plotting dots or points, review the checklist for
  # appropriate colors
  geom_sf(
    data = cais, 
    color = cori_colors["Squash"],
    linewidth = 1,
    # Adjust Size and Alpha as needed depending 
    # on the number and density of points
    size = 4,
    alpha = 0.9
  ) +
  # Clip our map view to only display what is within the bounding box
  coord_sf(
    expand = TRUE, 
    xlim = c(bbox['xmin'], bbox['xmax']), 
    ylim = c(bbox['ymin'], bbox['ymax'])
  ) +
  # Use CORI's default map theme
  theme_cori_map() +
  theme(
    # Remove all plot margin
    plot.margin = unit(c(0, 0, 0, 0), "cm")
  )
  

# Add map scale and north arrow
# Requires a boundary as an argument to determine both
map <- add_scale_and_north_arrow(map, liberty)

cori.charts::save_plot(
  fig = map,
  export_path = here('export/bb_map_example.png'),
  add_logo = FALSE
)
Example map of anchor institutions in Liberty, KS
Example map of anchor institutions in Liberty, KS

Polishing

After producing the map, load it into Figma in order to add titles and a caption.