IST = st_sfc(st_point(c(-9.1397404, 38.7370168)), crs = 4326) # create a point
IST$coordinates = st_coordinates(IST)
# BUFFERist500 = st_buffer(IST, dist = 500) # non projected - results may be weird
BUFFERist500 = geo_buffer(IST[1], dist = 500) # from stplnar, to make sure it is in meters.
BUFFERist2000 = geo_buffer(IST[1], dist = 2000)
mapview(BUFFERist500) + mapview(BUFFERist2000, alpha.regions = 0.5)14 Buffers vs. Isochones
We will use the stplnar package to create buffers in meters, and the openrouteservice package to create isochrones.
See the ors setup instructions for more details.
14.1 Buffer
Represent a buffer of 500 m and 2000 m from IST1.
14.2 Isochrone
Isochrone from 1 point - distance
We use again the openrouteservice r package.
ISOCist = ors_isochrones(
IST$coordinates,
profile = "foot-walking",
range_type = "distance", # or time
range = c(500, 1000, 2000),
output = "sf",
api_key = Sys.getenv("ORS_USHIFT")
)
ISOCist = arrange(ISOCist, -value) |> # to make the larger polygons on top of the table so the are displayed behind.
select(-center) # unnecessary variablemapview(ISOCist, zcol = "value", alpha.regions = 0.5)As you can see, the distance buffer of 500m is larger than the isochrone of 500m. Actually we can measure their area of reach.
ISOCist$area = st_area(ISOCist)
BUFFERist500$area = st_area(BUFFERist500)
BUFFERist2000$area = st_area(BUFFERist2000)
ratio1 = BUFFERist500$area / ISOCist$area[ISOCist$value == 500] # 1.71
ratio2 = BUFFERist2000$area / ISOCist$area[ISOCist$value == 2000] # 1.22The euclidean buffer of 500m is 1.7 times larger than its isochrone, and the buffer of 2000m is 1.23 times larger than its isochrone.
Isochrone from more than 1 point - time
For this purpose we will use the high schools dataset.
# import schools
SCHOOLS = st_read("../geo/SCHOOLS_basicsec.gpkg", quiet = TRUE)
SCHOOLS$coordinates = st_coordinates(SCHOOLS) # create coordinate variable
SCHOOLShigh = SCHOOLS |>
filter(Nivel == "Secundario") # filter the high schools
SCHOOLShigh = SCHOOLShigh |> mutate(id = 1:nrow(SCHOOLShigh)) # provide and id
# list of XY coordinates for ORS
coord_schools = data.frame(lon = SCHOOLShigh$coordinates[, 1],
lat = SCHOOLShigh$coordinates[, 2])
# id = SCHOOLShigh$id)And proceed with the time isochrones, for a range of 20 min, with 5 min intervals.
ISOCschools = ors_isochrones(
coord_schools,
profile = "foot-walking",
range_type = "time", # or distance
range = 20*60, # 20 minutes in seconds
interval = 5*60, # to have intervals of 5 minutes
attributes = "area", #you can directly get area, population, and so on.
output = "sf",
api_key = Sys.getenv("ORS_USHIFT")
)
ISOCschools = arrange(ISOCschools, -value) |> # larger polygons on top of the table so the are displayed behind.
select(-center)And now merge this information with the schools’ names.
ISOCschools = ISOCschools |>
mutate(id = group_index + 1, # because group_index starts at 0
value = value/60) |>
left_join(SCHOOLShigh |>
st_drop_geometry() |>
select(id, INF_NOME, Alunos))mapview(ISOCschools, zcol = "value", alpha.regions = 0.5)And estimate areas for the 20min isochrones
summary(ISOCschools$area[ISOCschools$value==20])/1000000 # in km² Min. 1st Qu. Median Mean 3rd Qu. Max.
3.295 4.303 5.363 5.098 5.804 6.511
Here I selected only the first variable because now we also have the coordinates information (unnecessary for this procedure)↩︎