The goal of municoder is to allow users to programmatically navigate the municode.com API, including all of the ordinances hosted therein.
Installation
You can install the development version of library(municoder)
like so:
renv::install("wcurrangroome/municoder")
Check the spatial coverage of municode.com-listed ordinances
all_states = municoder::get_states()
all_clients = all_states %>%
dplyr::pull(state_abbreviation) %>%
purrr::discard(~ str_detect(.x, "Tribes")) %>% ## "Tribes" throws an error for some reason
purrr::map_dfr(~ get_clients_in_state(.x))
states_sf = tigris::states(cb = TRUE, progress_bar = FALSE) %>%
dplyr::filter(GEOID < 60) %>%
tigris::shift_geometry() %>%
dplyr::left_join(
all_clients %>% dplyr::count(state_abbreviation),
by = c("STUSPS" = "state_abbreviation"))
#> Retrieving data for the year 2021
states_sf %>%
ggplot2::ggplot() +
ggplot2::geom_sf(ggplot2::aes(fill = n)) +
ggplot2::geom_sf(data = states_sf %>% dplyr::filter(n == 0), fill = "lightgrey") +
ggplot2::labs(
title = "municode.com Has Coverage across All 51 States",
subtitle = "Number of entities listed on municode.com, by state",
fill = "Entities with ordinances on municode.com" %>% str_wrap(30)) +
ggplot2::scale_fill_continuous(trans = "reverse") +
urbnthemes::theme_urbn_map()
Explore an ordinance’s table of contents (TOC):
## this gives us the client_id
alexandria_client_id = all_clients %>%
dplyr::filter(state_name == "Virginia", client_name == "Alexandria") %>%
dplyr::pull(client_id)
## this gives us `product_name`s and associated `product_id`s
alexandria_zoning_product_id = municoder::get_client_content(alexandria_client_id) %>%
dplyr::filter(product_name == "Zoning") %>%
dplyr::pull(product_id)
alexandria_zoning_job_id = municoder::get_jobs_latest(product_id = alexandria_zoning_product_id) %>%
dplyr::pull(id)
## this gives us `id`s for each primary component of the zoning ordinance
municoder::get_codes_toc(
job_id = alexandria_zoning_job_id,
product_id = alexandria_zoning_product_id)
#> # A tibble: 17 × 7
#> toc_id toc_heading id heading has_children parent_id children
#> <chr> <chr> <chr> <chr> <lgl> <chr> <lgl>
#> 1 12429 Zoning THZOORALVI THE ZONING… FALSE 12429 NA
#> 2 12429 Zoning SUHITA Supplement… FALSE 12429 NA
#> 3 12429 Zoning ARTIGERE ARTICLE I.… TRUE 12429 NA
#> 4 12429 Zoning ARTIIDE ARTICLE II… TRUE 12429 NA
#> 5 12429 Zoning ARTIIIREZORE ARTICLE II… TRUE 12429 NA
#> 6 12429 Zoning ARTIVCOOFINZO ARTICLE IV… TRUE 12429 NA
#> 7 12429 Zoning ARTVMIUSZO ARTICLE V.… TRUE 12429 NA
#> 8 12429 Zoning ARTVISPOVZO ARTICLE VI… TRUE 12429 NA
#> 9 12429 Zoning ARTVIISUZORE ARTICLE VI… TRUE 12429 NA
#> 10 12429 Zoning ARTVIIIOREPALO ARTICLE VI… TRUE 12429 NA
#> 11 12429 Zoning ARTIXSI ARTICLE IX… TRUE 12429 NA
#> 12 12429 Zoning ARTXHIDIBU ARTICLE X.… TRUE 12429 NA
#> 13 12429 Zoning ARTXIDEAPPR ARTICLE XI… TRUE 12429 NA
#> 14 12429 Zoning ARTXIINONO ARTICLE XI… TRUE 12429 NA
#> 15 12429 Zoning ARTXIIIENMA ARTICLE XI… TRUE 12429 NA
#> 16 12429 Zoning APXAZOMAAM APPENDIX A… FALSE 12429 NA
#> 17 12429 Zoning TAAM TABLE OF A… FALSE 12429 NA
And finally pull out the text for individual sections of an ordinance.
We can see that the “Purpose” statements for each of Alexandria’s residential zones tell us quite a bit about the rationale for each zone. For example, we might notice that the RMF zone is the only zone with a “Purpose” statement that refers to housing affordability–raising the question why Alexandria’s other zones aren’t also designed to further housing affordability–and that is also the only zone with a “Purpose” that does not explicitly refer to a cap on unit density.
municoder::get_codes_content(
product_id = alexandria_zoning_product_id,
node_id = "ARTIIIREZORE") %>%
dplyr::pull(id) %>%
purrr::map_dfr(~ get_codes_content(product_id = alexandria_zoning_product_id, node_id = .x)) %>%
dplyr::filter(
!is.na(content),
stringr::str_detect(heading, "Purpose")) %>%
dplyr::pull(content)
#> [1] " The R-20 zone is established to provide and maintain land areas for low density residential neighborhoods of single-unit, two-unit, and multi-unit up to four units dwellings on 20,000 square foot lots. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in a residential neighborhood are also permitted. "
#> [2] " The R-12 zone is established to provide and maintain land areas for low density residential neighborhoods of single-unit, two-unit, and multi-unit up to four units dwellings on 12,000 square foot lots. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in a residential neighborhood are also permitted. "
#> [3] " The R-8 zone is established to provide and maintain land areas for low density residential neighborhoods of single-unit, two-unit, and multi-unit up to four units dwellings on 8,000 square foot lots. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in a residential neighborhood are also permitted. "
#> [4] " The R-5 zone is established to provide and maintain land areas for low density residential neighborhoods of single-unit, two-unit, and multi-unit up to four units dwellings on 5,000 square foot lots. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in a residential neighborhood are also permitted. "
#> [5] " The R-2-5 zone is established to provide and maintain land areas for low density residential neighborhoods of single-unit, two-unit, and multi-unit up to four units dwellings on 5,000 square foot lots. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in a residential neighborhood are also permitted. "
#> [6] " The RA zone is established to provide and maintain land areas for medium density residential neighborhoods in which apartments predominate and in which single-unit, two-unit and townhouse development is permitted. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in such residential neighborhoods are also permitted. "
#> [7] " The RB zone is established to provide and maintain land areas for medium density residential neighborhoods in which single-unit, two-unit, and townhouse dwellings are permitted. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in such residential neighborhoods are also permitted. "
#> [8] " The RCX zone is established to provide and maintain land areas for medium density apartment buildings and to permit limited commercial uses in such structures. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in such residential neighborhoods are also permitted. "
#> [9] " The RC zone is established to provide and maintain land areas for high density apartment buildings and to permit limited commercial uses in such structures. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in such residential neighborhoods are also permitted. "
#> [10] " The RM zone is established to provide and maintain land areas for medium density residential neighborhoods of single-unit, two-unit and townhouse dwellings. Nonresidential uses of a noncommercial nature which are related to, supportive of and customarily found in such residential neighborhoods are also permitted. "
#> [11] " The RS zone is established to provide land areas for low to medium density townhouse development of approximately 15 units per acre which may be appropriate for infill sites in proximity to neighborhoods of single-family detached homes. "
#> [12] " The RT zone is established to provide land areas for low density residential townhouse development at approximately nine units per acre which may be appropriate for infill sites in proximity to neighborhoods of low density single-unit, two-unit, and multi-unit up to four units dwellings. "
#> [13] " The RMF zone is established to provide land areas for multi-unit residential development and to enhance or preserve long-term affordability of housing. The zone would also permit limited neighborhood-serving commercial uses. "