-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathREADME.Rmd
More file actions
247 lines (203 loc) · 10.5 KB
/
Copy pathREADME.Rmd
File metadata and controls
247 lines (203 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
---
title: "superblock"
output:
md_document:
variant: markdown_github
rmarkdown::html_vignette:
self_contained: no
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r opts, echo = FALSE}
knitr::opts_chunk$set (
collapse = TRUE,
warning = TRUE,
message = TRUE,
width = 120,
comment = "#>",
fig.retina = 2,
fig.path = "man/figures/README-"
)
```
[](https://github.com/UrbanAnalyst/superblock/actions/workflows/R-CMD-check.yaml)
[](https://app.codecov.io/gh/UrbanAnalyst/superblock)
# superblock
An R package to analyse potential
[superblocks](https://doi.org/10.1016%2Fj.cities.2024.105609). The following
example demonstrates the main functionality.
## Example
An example of the "Hansaviertel" of [Münster,
Germany](https://www.openstreetmap.org/#map=17/51.955569/7.639795). Note that
this entire document is dynamically-generated from the four lines of code shown
immediately below. All numerical values described in the text are then taken
from the actual data as downloaded from Open Street Map (OSM) at the time the
document was generated.
The first steps are to load the package and extract the necessary data:
```{r extract-data-fakey, message = FALSE, eval = FALSE}
library (superblock)
bbox <- c (7.63099, 51.95048, 7.66402, 51.96142)
hw_names <- c ("Bremer Straße", "Bremer Platz", "Wolbecker Straße", "Hansaring")
osmdat <- sb_osmdata_extract (bbox, hw_names)
```
```{r extract-data-for-real, message = FALSE, echo = FALSE}
library (superblock)
bbox <- c (7.63099, 51.95048, 7.66402, 51.96142)
hw_names <- c ("Bremer Straße", "Bremer Platz", "Wolbecker Straße", "Hansaring")
outer <- c (T, F, T, T)
# osmdat <- sb_osmdata_extract (bbox, hw_names, outer = outer)
osmdat <- readRDS ("osmdat.Rds")
```
### Summary
The analyses described in more detail below produce the following summary
statistics:
```{r summary, message = FALSE, echo = FALSE}
s <- sb_summary (osmdat)
prop_open <- sprintf ("%.1f", 100 * s$area_open / s$area_total)
prop_roads <- sprintf ("%.1f", 100 * s$area_hw / s$area_total)
prop_parking <- sprintf ("%.1f", 100 * s$area_parking / s$area_hw)
prop_other <- sprintf ("%.1f", 100 * (s$area_hw - s$area_road - s$area_parking) / s$area_hw)
park_res_prop <- sprintf ("%.1f", 100 * s$car_parks_per_res)
a_public <- s$area_open + s$area_hw - s$area_road - s$area_parking
a_public_adj <- s$area_open + s$area_hw
public_incr <- round (100 * (a_public_adj / a_public - 1))
```
```{r parking-times, echo = FALSE, warning = FALSE}
times <- sb_parking_times (osmdat, ntrials = 10, n_props = 20, prop_min = 0.7)
time_to_parking <- sprintf ("%.1f", times$time_to_parking + times$time_from_parking) [1]
```
```{r parking-per-km, echo = FALSE, warning = FALSE}
d <- sb_parking_km_per_empty (osmdat)
net <- superblock:::parking_as_dodgr_net (osmdat)
nspaces <- sum (net$np)
nspaces_filled <- round (0.3 * nspaces)
d_to_parking_fmt <- sprintf ("%.1f", d$d_to_parking [1])
d_tot_to_parking <- round (d$d_to_parking [1] * 0.3 * nspaces)
parking_efficiency <- round (100 * (1 - d_tot_to_parking / nspaces_filled))
# Then get lengths of streets:
names <- unique (net$name [which (!is.na (net$name))])
net$flow <- 1
net1 <- dodgr::merge_directed_graph (net)
lens <- vapply (names, function (n) {
index <- which (net1$name == n)
sum (net1$d [index])
}, numeric (1L))
lens_within <- lens [which (!names (lens) %in% osmdat$hw_names)]
max_len <- sprintf ("%.1f", max (lens) / 1000)
max_len_within <- sprintf ("%.1f", max (lens_within) / 1000)
ten_drivers <- round (10 * (max (lens) + max (lens_within)) / 1000)
```
- Hansaviertel covers `r round(s$area_total)` Hectares
- `r prop_open`% is public open space
- `r prop_roads`% is occupied by roads, of which:
- `r prop_parking`% is used for parking cars, and
- `r prop_other`% is available for general public usage
- There are only enough car parking spaces for `r park_res_prop`% of all
residents, who thereby occupy `r prop_parking`% of the total open street
space.
There are [several](https://www.openstreetmap.org/node/11782383432) large
[public](https://www.openstreetmap.org/way/110526495) parking
[facilities](https://www.openstreetmap.org/node/10275462175) very close to
Hansaviertel, and so cars could easily park there and free up this
`r prop_parking`% of the street space for use by everybody. That would increase
the total proportion of available public space by `r public_incr`%. The average
time needed to drive to one of these parking facilities and walk back home
within Hansaviertel is `r time_to_parking` minutes. The results below show that
times needed to drive around searching for parking spaces generally exceed that
once around 90% of all parking spaces are full.
Moreover, this search for the `r nspaces` available parking spaces within
Hansaviertel amounts to the `r park_res_prop`% of residents who are able to
park driving a total distance of around `r nspaces_filled` km every evening to
fill these spaces. Were they to park in the nearby parking facilities, this
total distance would reduce to only `r d_tot_to_parking` km.
**By this measure, use of nearby public parking facilities would be
`r parking_efficiency`% more efficient than this `r prop_parking`% of available
street space being otherwise used by only `r park_res_prop`% of all residents.
Using nearby public parking facilities would also increase space available for
general public usage within Hansaviertel by `r public_incr`%.**
Most of these results can easily be generated by calling the `sb_summary()`
function:
```{r sb-summary}
sb_summary (osmdat)
```
The additional statistics described above on distances driven and times taken
to search for parking spaces are generated from functions described in the
following section.
---
### Analysis of parking times
There are two additional functions to estimate how long people spend driving
around searching for car parking spaces, and how far they actually drive.
#### Individual times search for parking spaces
The first function estimates the time taken on average for each resident of the
superblock to find a car parking space, as a function of the proportion of
available car parking spaces. Results are based on simulations using actual
data for the specified superblock to estimate how long it takes on average to
fill all of the remaining parking spaces.
The results are compared to equivalent times to drive to the nearest large
parking facility ("garage" in the graph below), to park a car, and then walk
back to the place of residence.
```{r parking-times-plot, echo = FALSE, warn = FALSE}
# times <- sb_parking_times (osmdat, ntrials = 10, n_props = 20, prop_min = 0.7)
plot (times)
```
```{r parking-times-fakey, eval = FALSE}
times <- sb_parking_times (osmdat)
plot (times)
```
The results shows how long it takes to find a parking space for an average
attempt ("park(50%)"), for one out of every five attempts ("park(80%)", or one
working day per week), and for one out of every ten attempts ("park(90%)", or
one working day every two weeks). Above around 97-98% occupancy, which is the
general state most nights, an "average" attempt may still take under 5 minutes,
yet one out of four times will take 10 minutes or more, and one out of ten
times it will take more than half an hour. The horizontal lines shows the time
it would take on average for all residents of the area to drive directly to a
nearby large parking facility ("garage"), park, and walk back. Beyond around
95% occupancy, it is always quicker to park in a garage and walk back.
#### Total distances driven while searching for parking spaces
The average times to find parking spaces shown above are only high in extreme
cases (the 90% line), and when almost all parks are full. Nevertheless, most
parking spaces are indeed completely full most nights of the week, suggesting
the some people must experience these extremes most days. An additional
function generates a more useful "overview" statistic
by estimating the total distances driven by everybody while filling all parking
spaces, assuming that 70% of parking spaces are initially full. This is
equivalent to assuming that 30% of residents use their cars on a daily basis,
with results for other initial proportions readily seen from the graph below.
```{r parking-per-km-plot-fakey, eval = FALSE}
d <- sb_parking_km_per_empty (osmdat)
plot (d$prop_full, d$d,
type = "l", col = "red", lwd = 2,
xlab = "Initial proportion filled",
ylab = "Distance per empty car park until completely filled (in km)"
)
```
```{r parking-per-km-plot, echo = FALSE}
plot (d$prop_full, d$d,
type = "l", col = "red", lwd = 2,
xlab = "Initial proportion filled",
ylab = "Distance per empty car park until completely filled (in km)"
)
```
Because filling the final few spaces takes so long, as shown in the first graph
above, and people have to drive so far to fill them, the overall distance
driven to fill all spaces is actually quite long. The block has around
`r nspaces` parking spaces in total, so with an initial proportion filled of
70%, people have to drive a total of around 1km times 0.3 × `r nspaces` =
`r nspaces_filled`km. While this may seem extreme, consider that most of this
distance is covered by the last few people driving to find parking spaces, who
are forced to drive several kilometres. The longest street within the block is
`r max_len_within`km, while one of the surrounding streets is `r max_len`km.
Ten people driving along both of those streets will cover `r ten_drivers`km,
which is `r round(100*ten_drivers/nspaces_filled)`% of the total distance of
`r nspaces_filled` km covered by that same number of drivers.
The average distance needed to be driven to the public parking facility nearest
to every building in Hansaviertel is only `r d_to_parking_fmt`km, so the
`r nspaces_filled` people searching for parking spaces would have to drive only
`r round(d$d_to_parking[1] * nspaces_filled)`km in total. Thus, as summarised
at the outset, the use of nearby parking facilities would be
`r parking_efficiency`% more efficient than parking within Hansaviertel itself.
In terms of time, if the average driving speed while searching for a
parking space is 20km/hr, then those 186 people each take an average of
1/20th of an hour, or only 3 minutes, to find a park, yet aggregated
over all free parking spaces, that amounts to a total of
`r nspaces_filled / 20` hours for everybody to fill all remaining car
parks.