knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(overedge)
library(ggplot2)

Get location

Supported location types

The "type" of location data that you can access with get_location() is very flexible. You can provide:

You can also provide the name of a simple feature object that is either already loaded to the global environment or available to load through any installed package.

Data in packages include exported data that is available when a package is loaded, data that is available in the system files but not loaded (and may sometimes be undocumented), and data that is in the default cache folder path from rappdirs::user_cache_dir(). If you want to use package data that is cached in a different location, you need to provide the file path (or filename and directory) in order to use it with get_location().

All of these parameters are passed from get_location() to get_location_data() so the following section of this vignette includes more details on how the more general function works.

Finally, you can alternatively pass a named list to index that serves as a look-up table for matching the "type" to a an sf object.

Supported parameters to accessing a location

The most basic parameters for accessing a specific location are:

The passed value for name is coerced to character and id is coerced to numeric so, if the "id" column for this type of location is in a character format, you need to treat it as a "name" instead.

Alternatively you can use the location parameter which supports either:

If you provide a sf or bbox object, the object is used as a spatial filter either when reading in the data (using the bbox parameter for read_sf_path or read_sf_url) or before returning the data using the sf::st_filter() function.

Working with union and label parameters

Location types that are administrative boundaries can often be grouped together into larger areas. The union parameter makes it easy to do this.

What is get_location() good for?

Building custom look-up functions

Here is are a few examples showing how you can use get_location() to create new custom look-up functions.

If your location data is from another package, you can use the package parameters passed to get_location_data() to access that data even without loading the package. This approach works best when the package data uses a consistent naming scheme for columns and data to support. This makes it easy to turn the names into parameters as the example below using the nycgeo package.

# remotes::install_github("mfherman/nycgeo")

get_nyc_borough <- function(name = NULL, id = NULL, type = "simple") {
  data <- "borough_sf"
  if (type == "simple") {
    data <- paste(data, type, sep = "_")
  }

  package <- "nycgeo"

  get_location(
    type = data,
    package = package,
    name = name,
    id = id,
    name_col = "borough_name",
    id_col = "borough_id"
  )
}

get_nyc_borough(name = "Manhattan")

If your location data is sourced from an ArcGIS MapServer or FeatureServer, you can use the name and name_col parameters from the underlying get_esri_data() function. This avoids the need to download the full dataset every time.

# get_anc looks up the Advisory Neighborhood Council
# Data from Open Data DC https://opendata.dc.gov/datasets/fcfbf29074e549d8aff9b9c708179291

get_anc <- function(name) {
  url <- "https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Administrative_Other_Boundaries_WebMercator/MapServer/1"

  get_location(
    type = url,
    name = name,
    name_col = "name"
  )
}

get_anc(name = "5B")

Location data can also be loaded from a URL with a GeoJSON or other spatial data file.

Accessing overlapping geographies

Since location supports both addresses and sf objects, you can pull individual locations without knowing the name or id of an area. For example, you can use an address:

# remotes::install_github("elipousson/mapbaltimore")

lookup_tract <- function(address) {
  get_location(
    type = "baltimore_tracts",
    package = "mapbaltimore",
    location = address
  )
}

lookup_tract("100 Holliday St, Baltimore, MD 21202")

You can also combine multiple approaches to create a look-up function that returns overlapping geography for a named characteristic. For example, the following function takes the name of a school and returns any Baltimore City neighborhoods that overlap with that school's attendance zone.

lookup_school_neighborhoods <- function(school_name) {
  school <-
    get_location(
      type = "bcps_es_zones_SY2021",
      package = "bcpss",
      name = school_name,
      name_col = "program_name_short",
      crs = 2804
    )

  school_neighborhoods <-
    get_location(
    type = "neighborhoods",
    package = "mapbaltimore",
    location = school
  )

  return(school_neighborhoods)
}

lookup_school_neighborhoods(school_name = "Eutaw-Marshburn E")

Get location data

As noted in the previous section, get_location() is largely built around get_location_data(). But, get_location_data() is also a helpful function just by itself.

While the data parameter supports all of the options for the type parameter described in the prior section, get_location_data() also supports named parameters for path or url.

Note: This vignette is a work in progress with additional details to be added soon.

params <- list(
  type = "council_districts",
  id = 12,
  dist = 0.125,
  diag_ratio = NULL,
  unit = "mi",
  package = "mapbaltimore",
  layers = c("streets", "neighborhoods", "trees")
)

district <-
  get_location(
    type = params$type,
    package = params$package,
    id = params$id
  )

district

Selecting a page size

You can use the get_paper function to look up one or more common paper sizes or standard image sizes:

paper_options <- get_paper(paper = NULL, standard = c("Twitter", "Instagram"))
knitr::kable(paper_options)

You can also use the geometry of any specified location to set the orientation of the page or the suggested aspect ratio using the sf_bbox_asp function:

sf_bbox_asp(sf::st_bbox(district))

sf_bbox_asp((sf::st_bbox(district)), orientation = TRUE)

Based on this information, it looks like this map way work well as an Instagram post.

params$paper <- "Instagram post"

# Get a paper by name 
paper <- 
  get_paper(
    paper = params$paper
  )

# Move width, height, aspect ratio (asp), and units (for map) into params
params$width <- paper$width
params$height <- paper$height
params$asp <- paper$asp
# NOTE: px units are not fully supported by all functions
# NOTE: units supports map-scale options ("in") rather than the unit parameter used by st_buffer_ext
params$units <- paper$units

There is one additional consideration in setting the aspect ratio for the map area: the aspect ratio of the content block after marings have been applied. While this is less significant for a Instagram post where full bleed images are appropriate, an example below shows how to get the aspect ratio of a plot, text, or map block after margins have been added to a page. The "px" units associated with the Instagram post paper cannot currently be used with the header and footer option so I passed "npc" units to manually set the margin rather than using the preset options.

get_asp(
  paper = "letter",
  block_asp = FALSE)

get_asp(
  paper = "letter",
  margin = c(1, 1, 1.5, 1),
  block_asp = TRUE)

Finally, the final selections can be used to create a bounding box that reduces the need to pass these same variables to all similar functions. This can also works as a way of effectively saving different "zoom levels" for a map based on different buffer units.

# This information 
district_bbox <-
  st_bbox_ext(
    x = district,
    dist = params$dist,
    diag_ratio = params$diag_ratio,
    asp = params$asp
  )
district_trees <-
  get_location_data(
    location = district_bbox,
    data = "trees",
    package = "mapbaltimore",
    filetype = "gpkg"
  )

gt::gt(dplyr::slice_head(district_trees, n = 10))
ggplot() +
  layer_location_data(
    data = district_trees,
    mapping = aes(color = condition),
    size = 0.3,
    alpha = 0.4
  ) +
  theme_legend(
    position = "bottomleft"
  ) +
  theme_text(
    font_family = "Fira Code"
  ) +
  labs(
    color = "Condition"
  ) +
  scale_color_brewer(palette = "RdYlGn") +
  layer_mask(
    data = district,
    dist = 100,
    color = "gray70",
    neatline = TRUE
  )


elipousson/overedge documentation built on Aug. 13, 2022, 7:41 p.m.