Parking Lots, Parking Minimums, and All That

In 2019, Houston city council passed a ground-breaking ordinance that removed parking minimums for parts of Midtown and EaDo. The city’s climate action plan, which was adopted in 2020, calls for an end to all minimum parking requirements by 2030.

I thought it would be interesting to look at parking in The Heights, so I put together this little study. Originally I wanted to do the entire city, but I could not find a source of data on parking lots covering the whole city, so that was out. For this study I used OpenStreetMap, and added polygons for the parking lots in the west Heights. The editor is pretty easy to use, but that was still quite a few hours of work. I basically cover the area delineated by 20th street to the north, 11th street to the south, Durham to the west, and Heights Boulevard to the east.

One item of interest in the Heights is that the area along 19th street, which is largely businesses, has no parking minimums because it was built prior to those requirements. We’ll look at the different business corridors to see how they compare.

I’m also interested in how many people have easy access to businesses, either by walking or bicycling, and also how much potential property tax revenue is being lost by covering land with parking lots instead of buildings.

A good overview of many of the issues may be found in this paper from the Kinder Institute.

Read in the necessary datasets

First let’s establish an AOI_xy

The buffer is defined along the streets of interest, and the AOI_xy is 10,000 feet larger to ensure we grab the needed data.

###{r initialize, class.source = 'fold-show'}

#######################################
#   AOI_xy
#######################################

#   Start at 19th and Shepherd, east to Yale, south to 11th, west to Shepherd

Buffer_coord <- tribble(~Lat,      ~Lon,
                        29.802783, -95.410146,
                        29.802935, -95.399204,
                        29.790674, -95.398971,
                        29.790514, -95.409865,
                        29.802783, -95.410146)

Study_box_ll <- Buffer_coord %>%
  sf::st_as_sf(coords = c("Lon", "Lat"), crs = google_crs) %>%
  summarise(geometry = sf::st_combine(geometry)) %>%
  sf::st_cast("LINESTRING")

AOI_xy <- Study_box_ll %>% #  enlarge by 10,000 feet
  sf::st_transform(crs=CoH_crs) %>% 
  sf::st_line_sample(n=250) %>% 
  sf::st_buffer(dist=10000, endCapStyle="SQUARE")

AOI_ll <- AOI_xy %>% sf::st_transform(crs=google_crs)

#   Buffer used to extract parking lots for the study

Parking_select_xy <- Study_box_ll %>% #  enlarge by 1000 feet
  sf::st_transform(crs=CoH_crs) %>% 
  sf::st_line_sample(n=250) %>% 
  sf::st_buffer(dist=1000, endCapStyle="ROUND")

bbox_xy <- sf::st_bbox(sf::st_transform(Study_box_ll, crs=CoH_crs))
bbox_ll <- sf::st_bbox(Study_box_ll)
bbox_AOI_ll <- sf::st_bbox(AOI_ll)

#   Set default basemap
tmap::tmap_options(basemaps="OpenStreetMap")

tmap::tmap_mode("view") # set mode to interactive plots

tmap::tm_shape(sf::st_as_sf(as_tibble(AOI_ll) %>% mutate(Label="AOI"))) +
  tmap::tm_polygons(alpha=0.3, col="blue")+
tmap::tm_shape(sf::st_as_sf(as_tibble(sf::st_cast(Study_box_ll, "POLYGON")) %>% mutate(Label="Study area"))) +
  tmap::tm_polygons(alpha=0.3, col="red")+
  tmap::tm_scale_bar()+
  tmap::tmap_options(unit = "mi") +
  tmap::tm_layout(title="Area of Interest and Study Area")

I need a freeway polygon

It is painful for pedestrians and bicyclists to cross under the freeway. The roads pretty effectively segregate the neighborhood. I will honor that by clipping my distance polygons with the freeways that basically define the boundaries of the Heights.

#   Get freeway data

Freeways <- 
  osmdata::getbb(place_name = "Houston") %>% 
  osmdata::opq(timeout=50)%>% # Build query
  osmdata::add_osm_feature(key = "highway", 
                  value = c("motorway", 
                            "motorway_link" 
                            )) %>% # select the big roads
  osmdata::osmdata_sf(quiet=FALSE) 
## Issuing query to Overpass API ...
## Announced endpoint: z.overpass-api.de/api/
## Query complete!
## converting OSM data to sf format
#   These are the freeways that will define a polygon
Fwy_names <- paste0(c("North Loop", "Katy Freeway", "West Loop North", 
               "North Freeway", "North Loop West"), collapse="|")

Selected_fwys <- Freeways$osm_lines %>% 
  filter(stringr::str_detect(name, Fwy_names)) %>% 
  select(osm_id, name)

#   Create polygons and (interactively) figure out which one is wanted

Fwy_poly <- Selected_fwys %>% 
  st_union() %>% 
  st_polygonize() %>% 
  st_cast() %>% 
  as_tibble() %>% 
  mutate(id=row_number()) %>% 
  st_as_sf() %>% 
  filter(id==5)

#     Let's take a look

tmap::tmap_options(basemaps="OpenStreetMap")
tmap::tmap_mode("view") # set mode to interactive plots
## tmap mode set to interactive viewing
tmap::tm_shape(sf::st_as_sf(as_tibble(Fwy_poly) %>% mutate(Label="Freeways"))) +
  tmap::tm_polygons(alpha=0.3, col="blue")+
  tmap::tm_scale_bar()+
  tmap::tmap_options(unit = "mi") +
  tmap::tm_layout(title="Freeway-defined Study Area Cutoff")
## Warning in CPL_transform(x, crs, aoi, pipeline, reverse, desired_accuracy, :
## GDAL Error 1: PROJ: proj_as_wkt: DatumEnsemble can only be exported to WKT2:2019

Load parking lots

From OpenStreetMap we will load the digitized parking lots that I digitized for the study.

#######################################
#   Parking lots
#######################################

parking <- 
  osmdata::getbb(place_name = "Houston") %>% 
  osmdata::opq(timeout = 50) %>% # Build query
  osmdata::add_osm_feature(key = "amenity", 
                           value = "parking" 
                            ) %>% 
  osmdata::osmdata_sf(quiet=FALSE) # turn into an sf file

#   Extract parking lots in the AOI that are near the study box 

Parking_TF <- sf::st_contains( Parking_select_xy, 
                               sf::st_transform(
                                    sf::st_as_sfc(parking$osm_polygons,
                                              crs=google_crs),
                                    crs=CoH_crs))

Parking_ll <- parking$osm_polygons[unlist(Parking_TF),] %>% 
  select(osm_id, amenity, surface)


tmap::tmap_options(basemaps="OpenStreetMap")
tmap::tmap_mode("view") # set mode to interactive plots

tmap::tm_shape(Parking_ll) +
  tmap::tm_polygons(alpha=0.8, col="blue")+
  tmap::tm_scale_bar()+
  tmap::tmap_options(unit = "mi") +
  tmap::tm_layout(title="Parking lots")
#######################################
#   Census data
#######################################

path <- "/home/ajackson/Dropbox/Rprojects/Curated_Data_Files/Census_data/"


#######################################
#   HCAD data
#######################################