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.
## 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 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
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)
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
)
After producing the map, load it into Figma in order to add titles and a caption.