# SPDS
library(tidyverse)
library(sf)
library(units)

# Data
library(USAboundaries)
library(rnaturalearth)

# Visualization
library(gghighlight)
library(ggrepel)
library(knitr)

#Question1

#1.1
eqdc = '+proj=eqdc +lat_0=40 +lon_0=-96 +lat_1=20 +lat_2=60 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs'

#1.2
conus = USAboundaries::us_states(resolution = "low") %>%
  filter(!stusps %in% c("PR","AK","HI"))%>%
  st_transform(eqdc)

#1.3
library(rnaturalearth)
northamerica = rnaturalearth::countries110%>%
  st_as_sf()%>%
  filter(admin %in% c("Mexico","Canada","United States of America"))%>%
  st_transform(eqdc)

#1.4
library(readr)
cities = readr::read_csv("../data/uscities.csv")%>%
  st_as_sf(coords = c("lng","lat"), crs = 4326)%>%
  filter(!state_name%in% c("Puerto Rico","Alaska","Hawaii"))%>%
  st_transform(eqdc)

#Question2

#2.1
border_conus = st_union(conus)%>%
  st_cast("MULTILINESTRING")

cities = cities%>%
  mutate(dist_border = st_distance(cities, border_conus),
         dist_border = set_units(dist_border, "km"),
         dist_border = drop_units(dist_border))

select(cities, city, state_name, dist_border)%>%
  slice_max(dist_border, n = 5)%>%
  st_drop_geometry()%>%
  kable(caption = "5 cities farthest to the US border",
        col.name = c("City","State","Distance to US Border"))
5 cities farthest to the US border
City State Distance to US Border
Dresden Kansas 1012.317
Herndon Kansas 1007.750
Hill City Kansas 1005.147
Atwood Kansas 1004.734
Jennings Kansas 1003.646
#2.2
state_conus = st_combine(conus)%>%
  st_cast("MULTILINESTRING")

cities = cities%>%
  mutate(dist_state = st_distance(cities, state_conus),
         dist_state = set_units(dist_state, "km"),
         dist_state = drop_units(dist_state))

select(cities, city, state_name, dist_state)%>%
  slice_max(dist_state, n = 5)%>%
  st_drop_geometry()%>%
  kable(caption = "5 cities farthest to the state border",
        col.name = c("City","State","Distance to State border"))
5 cities farthest to the state border
City State Distance to State border
Lampasas Texas 308.9216
Bertram Texas 302.8190
Kempner Texas 302.5912
Harker Heights Texas 298.8125
Florence Texas 298.6804
#2.3
mexico = filter(northamerica, admin == "Mexico")

cities = cities%>%
  mutate(dist_mexico = st_distance(cities, mexico),
         dist_mexico = set_units(dist_mexico, "km"),
         dist_mexico = drop_units(dist_mexico))

select(cities, city, state_name, dist_mexico)%>%
  slice_max(dist_mexico, n = 5)%>%
  st_drop_geometry()%>%
  kable(caption = "5 cities farthest to the Mexico border",
        col.name = c("City","State","Distance to Mexico border"))
5 cities farthest to the Mexico border
City State Distance to Mexico border
Caribou Maine 3250.334
Presque Isle Maine 3234.570
Calais Maine 3134.348
Eastport Maine 3125.624
Old Town Maine 3048.366
#2.4
canada = filter(northamerica, admin == "Canada")

cities = cities%>%
  mutate(dist_canada = st_distance(cities, canada),
         dist_canada = set_units(dist_canada, "km"),
         dist_canada = drop_units(dist_canada))

select(cities, city, state_name, dist_canada)%>%
  slice_max(dist_canada, n = 5)%>%
  st_drop_geometry()%>%
  kable(caption = "5 cities farthest to the Mexico border",
        col.name = c("City","State","Distance to Canada border"))
5 cities farthest to the Mexico border
City State Distance to Canada border
Guadalupe Guerra Texas 2206.455
Sandoval Texas 2205.641
Fronton Texas 2204.784
Fronton Ranchettes Texas 2202.118
Evergreen Texas 2202.020

#Question 3

#3.1
ggplot()+
  geom_sf(data=northamerica)+
  geom_sf(data=border_conus)+
  geom_sf(data=state_conus, lty=2)+
  geom_sf(data=slice_max(cities, population, n=10),color="blue")+
  ggrepel::geom_label_repel(
    data=slice_max(cities, population, n=10),
    stat="sf_coordinates",
    aes(label=city,geometry=geometry))

#3.2

ggplot()+
  geom_sf(data=cities, aes(color=dist_border))+
  geom_sf(data=border_conus)+
  geom_sf(data=slice_max(cities, dist_border, n=5),color="red")+
  ggrepel::geom_label_repel(
    data=slice_max(cities, dist_border, n=5),
    stat="sf_coordinates",
    aes(label=city,geometry=geometry))

#3.3
ggplot()+
  geom_sf(data=cities, aes(color=dist_state))+
  geom_sf(data=border_conus)+
  geom_sf(data=slice_max(cities, dist_state, n=5),color="red")+
  ggrepel::geom_label_repel(
    data=slice_max(cities, dist_state, n=5),
    stat="sf_coordinates",
    aes(label=city,geometry=geometry))

#3.4

cities = cities%>%
  mutate(cities, difference = abs(dist_canada-dist_mexico))

e_dist = cities%>%
  filter(difference<100)%>%
  slice_max(population, n=5)

ggplot()+
  geom_sf(data=cities, aes(color=difference),size=0.5)+
  geom_sf(data=border_conus)+
  gghighlight(difference<100)+
  geom_sf(data=e_dist)+
  ggrepel::geom_label_repel(
    data=e_dist,
    stat="sf_coordinates",
    aes(label=city,geometry=geometry))

#Question4

#4.1

border_cities = cities%>%
  mutate(uspopulation=sum(population))%>%
  filter(dist_border<160)%>%
  st_drop_geometry()%>%
  summarise(city=n(),
            border_po=sum(population),
            ratio=100*(border_po/uspopulation[1]))
print(border_cities)
## # A tibble: 1 x 3
##    city border_po ratio
##   <int>     <dbl> <dbl>
## 1 12283 259935815  65.4
#Matching the ACLU estimation.

#4.2
b_label = cities%>%
  filter(dist_border<160)%>%
  group_by(state_name)%>%
  slice_max(population, n=1)

ggplot(cities)+
  geom_sf(aes(col=dist_border))+
  gghighlight(dist_border<160)+
  geom_sf(data=state_conus)+
  scale_color_gradient(low="orange",high="black")+
  ggrepel::geom_label_repel(
    data=b_label,
    aes(label = city, geometry=geometry),
    stat="sf_coordinates")