Distances on Directed Graphs in R
1---
2title: "dodgr: Distances on Directed Graphs in R"
3output:
4 md_document:
5 variant: markdown_github
6
7 rmarkdown::html_vignette:
8 self_contained: no
9---
10
11<!-- README.md is generated from README.Rmd. Please edit that file -->
12
13```{r opts, echo = FALSE}
14knitr::opts_chunk$set (
15 collapse = TRUE,
16 warning = TRUE,
17 message = TRUE,
18 width = 120,
19 comment = "#>",
20 fig.retina = 2,
21 fig.path = "README-"
22)
23```
24
25[](https://github.com/UrbanAnalyst/dodgr/actions?query=workflow%3AR-CMD-check)
27[](https://app.codecov.io/gh/UrbanAnalyst/dodgr)
28[](https://www.repostatus.org/#active)
29
30[](https://cran.r-project.org/package=dodgr)
31[](https://cran.r-project.org/package=dodgr)
32[](https://bestpractices.coreinfrastructure.org/projects/1396)
33
34# dodgr: Distances on Directed Graphs in R
35
36`dodgr` is an R package for efficient calculation of many-to-many pairwise
37distances on dual-weighted directed graphs, for aggregation of flows throughout
38networks, and for highly realistic routing through street networks (time-based
39routing considering incline, turn-angles, surface quality, everything).
40
41Note that most `dodgr` algorithms implement parallel computation with the
42[`RcppParallel` library](https://rcppcore.github.io/RcppParallel/), and by
43default use the maximal number of available cores or threads. If you do not
44wish `dodgr`to use all available threads, please reduce the number manually by
45first specifying a value via
46```{r num_threads, eval = FALSE}
47RcppParallel::setThreadOptions (numThreads = 1L) # or desired number
48```
49
50
51## What's so special?
52
53Four aspects. First, while other packages exist for calculating distances on
54directed graphs, notably [`igraph`](https://igraph.org/r/), even that otherwise
55fabulous package does not (readily) permit analysis of *dual-weighted* graphs.
56Dual-weighted graphs have two sets of weights for each edge, so routing can be
57evaluated with one set of weights, while distances can be calculated with the
58other. A canonical example is a street network, where *weighted distances* are
59assigned depending on mode of transport (for example, weighted distances for
60pedestrians on multi-lane vehicular roads are longer than equivalent distances
61along isolated walking paths), yet the desired output remains direct,
62unweighted distances. Accurate calculation of distances on street networks
63requires a dual-weighted representation. In **R**, `dodgr` is currently the
64only package that offers this functionality (without excessive data wrangling).
65
66Second, while [`igraph`](https://igraph.org/r/) and almost all other routing
67packages are primarily designed for one-to-one routing, `dodgr` is specifically
68designed for many-to-many routing, and will generally outperform equivalent
69packages in large routing tasks.
70
71Third, `dodgr` goes beyond the functionality of comparable packages through
72including routines to aggregate flows throughout a network, through specifying
73origins, destinations, and flow densities between each pair of points.
74Alternatively, flows can be aggregated according to a network dispersal model
75from a set of origin points and associated densities, and a user-specified
76dispersal model.
77
78Fourth and finally, `dodgr` implements highly realistic and fully-customisable
79profiles for routing through street networks with various modes of transport,
80and using either distance- or time-based routing. Routing can include such
81factors as waiting times at traffic lights, delays for turning across oncoming
82traffic, access restrictions, and the effects of elevation on both cyclists and
83pedestrians. See the dedicated vignette on [street networks and
84time-based routing](https://UrbanAnalyst.github.io/dodgr/articles/times.html) for
85more detail.
86
87
88## Installation
89
90You can install latest stable version of `dodgr` from CRAN with:
91```{r cran-installation, eval = FALSE}
92install.packages ("dodgr") # current CRAN version
93```
94Alternatively, current development versions can be installed using any of the
95following options:
96```{r gh-installation, eval = FALSE}
97# install.packages("remotes")
98remotes::install_git ("https://git.sr.ht/~mpadge/dodgr")
99remotes::install_git ("https://codeberg.org/UrbanAnalyst/dodgr")
100remotes::install_bitbucket ("UrbanAnalyst/dodgr")
101remotes::install_gitlab ("UrbanAnalyst/dodgr")
102remotes::install_github ("UrbanAnalyst/dodgr")
103```
104Then load with
105```{r library}
106library (dodgr)
107packageVersion ("dodgr")
108```
109
110## Important Note
111
112While `dodgr` works with any arbitrary networks, it also includes numerous
113functions explicitly intended to be applied to geodesic coordinates, which are
114identified whenever input data have columns labelled "longitude" and
115"latitude", or similar. Coordinates for such data must be in the EPSG:4326
116(WGS84) coordinate system. `dodgr` treats coordinates as numbers only, and it
117is up to the user to ensure appropriate transformation to WGS84 coordinates
118prior to submitting data to `dodgr` functions.
119
120## Usage: Sample Data and `dodgr` networks
121
122To illustrate functionality, the package includes an example data set
123containing the Open Street Map network for [Hampi,
124India](https://www.openstreetmap.org/#map=15/15.3368/76.4601) (a primarily
125pedestrian village in the middle of a large World Heritage zone). These data
126are in [Simple Features (`sf`)](https://cran.r-project.org/package=sf) format,
127as a collection of `LINESTRING` objects. `dodgr` represents networks as
128a simple rectangular graph, with each row representing an edge segment between
129two points or vertices. `sf`-format objects can be converted to equivalent
130`dodgr` representations with the `weight_streetnet()` function:
131```{r hampi}
132class (hampi)
133dim (hampi)
134graph <- weight_streetnet (hampi, wt_profile = "foot")
135class (graph)
136dim (graph)
137```
138The `sf`-format network contained `r nrow (hampi)` `LINESTRING` objects, with
139the `weight_streetnet()` function decomposing these into `r format (nrow (graph),
140big.mark = ",")` distinct edges, indicating that the `sf` representation had
141around `r round (nrow (graph) / nrow (hampi))` edges or segments in each
142`LINESTRING` object. The `dodgr` network then looks like this:
143```{r hampi-net-fakey, eval = FALSE}
144head (graph)
145```
146```{r hampi-net, echo = FALSE}
147knitr::kable (head (graph))
148```
149
150The `geom_num` column maps directly onto the sequence of `LINESTRING` objects
151within the `sf`-formatted data. The `highway` column is taken directly from
152Open Street Map, and denotes the kind of "highway" represented by each edge. The
153`component` column is an integer value describing which of the connected
154components of the network each edge belongs to (with `1` always being the
155largest component; `2` the second largest; and so on).
156
157Note that the `d_weighted` values are often greater than the geometric
158distances, `d`. In the example shown, `service` highways are not ideal for
159pedestrians, and so weighted distances are slightly greater than actual
160distances. Compare this with:
161```{r hampi-net-faken2, eval = FALSE}
162head (graph [graph$highway == "path", ])
163```
164```{r hampi-net2, echo = FALSE}
165knitr::kable (head (graph [graph$highway == "path", ]))
166```
167
168A `"path"` offers ideal walking conditions, and so weighted distances are equal
169to actual distances.
170
171
172
173
174
175## Usage: Distances and Times
176
177The many-to-many nature of `dodgr` means that the function to calculate
178distances,
179[`dodgr_distances()`](https://UrbanAnalyst.github.io/dodgr/reference/dodgr_distances.html)
180or, for street networks, times,
181[`dodgr_times()`](https://UrbanAnalyst.github.io/dodgr/reference/dodgr_times.html),
182accepts two vectors or matrices of routing
183points as inputs (describing origins and destinations), and returns
184a corresponding matrix of pairwise distances. If an input graph has columns for
185both distances and weighted distances, and/or times and weighted times, the
186weighted versions are used to determine the effectively shortest or fastest
187routes through a network, while actual distances or times are summed along the
188routes to calculate final values. It is of course also possible to calculate
189distances along fastest routes, times along shortest routes, or any combination
190thereof, as detailed in the package vignette on [street networks and time-based
191routing](https://UrbanAnalyst.github.io/dodgr/articles/times.html).
192
193Routing points can, for example, be randomly selected from the vertices of a
194graph. The vertices can in turn be extracted with the `dodgr_vertices()`
195function:
196```{r verts-fakey, eval = FALSE}
197v <- dodgr_vertices (graph)
198head (v)
199```
200```{r verts, echo = FALSE}
201v <- dodgr_vertices (graph)
202knitr::kable (head (v))
203```
204
205For OSM data extracted with the `osmdata` package (or, equivalently, via the
206`dodgr::dodgr_streetnet()` function), each object (vertices, ways, and
207high-level relations between these objects) is assigned a unique identifying
208number. These are retained both in `osmdata` and `dodgr`, as the `way_id` column
209in the above `graph`, and as the `id` column in the vertices. Random vertices
210may be generated in this case through selecting `id` values:
211```{r random-verts}
212from <- sample (v$id, size = 20)
213to <- sample (v$id, size = 50)
214d <- dodgr_dists (graph = graph, from = from, to = to)
215dim (d)
216```
217Alternatively, the points may be specified as matrices of geographic
218coordinates:
219```{r}
220from_x <- min (graph$from_lon) + runif (20) * diff (range (graph$from_lon))
221from_y <- min (graph$from_lat) + runif (20) * diff (range (graph$from_lat))
222to_x <- min (graph$from_lon) + runif (50) * diff (range (graph$from_lon))
223to_y <- min (graph$from_lat) + runif (50) * diff (range (graph$from_lat))
224d <- dodgr_dists (graph = graph, from = cbind (from_x, from_y), to = cbind (to_x, to_y))
225```
226In this case, the random points will be mapped on to the nearest points on the
227street network. This may, of course, map some points onto minor, disconnected
228components of the graph. This can be controlled either by reducing the graph to
229it's largest connected component only:
230```{r large-comp, eval = FALSE}
231graph <- graph [graph$component == 1, ]
232nrow (graph)
233```
234or by explicitly using the `match_points_to_verts()` function with the option
235`connected = TRUE`:
236```{r}
237from <- match_points_to_verts (v, cbind (from_x, from_y), connected = TRUE)
238to <- match_points_to_verts (v, cbind (to_x, to_y), connected = TRUE)
239```
240This function returns an index into the result of `dodgr_vertices`, and so
241points to use for routing must then be extracted as follows:
242```{r}
243from <- v$id [from] # or from <- v [from, c ("x", "y")]
244to <- v$id [to]
245d <- dodgr_dists (graph = graph, from = from, to = to)
246```
247
248## Usage: Flow Aggregation
249
250Flow aggregation refers to the procedure of routing along multiple ways
251according to specified densities of flow between defined origin and destination
252points, and aggregating flows along each edge of the network. The procedure is
253functionally similar to the above procedure for distances, with the addition of
254a matrix specifying pairwise flow densities between the input set of origin
255(`from`) and destination (`to`) points. The following example illustrates use
256with a random "flow matrix":
257
258```{r flows}
259flows <- array (runif (length (from) * length (to)), dim = c (length (from), length (to)))
260length (from)
261length (to)
262dim (flows)
263f <- dodgr_flows_aggregate (graph = graph, from = from, to = to, flows = flows)
264```
265The result is simply the input `graph` with an additional column quantifying
266the aggregate flows along each edge:
267```{r flows-out-fakey, eval = FALSE}
268head (f)
269```
270```{r flows-out, echo = FALSE}
271knitr::kable (head (f))
272```
273
274An additional flow aggregation function can be applied in cases where only
275densities at origin points are known, and movement throughout a graph is
276dispersive:
277
278```{r, eval = FALSE}
279f <- dodgr_flows_disperse (graph = graph, from = from, dens = runif (length (from)))
280```
281
282## Further detail
283
284For more detail, see the [main package
285vignette](https://UrbanAnalyst.github.io/dodgr/articles/dodgr.html), and the second
286vignette on [street networks and time-based
287routing](https://UrbanAnalyst.github.io/dodgr/articles/times.html)
288
289
290## Contributors
291
292
293
294
295
296
297
298
299<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
300<!-- prettier-ignore-start -->
301<!-- markdownlint-disable -->
302
303All contributions to this project are gratefully acknowledged using the [`allcontributors` package](https://github.com/ropensci/allcontributors) following the [allcontributors](https://allcontributors.org) specification. Contributions of any kind are welcome!
304
305### Code
306
307<table>
308
309<tr>
310<td align="center">
311<a href="https://github.com/mpadge">
312<img src="https://avatars.githubusercontent.com/u/6697851?v=4" width="100px;" alt=""/>
313</a><br>
314<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=mpadge">mpadge</a>
315</td>
316<td align="center">
317<a href="https://github.com/karpfen">
318<img src="https://avatars.githubusercontent.com/u/11758039?v=4" width="100px;" alt=""/>
319</a><br>
320<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=karpfen">karpfen</a>
321</td>
322<td align="center">
323<a href="https://github.com/leoniedu">
324<img src="https://avatars.githubusercontent.com/u/54786?v=4" width="100px;" alt=""/>
325</a><br>
326<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=leoniedu">leoniedu</a>
327</td>
328<td align="center">
329<a href="https://github.com/Robinlovelace">
330<img src="https://avatars.githubusercontent.com/u/1825120?v=4" width="100px;" alt=""/>
331</a><br>
332<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=Robinlovelace">Robinlovelace</a>
333</td>
334<td align="center">
335<a href="https://github.com/agila5">
336<img src="https://avatars.githubusercontent.com/u/22221146?v=4" width="100px;" alt=""/>
337</a><br>
338<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=agila5">agila5</a>
339</td>
340<td align="center">
341<a href="https://github.com/JimShady">
342<img src="https://avatars.githubusercontent.com/u/2901470?v=4" width="100px;" alt=""/>
343</a><br>
344<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=JimShady">JimShady</a>
345</td>
346</tr>
347
348
349<tr>
350<td align="center">
351<a href="https://github.com/DavisVaughan">
352<img src="https://avatars.githubusercontent.com/u/19150088?v=4" width="100px;" alt=""/>
353</a><br>
354<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=DavisVaughan">DavisVaughan</a>
355</td>
356<td align="center">
357<a href="https://github.com/layik">
358<img src="https://avatars.githubusercontent.com/u/408568?v=4" width="100px;" alt=""/>
359</a><br>
360<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=layik">layik</a>
361</td>
362<td align="center">
363<a href="https://github.com/olivroy">
364<img src="https://avatars.githubusercontent.com/u/52606734?v=4" width="100px;" alt=""/>
365</a><br>
366<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=olivroy">olivroy</a>
367</td>
368<td align="center">
369<a href="https://github.com/virgesmith">
370<img src="https://avatars.githubusercontent.com/u/19323577?v=4" width="100px;" alt=""/>
371</a><br>
372<a href="https://github.com/UrbanAnalyst/dodgr/commits?author=virgesmith">virgesmith</a>
373</td>
374</tr>
375
376</table>
377
378
379### Issue Authors
380
381<table>
382
383<tr>
384<td align="center">
385<a href="https://github.com/chrjangit">
386<img src="https://avatars.githubusercontent.com/u/13800425?v=4" width="100px;" alt=""/>
387</a><br>
388<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Achrjangit">chrjangit</a>
389</td>
390<td align="center">
391<a href="https://github.com/rafapereirabr">
392<img src="https://avatars.githubusercontent.com/u/7448421?u=01aed495e612154e54be4c51221e706cdff7779d&v=4" width="100px;" alt=""/>
393</a><br>
394<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Arafapereirabr">rafapereirabr</a>
395</td>
396<td align="center">
397<a href="https://github.com/chrijo">
398<img src="https://avatars.githubusercontent.com/u/37801457?v=4" width="100px;" alt=""/>
399</a><br>
400<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Achrijo">chrijo</a>
401</td>
402<td align="center">
403<a href="https://github.com/dataandcrowd">
404<img src="https://avatars.githubusercontent.com/u/25252172?u=2c62dac1ac9bfef3f26ee56c3d63b18dccc553a3&v=4" width="100px;" alt=""/>
405</a><br>
406<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Adataandcrowd">dataandcrowd</a>
407</td>
408<td align="center">
409<a href="https://github.com/mem48">
410<img src="https://avatars.githubusercontent.com/u/15819577?u=0c128db4e7567656c23e83e4314111fcea424526&v=4" width="100px;" alt=""/>
411</a><br>
412<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Amem48">mem48</a>
413</td>
414<td align="center">
415<a href="https://github.com/fzenoni">
416<img src="https://avatars.githubusercontent.com/u/6040873?u=bf32b8c1bc7ffc30c34bb09a1b0ae0f851414a48&v=4" width="100px;" alt=""/>
417</a><br>
418<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Afzenoni">fzenoni</a>
419</td>
420</tr>
421
422
423<tr>
424<td align="center">
425<a href="https://github.com/mdsumner">
426<img src="https://avatars.githubusercontent.com/u/4107631?u=77e928f4bb904a5c2e8927a02194b86662408329&v=4" width="100px;" alt=""/>
427</a><br>
428<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Amdsumner">mdsumner</a>
429</td>
430<td align="center">
431<a href="https://github.com/nacnudus">
432<img src="https://avatars.githubusercontent.com/u/3522552?u=53524b68ca89335d9079b7272ee6c2b0afda340a&v=4" width="100px;" alt=""/>
433</a><br>
434<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Anacnudus">nacnudus</a>
435</td>
436<td align="center">
437<a href="https://github.com/mkvasnicka">
438<img src="https://avatars.githubusercontent.com/u/8019045?u=16ba8f6406bcb20ade64481fbc177998bd1549fb&v=4" width="100px;" alt=""/>
439</a><br>
440<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Amkvasnicka">mkvasnicka</a>
441</td>
442<td align="center">
443<a href="https://github.com/orlando-sabogal">
444<img src="https://avatars.githubusercontent.com/u/7365739?u=047a8fa924d2be94b99e88e83c2634668ae1f005&v=4" width="100px;" alt=""/>
445</a><br>
446<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Aorlando-sabogal">orlando-sabogal</a>
447</td>
448<td align="center">
449<a href="https://github.com/tbuckl">
450<img src="https://avatars.githubusercontent.com/u/98956?u=9580c2ee3c03cbbe44ac8180b0f6a6725b0415f0&v=4" width="100px;" alt=""/>
451</a><br>
452<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Atbuckl">tbuckl</a>
453</td>
454<td align="center">
455<a href="https://github.com/douglascm">
456<img src="https://avatars.githubusercontent.com/u/29764356?v=4" width="100px;" alt=""/>
457</a><br>
458<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Adouglascm">douglascm</a>
459</td>
460</tr>
461
462
463<tr>
464<td align="center">
465<a href="https://github.com/darinchristensen">
466<img src="https://avatars.githubusercontent.com/u/6937320?u=987f49819efb67eda19f14e59f9c37b122ebc289&v=4" width="100px;" alt=""/>
467</a><br>
468<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Adarinchristensen">darinchristensen</a>
469</td>
470<td align="center">
471<a href="https://github.com/romainFr">
472<img src="https://avatars.githubusercontent.com/u/1626262?v=4" width="100px;" alt=""/>
473</a><br>
474<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3AromainFr">romainFr</a>
475</td>
476<td align="center">
477<a href="https://github.com/dcooley">
478<img src="https://avatars.githubusercontent.com/u/8093396?u=2c8d9162f246d90d433034d212b29a19e0f245c1&v=4" width="100px;" alt=""/>
479</a><br>
480<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Adcooley">dcooley</a>
481</td>
482<td align="center">
483<a href="https://github.com/Hussein-Mahfouz">
484<img src="https://avatars.githubusercontent.com/u/45176416?u=ceef68f4fec4aed25b069522e8c90fde3629c7f0&v=4" width="100px;" alt=""/>
485</a><br>
486<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3AHussein-Mahfouz">Hussein-Mahfouz</a>
487</td>
488<td align="center">
489<a href="https://github.com/sigmafelix">
490<img src="https://avatars.githubusercontent.com/u/25448786?u=92f45291c06443ff01cba29555f309ff3ceccee7&v=4" width="100px;" alt=""/>
491</a><br>
492<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Asigmafelix">sigmafelix</a>
493</td>
494<td align="center">
495<a href="https://github.com/polettif">
496<img src="https://avatars.githubusercontent.com/u/17431069?u=757eac2821736acbb02e7c90b456411d256d5780&v=4" width="100px;" alt=""/>
497</a><br>
498<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Apolettif">polettif</a>
499</td>
500</tr>
501
502
503<tr>
504<td align="center">
505<a href="https://github.com/edzer">
506<img src="https://avatars.githubusercontent.com/u/520851?u=9bc892c3523be428dc211f2ccbcf04e8e0e564ff&v=4" width="100px;" alt=""/>
507</a><br>
508<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Aedzer">edzer</a>
509</td>
510<td align="center">
511<a href="https://github.com/FlxPo">
512<img src="https://avatars.githubusercontent.com/u/5145583?u=cbd02ee0a0fa0447429f38bd7e3a1da57c841239&v=4" width="100px;" alt=""/>
513</a><br>
514<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3AFlxPo">FlxPo</a>
515</td>
516<td align="center">
517<a href="https://github.com/LeshunXu">
518<img src="https://avatars.githubusercontent.com/u/48538622?v=4" width="100px;" alt=""/>
519</a><br>
520<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3ALeshunXu">LeshunXu</a>
521</td>
522<td align="center">
523<a href="https://github.com/deanmarchiori">
524<img src="https://avatars.githubusercontent.com/u/9559770?u=5abd6534fd7f1cf94a54f894cdb12e017db1a9af&v=4" width="100px;" alt=""/>
525</a><br>
526<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Adeanmarchiori">deanmarchiori</a>
527</td>
528<td align="center">
529<a href="https://github.com/demcortillas">
530<img src="https://avatars.githubusercontent.com/u/41303271?u=de6dad5177d4a0db395a751ba9a4f9acb32c9ef7&v=4" width="100px;" alt=""/>
531</a><br>
532<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Ademcortillas">demcortillas</a>
533</td>
534<td align="center">
535<a href="https://github.com/Urban-JonathanCohen">
536<img src="https://avatars.githubusercontent.com/u/51330244?u=b67ded6a42ccf69116ed9999ba183b8523e8fde9&v=4" width="100px;" alt=""/>
537</a><br>
538<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3AUrban-JonathanCohen">Urban-JonathanCohen</a>
539</td>
540</tr>
541
542
543<tr>
544<td align="center">
545<a href="https://github.com/sriramab">
546<img src="https://avatars.githubusercontent.com/u/12668606?u=353aaf316777539836fbd9b9f8e7ec5ae6527666&v=4" width="100px;" alt=""/>
547</a><br>
548<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Asriramab">sriramab</a>
549</td>
550<td align="center">
551<a href="https://github.com/xiaofanliang">
552<img src="https://avatars.githubusercontent.com/u/22874361?u=7d6ade584aeaf34e1fde47c400ffae1a82b79a25&v=4" width="100px;" alt=""/>
553</a><br>
554<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Axiaofanliang">xiaofanliang</a>
555</td>
556<td align="center">
557<a href="https://github.com/grobins">
558<img src="https://avatars.githubusercontent.com/u/4343493?u=48c1092702254899739e853db95cb1f704f99971&v=4" width="100px;" alt=""/>
559</a><br>
560<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Agrobins">grobins</a>
561</td>
562<td align="center">
563<a href="https://github.com/jucardwell">
564<img src="https://avatars.githubusercontent.com/u/91475282?v=4" width="100px;" alt=""/>
565</a><br>
566<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Ajucardwell">jucardwell</a>
567</td>
568<td align="center">
569<a href="https://github.com/diegoteca">
570<img src="https://avatars.githubusercontent.com/u/39192686?u=cca8991aa0bcabb4a3547aa81eacf99efcabcbfb&v=4" width="100px;" alt=""/>
571</a><br>
572<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Adiegoteca">diegoteca</a>
573</td>
574<td align="center">
575<a href="https://github.com/xtimbeau">
576<img src="https://avatars.githubusercontent.com/u/54633745?u=578caa070217a333e22be67990e42e8bdf434512&v=4" width="100px;" alt=""/>
577</a><br>
578<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Axtimbeau">xtimbeau</a>
579</td>
580</tr>
581
582
583<tr>
584<td align="center">
585<a href="https://github.com/pasipasi123">
586<img src="https://avatars.githubusercontent.com/u/34722481?v=4" width="100px;" alt=""/>
587</a><br>
588<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Apasipasi123">pasipasi123</a>
589</td>
590<td align="center">
591<a href="https://github.com/jamiedtor">
592<img src="https://avatars.githubusercontent.com/u/90428083?v=4" width="100px;" alt=""/>
593</a><br>
594<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Ajamiedtor">jamiedtor</a>
595</td>
596<td align="center">
597<a href="https://github.com/chinhqho">
598<img src="https://avatars.githubusercontent.com/u/47441312?u=577d1dca03b4bb904bb45f1e6205b11144c900cd&v=4" width="100px;" alt=""/>
599</a><br>
600<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Achinhqho">chinhqho</a>
601</td>
602<td align="center">
603<a href="https://github.com/szhorvat">
604<img src="https://avatars.githubusercontent.com/u/1212871?v=4" width="100px;" alt=""/>
605</a><br>
606<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Aszhorvat">szhorvat</a>
607</td>
608<td align="center">
609<a href="https://github.com/nataliamush">
610<img src="https://avatars.githubusercontent.com/u/21228099?v=4" width="100px;" alt=""/>
611</a><br>
612<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Anataliamush">nataliamush</a>
613</td>
614<td align="center">
615<a href="https://github.com/juanfonsecaLS1">
616<img src="https://avatars.githubusercontent.com/u/69847296?u=c6451574213e6cef9ce77d937970355d244240d5&v=4" width="100px;" alt=""/>
617</a><br>
618<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3AjuanfonsecaLS1">juanfonsecaLS1</a>
619</td>
620</tr>
621
622
623<tr>
624<td align="center">
625<a href="https://github.com/luukvdmeer">
626<img src="https://avatars.githubusercontent.com/u/26540305?u=c576e87314499815cbf698b7781ee58fd1d773e2&v=4" width="100px;" alt=""/>
627</a><br>
628<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Aluukvdmeer">luukvdmeer</a>
629</td>
630<td align="center">
631<a href="https://github.com/jonas260492">
632<img src="https://avatars.githubusercontent.com/u/59968564?v=4" width="100px;" alt=""/>
633</a><br>
634<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Ajonas260492">jonas260492</a>
635</td>
636<td align="center">
637<a href="https://github.com/meptrsn">
638<img src="https://avatars.githubusercontent.com/u/22846094?v=4" width="100px;" alt=""/>
639</a><br>
640<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3Ameptrsn">meptrsn</a>
641</td>
642<td align="center">
643<a href="https://github.com/RegularnaMatrica">
644<img src="https://avatars.githubusercontent.com/u/65914613?v=4" width="100px;" alt=""/>
645</a><br>
646<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+author%3ARegularnaMatrica">RegularnaMatrica</a>
647</td>
648</tr>
649
650</table>
651
652
653### Issue Contributors
654
655<table>
656
657<tr>
658<td align="center">
659<a href="https://github.com/richardellison">
660<img src="https://avatars.githubusercontent.com/u/10625733?u=8d7cd55a61f1a1b3f9973ddff5adbb45e0b193c6&v=4" width="100px;" alt=""/>
661</a><br>
662<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+commenter%3Arichardellison">richardellison</a>
663</td>
664<td align="center">
665<a href="https://github.com/coatless">
666<img src="https://avatars.githubusercontent.com/u/833642?u=d7a2ccb381bd1517d2d51778670ef227cbd8d3aa&v=4" width="100px;" alt=""/>
667</a><br>
668<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+commenter%3Acoatless">coatless</a>
669</td>
670<td align="center">
671<a href="https://github.com/znmeb">
672<img src="https://avatars.githubusercontent.com/u/4938?u=e9e8d4bececded56a36606575ae85ab55ab7633c&v=4" width="100px;" alt=""/>
673</a><br>
674<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+commenter%3Aznmeb">znmeb</a>
675</td>
676<td align="center">
677<a href="https://github.com/yihui">
678<img src="https://avatars.githubusercontent.com/u/163582?v=4" width="100px;" alt=""/>
679</a><br>
680<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+commenter%3Ayihui">yihui</a>
681</td>
682<td align="center">
683<a href="https://github.com/MartinLHazelton">
684<img src="https://avatars.githubusercontent.com/u/36397695?u=bc2261049e9b33f2c5d8e25f0bd56d4b1d6275df&v=4" width="100px;" alt=""/>
685</a><br>
686<a href="https://github.com/UrbanAnalyst/dodgr/issues?q=is%3Aissue+commenter%3AMartinLHazelton">MartinLHazelton</a>
687</td>
688</tr>
689
690</table>
691
692<!-- markdownlint-enable -->
693<!-- prettier-ignore-end -->
694<!-- ALL-CONTRIBUTORS-LIST:END -->