#' Author: Julio Trecenti | |
#' Subject: Distâncias das capitais | |
library(tidyverse) | |
library(leaflet) | |
library(plotly) | |
# Import ----------------------------------------------------------------------- | |
## Download a partir do site | |
r_capitals <- httr::GET( | |
"https://lab.lmnixon.org/4th/worldcapitals.html", | |
httr::user_agent("Mozilla/5.0 (X11; Linux x86_64)") | |
) | |
## Parse do resultado do site | |
da_countries_raw <- r_capitals %>% | |
xml2::read_html() %>% | |
xml2::xml_find_first("//table") %>% | |
rvest::html_table(header = TRUE) %>% | |
tibble::as_tibble() %>% | |
janitor::clean_names() | |
# Tidy ------------------------------------------------------------------------- | |
da_countries_tidy <- da_countries_raw %>% | |
filter(country != "") %>% | |
# transforma (N,S) (E,W) em (1,-1), (1,-1) | |
mutate( | |
lat_num = str_detect(latitude, "N") * 2 - 1, | |
lng_num = str_detect(longitude, "E") * 2 - 1 | |
) %>% | |
# transforma em numérico | |
mutate( | |
across(c(latitude, longitude), parse_number), | |
lat = latitude * lat_num, | |
lng = longitude * lng_num | |
) %>% | |
# arruma Israel | |
mutate( | |
lat = if_else(country == "Israel", 31.7683, lat), | |
lng = if_else(country == "Israel", 35.2137, lng) | |
) %>% | |
select(country, capital, lat, lng) | |
# Transform -------------------------------------------------------------------- | |
da_countries <- da_countries_tidy %>% | |
# cria pontos com base em lat lng e sf::st_point() | |
# sf::st_sfc() serve para transformar a lista num objeto POINT do {sf} | |
# crs = 4326 serve para o {sf} saber que são coordenadas no planeta Terra. | |
mutate(pt = sf::st_sfc( | |
map2(lng, lat, ~sf::st_point(c(.x, .y, 1))), | |
crs = 4326 | |
)) %>% | |
mutate( | |
across(c(lat, lng), list(br = ~.x[country == "Brazil"])), | |
pt_br = sf::st_sfc( | |
list(sf::st_point(c(lng_br[1], lat_br[1], 1))), | |
crs = 4326 | |
) | |
) %>% | |
mutate( | |
dist_br = sf::st_distance(pt, pt_br, by_element = TRUE), | |
dist_br = as.numeric(dist_br / 1000) | |
) %>% | |
# ordena a base pelas distâncias | |
arrange(dist_br) | |
da_lines_sf <- da_countries %>% | |
mutate(geometry = sf::st_sfc( | |
purrr::map2(pt, pt_br, ~sf::st_linestring(c(.x, .y), dim = "XYZ")) | |
)) %>% | |
mutate( | |
geometry = sf::st_line_sample(geometry, n = 30), | |
geometry = sf::st_cast(geometry, "LINESTRING") | |
) %>% | |
select(-pt, -pt_br) %>% | |
arrange(desc(dist_br)) %>% | |
head(10) %>% | |
sf::st_as_sf() | |
# Visualize -------------------------------------------------------------------- | |
## Tabelas | |
tab_perto <- da_countries %>% | |
arrange(dist_br) %>% | |
filter(country != "Brazil") %>% | |
select(country, capital, dist_br) %>% | |
head(10) | |
tab_longe <- da_countries %>% | |
arrange(-dist_br) %>% | |
filter(country != "Brazil") %>% | |
select(country, capital, dist_br) %>% | |
head(10) | |
## Grafico com {leaflet} | |
make_label <- function(pais, capital) { | |
txt <- stringr::str_glue("<b>País</b>: {pais}<br/><b>Capital</b>: {capital}") | |
htmltools::HTML(txt) | |
} | |
p_leaflet <- da_countries %>% | |
mutate(lab = map2(country, capital, make_label)) %>% | |
leaflet() %>% | |
addTiles() %>% | |
addMarkers( | |
clusterOptions = markerClusterOptions(), | |
lat = ~lat, lng = ~lng, popup = ~lab | |
) | |
library(plotly) | |
# mapa mundi | |
world <- sf::st_as_sf(maps::map("world", plot = FALSE, fill = TRUE)) %>% | |
sf::st_simplify(dTolerance = 0.1) %>% | |
filter(!sf::st_is_empty(geom)) %>% | |
mutate(geom = sf::st_cast(geom, "MULTIPOLYGON")) | |
# funções de transformação de coordenadas | |
deg2rad <- function(degree) degree * pi / 180 | |
coord_x <- function(x, y) 1.001 * cos(deg2rad(x)) * cos(deg2rad(y)) | |
coord_y <- function(x, y) 1.001 * sin(deg2rad(x)) * cos(deg2rad(y)) | |
coord_z <- function(y) 1.001 * sin(deg2rad(y)) | |
label_plotly <- function(pais, capital, dist) { | |
stringr::str_glue( | |
"<b>País</b>: {pais}<br>", | |
"<b>Capital</b>: {capital}<br>", | |
"<b>Distância</b>: {round(dist, 1)}km" | |
) | |
} | |
p_plotly <- plot_ly(height = 1000) %>% | |
# adiciona o mapa mundi | |
add_sf( | |
data = world, | |
x = ~coord_x(x, y), | |
y = ~coord_y(x, y), | |
z = ~coord_z(y), | |
color = I("gray80"), | |
size = I(2), | |
hoverinfo = "none" | |
) %>% | |
# adiciona as linhas | |
add_sf( | |
data = da_lines_sf, | |
name = "linhas", | |
x = ~coord_x(x, y), | |
y = ~coord_y(x, y), | |
z = ~coord_z(y), | |
color = ~dist_br, | |
size = I(3), | |
text = ~label_plotly(country, capital, dist_br), | |
hoverinfo = "text" | |
) %>% | |
layout(showlegend = FALSE) | |
# Model ------------------------------------------------------------------------ | |
## Não tem modelagem :) | |
# Export ----------------------------------------------------------------------- | |
htmlwidgets::saveWidget(p_leaflet, "~/Documents/drafts/data/p_leaflet_world.html") | |
htmlwidgets::saveWidget(p_plotly, "~/Documents/drafts/data/p_plotly_world.html") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment