birdseyeview

The goal of birdseyeview is to make it easy to create the types of maps, plots, and tables used for community plans.

This package was initially designed to use the overedge package and data packages like mapbaltimore or bcpss to create reproducible maps and tables for a range of needs. The {overedge} package has since been superseded by sfext, getdata, and maplayer. maplayer incorporated most of the mapping functions creating for birdseyeview. These duplicative functions were removed from birdseyeview in Setember 2022.

Installation

You can install the development version of birdseyeview like so:

# remotes::install_github("elipousson/birdseyeview")
install.packages("birdseyeview", repos = c('https://elipousson.r-universe.dev', 'https://cloud.r-project.org'))

Example

library(birdseyeview)
library(getdata)
library(sfext)
library(maplayer)

Make tables

parks <-
  getdata::get_location_data(
    data = "parks",
    package = "mapbaltimore"
  )

parks %>%
  dplyr::slice_head(n = 4) %>%
  dplyr:::select(name, address, park_district, acres, geometry) %>%
  dplyr::group_by(park_district) %>%
  gt::gt() %>%
  gt_sf_rows(fill = "forestgreen", color = "lightgreen", size = 6)
<style>html { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif; }

#zntuztalnp .gt_table { display: table; border-collapse: collapse; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }

#zntuztalnp .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }

#zntuztalnp .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }

#zntuztalnp .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 0; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }

#zntuztalnp .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }

#zntuztalnp .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }

#zntuztalnp .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }

#zntuztalnp .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }

#zntuztalnp .gt_column_spanner_outer:first-child { padding-left: 0; }

#zntuztalnp .gt_column_spanner_outer:last-child { padding-right: 0; }

#zntuztalnp .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }

#zntuztalnp .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; }

#zntuztalnp .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }

#zntuztalnp .gt_from_md > :first-child { margin-top: 0; }

#zntuztalnp .gt_from_md > :last-child { margin-bottom: 0; }

#zntuztalnp .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }

#zntuztalnp .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }

#zntuztalnp .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }

#zntuztalnp .gt_row_group_first td { border-top-width: 2px; }

#zntuztalnp .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }

#zntuztalnp .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; }

#zntuztalnp .gt_first_summary_row.thick { border-top-width: 2px; }

#zntuztalnp .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }

#zntuztalnp .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }

#zntuztalnp .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }

#zntuztalnp .gt_striped { background-color: rgba(128, 128, 128, 0.05); }

#zntuztalnp .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }

#zntuztalnp .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }

#zntuztalnp .gt_footnote { margin: 0px; font-size: 90%; padding-left: 4px; padding-right: 4px; padding-left: 5px; padding-right: 5px; }

#zntuztalnp .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }

#zntuztalnp .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; }

#zntuztalnp .gt_left { text-align: left; }

#zntuztalnp .gt_center { text-align: center; }

#zntuztalnp .gt_right { text-align: right; font-variant-numeric: tabular-nums; }

#zntuztalnp .gt_font_normal { font-weight: normal; }

#zntuztalnp .gt_font_bold { font-weight: bold; }

#zntuztalnp .gt_font_italic { font-style: italic; }

#zntuztalnp .gt_super { font-size: 65%; }

#zntuztalnp .gt_footnote_marks { font-style: italic; font-weight: normal; font-size: 75%; vertical-align: 0.4em; }

#zntuztalnp .gt_asterisk { font-size: 100%; vertical-align: 0; }

#zntuztalnp .gt_indent_1 { text-indent: 5px; }

#zntuztalnp .gt_indent_2 { text-indent: 10px; }

#zntuztalnp .gt_indent_3 { text-indent: 15px; }

#zntuztalnp .gt_indent_4 { text-indent: 20px; }

#zntuztalnp .gt_indent_5 { text-indent: 25px; } </style>

name address acres map
Clifton
Abell Open Space 301 E 32nd St 0.1687215 [acres]
Adams Park 1530 Montpelier St 0.6228435 [acres]
Alhambra Park 5200 Alhambra Ave 0.9927695 [acres]
Gwynns Falls
Alexander Odum Park 3111 Presstman St 1.3572063 [acres]
park_photos <-
  getdata::get_flickr_photos(
    user_id = "baltimoreheritage",
    tags = "druidhillpark",
    img_size = "m",
    sort = "date-posted",
    per_page = 20
  )

park_photos[1:6, ] %>%
  dplyr::select(title, datetaken, image_height, image_width, image_url) %>%
  tbl_photo_key(photo_col = "image_url", orientation = "landscape", number = TRUE)

Make maps

library(ggplot2)
ggplot() +
  maplayer::layer_location_context(
    data = parks[245, ],
    fill = "green",
    context = parks,
    context_params = list(fill = "forestgreen", color = "gray60", alpha = 1)
  )
# make_group_layers has been dropped from birdseyeview but isn't available in maplayer yet
park_district_layers <-
  make_group_layers(
    data = parks %>% sf::st_centroid(),
    mapping = aes(color = name),
    groupname_col = "park_district"
  )

clifton_district <-
  getdata::get_location(
    type = "park_districts",
    package = "mapbaltimore",
    name = "Clifton"
  )

ggplot() +
  park_district_layers[[1]] +
  guides(color = "none") +
  layer_show_location(
    data = clifton_district
  ) +
  theme_void()