library(tidyverse)
library(leaflet)
library(osrm)
library(sf)San Antonio and Austin Isochrones
Goal
Find properties for sale that are within a 50 minute drive of both Austin and San Antonio downtowns.
Coordinates of Austin and San Antonio Centers
points <-
tibble::tribble(
~Name,~Lat,~Long,
"San Antonio", 29.424349, -98.491142,
"Austin", 30.266666, -97.733330
)
pointsCopy <- pointspoints <- points |>
st_as_sf(coords = c("Long", "Lat")) |>
st_set_crs("WGS84")Isochrone
An isochrone map in geography and urban planning is a map that depicts the area accessible from a point within a certain time threshold.
saDrive <-
osrmIsochrone(loc = points |> filter(Name == "San Antonio") |> select(geometry),
breaks = seq(from = 0,
to = 50,
by = 50),
res=50)
austinDrive <-
osrmIsochrone(loc = points |> filter(Name == "Austin") |> select(geometry),
breaks = seq(from = 0,
to = 50,
by = 50),
res=50)Powered by OpenStreetMap, two isochrones are generated. The isochrones begin in the center of the two cities and extend as far as you can drive in 50 minutes under ideal conditions.
leaflet() |>
setView(mean(pointsCopy$Long), mean(pointsCopy$Lat), zoom = 8) |>
addTiles() |>
addMarkers(lng = pointsCopy$Long, pointsCopy$Lat, label = pointsCopy$Name) |>
addPolygons(fill=TRUE, stroke=TRUE, color = "black",
fillColor = "blue",
weight=0.5, fillOpacity=0.2,
data = saDrive$geometry,
group = "Drive Time") |>
addPolygons(fill = T, stroke = T, color = "black",
fillColor = "red",
weight=.5, fillOpacity = .2,
data = austinDrive,
group = "Drive Time")Intersection
Using the R package sf, a geoprocessing package, the intersection of the two isochrones is determined. A polygon boundary is mapped to show the extent of the intersection. Properties within this boundary are 50 minutes from both Austin and San Antonio centers.
sf_use_s2(FALSE)
inter <-
st_intersection(saDrive$geometry,austinDrive$geometry)
interCenter <-
st_centroid(inter)leaflet() |>
setView(-98.043237, 29.762738, zoom = 11) |>
addTiles() |>
addPolygons(fill=F, stroke=TRUE, color = "red",
data = inter,
group = "Drive Time")Properties for Sale
The next step would be to connect with a real estate API such as Zillow to dynamically import current listings, however I couldn’t obtain access. Then, listings that are contained in the boundary would be displayed.
adresses <-
tribble(
~Address,~Latitude,~Longitude,~Value,~SqFt,
"110 Highwater Ln, New Braunfels, TX 78130",29.769070,-98.037140,1325000,1792,
"5744 Tug, New Braunfels, TX 78130",29.752520,-98.042560,689990,3050
)leaflet() |>
setView(-98.043237, 29.762738, zoom = 12) |>
addTiles() |>
addPolygons(fill=F, stroke=TRUE, color = "red",
data = inter,
group = "Drive Time") |>
addMarkers(lng = adresses$Longitude, adresses$Latitude, label = adresses$Address)Next Steps
Connect to a real estate API to collect current listings in a geographic area. For instance, the county the center of the polygon resides in. Geocode the addresses. Geocoding is the process of converting addresses to geographic coordinates. Next, using the sf package, find those listings’ coordinates that are contained by the intersection polygon. Include attributes such as value and square footage.
Use Extension
This technique can be used in a variety of analyses:
- Use census data to calculate disparity in access to hospitals, grocery stores, libraries, and schools among races, income groups, and age groups.
- Mapping walkability of urban centers
- Comparison of public transit vs. personal vehicle commute times