-
Notifications
You must be signed in to change notification settings - Fork 0
/
Andrew_Collier_(Datawookie)_2019-07-28_Graphic-all-roads-lead-to-rome.R
105 lines (87 loc) · 3.19 KB
/
Andrew_Collier_(Datawookie)_2019-07-28_Graphic-all-roads-lead-to-rome.R
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
library(readr)
library(dplyr)
library(stringr)
library(purrr)
library(memoise)
library(osrm)
library(geosphere)
library(ggplot2)
library(gganimate)
# Inpsired by https://www.reddit.com/r/dataisbeautiful/comments/7pwnub/optimal_routes_from_the_geographic_center_of_the/.
city <- read_csv("https://github.com/datawookie/data-diaspora/blob/master/spatial/city-country.csv?raw=true", comment = "#", na = "") %>%
select(-iso2, -country) %>%
mutate(id = as.character(id))
country <- read_csv("https://github.com/datawookie/data-diaspora/raw/master/spatial/country-continent.csv", comment = "#", na = "") %>%
select(-iso2)
city <- city %>%
inner_join(country, by = "iso3") %>%
filter(
continent == "Europe",
!iso3 %in% c("GBR", "IRL", "MLT", "FRO", "IMN", "CYP"),
!str_detect(country, "^Iceland"),
!admin_name %in% c("Canary Islands", "Madeira", "Azores", "Kamchatskiy Kray", "Sakhalinskaya Oblast’",
"Chukotskiy Avtonomnyy Okrug", "Sardegna", "Corsica", "Balearic Islands", "Kríti",
"Sicilia"),
!(city %in% c("Oktyabrskiy", "Noginsk", "Melilla"))
)
rome <- city %>% filter(city == "Rome") %>% select(id, lng, lat)
rest <- city %>% filter(city != "Rome") %>% select(id, lng, lat)
SINK = tempfile()
find_route = memoise(function(id, lng, lat) {
message(id)
while (TRUE) {
# Capture output so that can identify "no route" error.
#
sinkfile <- file(SINK, open = "wt")
#
sink(sinkfile, type = "message")
route = possibly(osrmRoute, otherwise = NULL)(src = c(id, lng, lat), dst = rome)
sink(type = "message")
#
close(sinkfile)
cat(" Pausing... ")
Sys.sleep(rpois(1, 15))
cat("done!\n")
# Check for "no route".
#
if (readLines(SINK) %>% str_detect("NoRoute") %>% any()) {
return(NULL)
}
# Check for distance >= 10000 km.
#
if (readLines(SINK) %>% str_detect("Total distance between all coordinates cannot exceed 10000 km") %>% any()) {
return(NULL)
}
if (is.null(route)) {
cat(" Waiting to retry... ")
Sys.sleep(600)
cat("done!\n")
} else {
return(route %>% mutate(id = id))
}
}
})
routes <- pmap(rest, find_route) %>% bind_rows()
# That took a while, so let's store the results just in case.
#
saveRDS(routes, "rome-routes.rds")
# DISTANCES -----------------------------------------------------------------------------------------------------------
routes <- routes %>%
group_by(id) %>%
mutate(
frac = row_number() / n(),
step = row_number()
)
# MAP -----------------------------------------------------------------------------------------------------------------
p <- ggplot(routes) +
geom_polygon(data = map_data('world'), aes(x=long, y=lat, group=group), fill = "grey90") +
geom_path(aes(x = lon, y = lat, group = id), lwd = 1, alpha = 0.125, colour = "#3498db") +
geom_point(data = rome, aes(x = lng, y = lat), pch = 21, size = 5, fill = "black", alpha = 0.3) +
# geom_point(data = rest, aes(x = lng, y = lat), alpha = 0.3) +
coord_cartesian(xlim = c(-10, 165), ylim = c(35, 75)) +
theme_void() +
NULL
p
ggsave("all-roads-lead-to-rome.png", width = 16, height = 9)
p +
transition_reveal(step)