#' ---
#' title: "GIS and mapping in R"
#' subtitle: "Introduction to the sf package"
#' author: "Olivier Gimenez"
#' date: "2022-05-13"
#' output:
#'   xaringan::moon_reader:
#'     css: ["css/rutgers-tidyverse.css","css/rutgers-fonts_og.css"]
#'     lib_dir: libs
#'     nature:
#'       highlightStyle: github
#'       highlightLines: true
#'       countIncrementalSlides: false
#' ---
#' 
## ----setup, include=FALSE-------------------------------------------------------------------------------------------
options(htmltools.dir.version = FALSE)
knitr::opts_chunk$set(fig.align = "center", 
                      message = FALSE, 
                      warning = FALSE, 
                      paged.print = FALSE)

#' 
#' 
#' # Simple Features for R: the sf package
#' 
## ----echo = FALSE, out.width = "700px"------------------------------------------------------------------------------
knitr::include_graphics("img/sfcartoon.jpg")

#' 
#' ---
#' class: inverse, middle, center
#' # Introduction
#' ---
#' 
#' 
#' # What's so nice about `sf`?
#' 
#' * Easy to work with spatial data because the distinction between spatial data and other forms of data is minimized
#' 
#' * Spatial objects are stored as **dataframes**, with the feature geometries stored in list-columns
#' 
#' * This is similar to the way that **spatial databases** are structured
#' 
#' * All functions begin with `st_` for easy autofill with RStudio tab 
#' 
#' * Functions are **pipe-friendly**
#' 
#' * `dplyr` and `tidyr` verbs have been defined for the `sf` objects
#' 
#' * `ggplot2` is able to plot `sf` objects directly
#' 
## ----echo=FALSE, out.width = "100px"--------------------------------------------------------------------------------
knitr::include_graphics("img/animatedsf.gif")

#' 
#' 
#' ---
#' 
#' # Load packages
#' 
## ----message = TRUE, warning = FALSE, paged.print = FALSE-----------------------------------------------------------
library(sf) # GIS package
library(tidyverse) # tidyverse packages, dplyr and ggplot2 among others
theme_set(theme_minimal(base_size = 14)) # set ggplot theme 

#' 
#' 
#' ---
#' 
#' ## Vector layers in `sf`
#' 
#' * The `sf` class is a hierarchical structure composed of 3 classes 
#'     * In green, **sf** - Vector layer object, `data.frame` with $\geq 1$ attribute columns and 1 geometry column
#'     * In red, **sfc** - Geometric part of vector layer - geometry column
#'     * In blue, **sfg** - Geometry of individual [simple feature](https://en.wikipedia.org/wiki/Simple_Features)
#' 
## ---- echo=FALSE----------------------------------------------------------------------------------------------------
knitr::include_graphics("img/sf_xfig.png")

#' 
#' 
#' ---
#' 
#' ## Simple feature geometry **`sfg`**
#' 
## ----echo=FALSE, dpi = 300, out.width = "550px", fig.align='center',warning=FALSE-----------------------------------
# knitr::include_graphics("images/simple_feature_types.png")
point <- st_as_sfc("POINT (30 10)")[[1]]
linestring <- st_as_sfc("LINESTRING (30 10, 10 30, 40 40)")[[1]]
polygon <- st_as_sfc("POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10),(20 30, 35 35, 30 20, 20 30))")[[1]]
multipoint <- st_as_sfc("MULTIPOINT ((10 40), (40 30), (20 20), (30 10))")[[1]]
multilinestring <- st_as_sfc("MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))")[[1]]
multipolygon <- st_as_sfc("MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20)))")[[1]]
geometrycollection <- st_as_sfc("GEOMETRYCOLLECTION (POLYGON((30 20, 45 40, 10 40, 30 20)),LINESTRING (10 10, 20 20, 10 30),POINT (40 20))")[[1]]
pol <- st_as_sfc("POLYGON((30 20, 45 40, 10 40, 30 20))")[[1]]
l <- st_as_sfc("LINESTRING (10 10, 20 20, 10 30)")[[1]]
p <- st_as_sfc("POINT (40 20)")[[1]]
opar <- par()
par(mfrow = c(2, 4), mar = c(1,1,1,1))
plot(point, main = "POINT", col = "blue", cex = 1.8, lwd = 2)
plot(linestring, main = "LINESTRING", col = "blue", lwd = 2)
plot(polygon, main = "POLYGON", border = "blue", col = "#0000FF33", lwd = 2)
plot(1, type="n", axes=F, xlab="", ylab="")
plot(multipoint, main = "MULTIPOINT", col = "blue", cex = 1.8, lwd = 2)
plot(multilinestring, main = "MULTILINESTRING", col = "blue", lwd = 2)
plot(multipolygon, main = "MULTIPOLYGON", border = "blue", col = "#0000FF33", lwd = 2)
plot(geometrycollection, main = "GEOMETRYCOLLECTION", col = NA, border = NA, lwd = 2)
plot(pol, border = "blue", col = "#0000FF33", add = TRUE, lwd = 2)
plot(l, col = "blue", add = TRUE, lwd = 2)
plot(p, col = "blue", add = TRUE, cex = 1.8, lwd = 2)
par(opar)

#' 
#' 
#' ---
#' class: inverse, middle, center
#' # First steps
#' ---
#' 
#' 
#' # Case study
#' 
## ----echo=FALSE, message=FALSE, warning=FALSE, paged.print=FALSE, out.width = "600px", fig.align = "center"---------
knitr::include_graphics("img/oryxpaper.png")

#' 
#' ---
#' 
#' # Read in spatial data
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
studysites_raw <- st_read("shp/bearpyrenees.shp")

#' 
#' ---
#' 
#' # Examine structure
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
glimpse(studysites_raw)

#' 
#' ---
#' 
#' # Examine structure
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
studysites_raw

#' 
#' 
#' ---
#' 
#' # Select relevant columns
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
studysites <- studysites_raw %>%
  select('bearpresence' = pres_08_12, #<<
         'idsite' = Numero) #<<
studysites

#' 
#' ---
#' 
#' # Our first map
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300------
studysites %>%
  ggplot() + #<<
  geom_sf() + #<<
  labs(title = 'Brown bear monitoring sites in the French Pyrenees mountains',
       subtitle = 'Source: French Biodiversity Agency')

#' 
#' ---
#' 
#' # Where did the species occur?
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300------
studysites %>%
  ggplot() +
  geom_sf(aes(fill = bearpresence)) + #<<
  labs(title = 'Brown bear presence in the French Pyrenees mountains',
       subtitle = 'Source: French Biodiversity Agency')

#' 
#' ---
#' 
#' # Where did the species occur?
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300------
studysites %>%
  ggplot() +
  geom_sf(aes(fill = bearpresence)) + 
  labs(title = 'Brown bear presence in the French Pyrenees mountains',
       subtitle = 'Source: French Biodiversity Agency',
       fill = "Presence") #<<

#' 
#' 
#' 
#' ---
#' 
#' # Take control of your legends
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300------
studysites %>%
  ggplot() +
  geom_sf(aes(fill = bearpresence)) +
  labs(title = 'Brown bear presence in the French Pyrenees mountains',
       subtitle = 'Source: French Biodiversity Agency') +
  scale_fill_manual(values = c('gray90','steelblue1','steelblue4'), #<<
                    name = "Bear presence", #<<
                    labels = c("Absent", "Occasional", "Regular")) #<<

#' 
#' ---
#' class: inverse, middle, center
#' # Spatial operations: transform, crop, intersect, join
#' ---
#' 
#' # Forest cover
#' 
#' * Forest cover might be a driver of brown bear distribution
#' 
#' * We use corine land cover (CLC) data (2012 version) to get forest cover
#' 
#' * Data can be downloaded [from the official website](http://www.donnees.statistiques.developpement-durable.gouv.fr/donneesCLC/CLC/millesime/CLC12_FR_RGF_SHP.zip)
#' 
#' * An explanation of what's in the data is available [here](https://www.statistiques.developpement-durable.gouv.fr/sites/default/files/2019-07/Nomenclature_CLC.pdf).  
#' 
#' ---
#' 
#' # Read in data
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
clc2012 <- st_read("shp/CLC12_FR_RGF.shp")

#' 
#' ---
#' 
#' # Read in data
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
clc2012

#' 
#' ---
#' 
#' # Extract forest codes
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
forest <- clc2012 %>%
  filter(CODE_12 == '311' | CODE_12 == '312' | CODE_12 == '313') #<<
forest

#' 
#' ---
#' 
#' # Use same coordinates system for map of the Pyrénées and forest layer
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
studysites <- studysites %>% 
  st_transform(crs = st_crs(forest))  #<<
studysites

#' 
#' ---
#' 
#' # Calculate area of each site
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
studysites %>% 
  mutate(area = st_area(.), #<<
         .before = 1)

#' 
#' ---
#' 
#' # Convert area in km<sup>2</sup>
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
studysites %>% 
  mutate(.before = 1,
         area = st_area(.),
         areakm2 = units::set_units(area, km^2)) #<<

#' 
#' ---
#' 
#' # Define big sites (area > 300 km<sup>2</sup>)
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
studysites <- studysites %>% 
  mutate(.before = 1,
         area = st_area(.),
         areakm2 = units::set_units(area, km^2),
         bigsites = ifelse(as.numeric(areakm2) > 300, areakm2, NA)) #<<
studysites

#' 
## ----include=FALSE--------------------------------------------------------------------------------------------------
# st_is_valid(studysites)
studysites <- st_make_valid(studysites) %>% st_cast()

#' 
#' 
#' 
#' ---
#' # Map again, with area on top of big sites
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300------
studysites %>%
  ggplot() + 
  geom_sf() +
  geom_sf_label(aes(label = round(bigsites))) + #<<
  labs(title = 'Brown bear big monitoring sites in the French Pyrenees mountains',
       subtitle = 'Big sites have area > 300km2',
       caption = 'Data from: French Biodiversity Agency',
       x = "", y = "")

#' 
#' ---
#' 
#' # Crop forest to match study area boundaries
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
forest %>% 
  st_crop(st_bbox(studysites)) %>% #<<
  as_tibble()

#' 
#' ---
#' 
#' # Then intersect the two layers
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
forest %>% 
  st_crop(st_bbox(studysites)) %>%
  st_intersection(studysites) %>% #<<
  as_tibble()

#' 
#' ---
#' 
#' # Get forest area for each intersected `sfg`
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
forest %>% 
  st_crop(st_bbox(studysites)) %>%
  st_intersection(studysites) %>%
  mutate(area = st_area(.)) %>% #<<
  as_tibble()

#' 
#' ---
#' 
#' # Sum forest over all study sites
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
forestpyrenees <- forest %>% 
  st_crop(st_bbox(studysites)) %>%
  st_intersection(studysites) %>%
  mutate(area = st_area(.)) %>%
  group_by(idsite) %>% # groups a data frame by variables #<< 
  summarise(areaforest = sum(area)) %>% # perform group-wise summaries #<<
  as_tibble() %>%
  select(-geometry)
forestpyrenees

#' 
#' ---
#' 
#' # Join `sf` and `tibble` objects 
#' ## More info [here](https://r-spatial.github.io/sf/reference/tidyverse.html)
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
studysites %>% 
  inner_join(forestpyrenees, by = 'idsite') #<<

#' 
#' ---
#' 
#' # Calculate forest cover
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
covariates <- studysites %>% 
  inner_join(forestpyrenees, by = 'idsite') %>% 
  mutate(.before = 1,
         forestcover = areaforest / area) #<<

#' 
#' 
#' ---
#' 
#' # Map forest cover
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300, eval = FALSE----
## covariates %>%
##   ggplot() +
##   aes(fill = as.numeric(forestcover)) +
##   geom_sf(lwd = 0.1) +
##   scale_fill_viridis_c(
##     labels = scales::percent_format(), #<< format percentage
##     name = 'Cover',
##     alpha = 0.7) +  #<< control transparency
##   labs(title = 'Map of forest cover in the Pyrenees mountains',
##        subtitle = 'Source: Corine Land Cover 2012')

#' 
#' ---
#' 
#' # Map forest cover
## ----echo = FALSE, message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300----
covariates %>%
  ggplot() +
  aes(fill = as.numeric(forestcover)) +
  geom_sf(lwd = 0.1) +
  scale_fill_viridis_c(
    labels = scales::percent_format(), #<< format percentage
    name = 'Cover',
    alpha = 0.7) +  #<< control transparency
  labs(title = 'Map of forest cover in the Pyrenees mountains',
       subtitle = 'Source: Corine Land Cover 2012')

#' 
#' ---
#' 
#' # Interactive map with `mapview`
#' ## More info [here](https://r-spatial.github.io/mapview/)
#' 
## ---- fig.align="center", fig.width=5, fig.height=5, out.width="100%", warning=FALSE--------------------------------
library(mapview)
mapview(covariates, zcol = "bearpresence") #<<

#' 
#' ---
#' 
#' # Interactive map with `mapview`
## ---- fig.align="center", fig.width=4, fig.height=4, out.width="100%", warning=FALSE--------------------------------
covariates <- covariates %>% mutate(forestcover = as.numeric(forestcover))
mapview(covariates, zcol = "forestcover", map.types = "OpenTopoMap") #<<
# map.types = "CartoDB.Positron", "CartoDB.DarkMatter", "OpenStreetMap", 
# "Esri.WorldImagery"

#' 
#' 
#' ---
#' 
#' # Human density
#' 
#' * Human density might be a driver of brown bear distribution
#' 
#' * We use data on population size of cities in France
#' 
#' * Population data is available from **IGN Admin-Express** database   [here](https://geoservices.ign.fr/documentation/diffusion/telechargement-donnees-libres.html#admin-express)  
#' 
#' ---
#' 
#' # Human density
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
load("shp/france_population_data_2016.RData")
glimpse(df.france)

#' 
#' ---
#' 
#' # Transform into lower case
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
colnames(df.france) <- colnames(df.france) %>% 
  str_to_lower() #<<
colnames(df.france)

#' 
#' ---
#' 
#' # Have a look to the distribution
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
df.france$population %>% 
  summary() #<<

#' 
#' ---
#' 
#' # Calculate density
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
df.france <- df.france %>% 
  mutate(density = population/superficie*100) #<<
as_tibble(df.france)

#' 
#' ---
#' 
#' # Show density
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
df.france %>%
  pull(density) %>%
  head()

#' 
#' ---
#' 
#' # Sum population size over sites
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
df.pyrenees <- df.france %>% 
  st_transform(crs = st_crs(forest)) %>%
  st_crop(st_bbox(covariates)) %>%
  st_intersection(covariates) %>%
  st_set_geometry(NULL) %>%
  group_by(idsite) %>% #<<
  summarise(humpop = sum(population)) #<<
df.pyrenees

#' 
#' ---
#' 
#' # Join, then calculate density
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
covariates <- covariates %>% 
  inner_join(df.pyrenees, by = 'idsite') %>% #<<
  mutate(.before = 1,
         humdens = humpop / (area/1000000)) #<<
as_tibble(covariates)

#' 
#' ---
#' 
#' # Map human population density
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300, eval = FALSE----
## covariates %>%
##   ggplot() +
##   aes(fill = as.numeric(humdens)) +
##   geom_sf(lwd = 0.1) +
##   scale_fill_viridis_c(
##     name = bquote('Density\n(people per km'^2*')'),
##     alpha = 0.7) +
##   labs(title = 'Human population density',
##        subtitle = 'Source: IGN GEOFLA 2016')

#' 
#' ---
#' 
#' # Map human population density
## ----echo=FALSE, fig.align='center', fig.dim=c(17, 12), message=FALSE, warning=FALSE, dpi = 300, paged.print=FALSE----
covariates %>%
  ggplot() +
  aes(fill = as.numeric(humdens)) +
  geom_sf(lwd = 0.1) +
  scale_fill_viridis_c(
    name = bquote('Density\n(people per km'^2*')'),
    alpha = 0.7) + 
  labs(title = 'Human population density',
       subtitle = 'Source: Source: IGN GEOFLA 2016')

#' 
#' ---
#' class: inverse, middle, center
#' # Spatial operations: distance
#' ---
#' 
#' 
#' # Distance to highways
#' 
#' * Distance to highways might be a driver of brown bear distribution
#' 
#' * We use data from [Route500 database](https://geoservices.ign.fr/documentation/diffusion/telechargement-donnees-libres.html#route-500)
#' 
#' ---
#' 
#' # Read in data
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
roads <- st_read("shp/TRONCON_ROUTE.shp")

#' 
#' ---
#' 
#' # Read in data
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
as_tibble(roads)

#' 
#' ---
#' 
#' # Focus on highways
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
highways <- roads %>%
  filter(CLASS_ADM == "Autoroute") #<<
as_tibble(highways)

#' 
#' ---
#' 
#' # Reproject and crop to match France extent
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
highways <- highways %>% 
  st_transform(crs = st_crs(forest)) %>% #<<
  st_crop(st_bbox(df.france)) #<<
as_tibble(highways)

#' 
#' ---
#' 
#' # Get centroids of each monitoring sites
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
centroids <- covariates %>% 
  st_centroid() #<<
as_tibble(centroids)

#' 
#' ---
#' 
#' # Then distance from centroids to highways
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
dtohighways <- highways %>% 
  st_distance(centroids, by_element = F) #<<
head(dtohighways)

#' 
#' ---
#' 
#' # Convert distance to highways into numeric values and keep only minimal distance to highways
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
units(dtohighways) <- units::as_units("km")
dtohighwaysnum <- matrix(as.numeric(dtohighways),
                      nrow = nrow(dtohighways),
                      ncol = ncol(dtohighways))
dtohighwaysnum <- apply(dtohighwaysnum,2,min)
head(dtohighwaysnum)

#' 
#' ---
#' 
#' # Map the distance to highways
## ----message=FALSE, warning=FALSE, paged.print=FALSE, eval = FALSE--------------------------------------------------
## covariates <- covariates %>%
##   add_column(dtohighwaysnum)
## covariates %>%
##   ggplot() +
##   geom_sf(lwd = 0.1, aes(fill = dtohighwaysnum)) +
##   scale_fill_viridis_c(name = 'distance\n(km)',alpha = 0.7) +
##   geom_sf(data = highways, aes(color = 'red'), show.legend = "line") +
##   scale_color_manual(values = "red", labels = "", name = "highway") +
##   coord_sf(xlim = st_bbox(covariates)[c(1,3)],
##            ylim = st_bbox(covariates)[c(2,4)]) + # what if you turn this off?
##   labs(title = 'Distance to highways in the Pyrénées',
##        subtitle = 'Source: Route500')

#' 
#' ---
#' 
#' # Map the distance to highways
## ----echo=FALSE, fig.align='center', fig.dim=c(15, 7), message=FALSE, warning=FALSE, dpi = 300, paged.print=FALSE----
covariates <- covariates %>%
  add_column(dtohighwaysnum)
covariates %>%
  ggplot() +
  geom_sf(lwd = 0.1, aes(fill = dtohighwaysnum)) +
  scale_fill_viridis_c(name = 'distance\n(km)',alpha = 0.7) + 
  geom_sf(data = highways, aes(color = 'red'), show.legend = "line") +
  scale_color_manual(values = "red", labels = "", name = "highway") +
  coord_sf(xlim = st_bbox(covariates)[c(1,3)], ylim = st_bbox(covariates)[c(2,4)]) + # what if you turn this off?
  labs(title = 'Distance to highways in the Pyrénées', subtitle = 'Source: Route500')

#' 
#' ---
#' class: inverse, middle, center
#' # Moooooore
#' ---
#' 
#' # Generate geometries from (X,Y) columns
#' 
#' * We use [EPSG code = 4326](https://epsg.io/4326) as CRS for WGS84 coordinates
#' 
#' * Let's make a tibble with 10 points
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE----------------------------------------------------------
random_pts <- tibble(
  id_point = seq_len(10),
  lat = c(42.96, 42.71, 42.72, 42.95, 42.96, 42.72, 42.68, 42.82, 42.79, 42.85),
  lon = c(0.31, 0.66, 0.75, 1.60, 0.58, 1.87, 1.07, 1.05, 0.36, 0.06)
)

sf_pts <- st_as_sf( #<<
  random_pts, coords = c("lon", "lat"), crs=4326, remove=FALSE)  #<<

#' 
#' ---
#' 
#' # Generate geometries from (X,Y) columns
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE----------------------------------------------------------
sf_pts

#' 
#' ---
#' 
#' # Display our points
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center', fig.dim = c(15, 7), dpi = 300-----
ggplot() +
  geom_sf(data = studysites) + 
  geom_sf(data = sf_pts) +
  labs(title = 'Study area and some random points')

#' 
#' ---
#' 
#' # Find points that intersect polygons
#' 
#' * `st_intersects` tells us which polygons intersect which points
#' * All objects should have same CRS
#' * If there is no intersection, we get an empty result
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
sf_pts <- sf_pts %>% 
  st_transform(st_crs(studysites))
result <- st_intersects(sf_pts, studysites) #<<
result

#' 
#' ---
#' 
#' # Find points that intersect polygons
#' 
#' * `st_intersects` tells us which polygons intersect which points
#' * All objects should have same CRS
#' * If there is no intersection, we get an empty result
#' 
## ----message=FALSE, warning=FALSE, paged.print=FALSE----------------------------------------------------------------
sf_pts <- sf_pts %>% 
  st_transform(st_crs(studysites))

result <- st_intersects(sf_pts, studysites)

subset_pts <- sf_pts %>%  #<<
  add_column(nb_intersected = sapply(result, length)) %>%  #<<
  filter(nb_intersected > 0)  #<<

#' 
#' ---
#' 
#' # Highlight points intersecting polygons
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300------
ggplot() +
  geom_sf(data = studysites) + 
  geom_sf(data = sf_pts) +
  geom_sf(data = subset_pts, color = "red") +
  labs(title = 'Study area and some random points')

#' 
#' ---
#' 
#' # How to make a grid
#' 
#' * Let's create an hexagonal grid with 10 km cells covering the study area
#' 
## ----message = FALSE, warning = FALSE, paged.print = FALSE, fig.align = 'center',fig.dim = c(15, 7), dpi = 300------
hex_grid <- st_make_grid(studysites, cellsize = 10000, square = FALSE)  #<<

ggplot() +
  geom_sf(data = studysites, color = NA, fill = "blue", alpha = 0.4) + 
  geom_sf(data = hex_grid, fill = NA, lwd = 0.2) +
  labs(title = 'A hexagonal grid')

#' 
#' ---
#' class: inverse, middle, center
#' # Wrap up
#' ---
#' 
#' 
#' ## Geometric calculations
#' 
#' **Geometric operations** on vector layers can conceptually be divided into **three groups** according to their output:
#' 
#' * **Numeric** values: Functions that summarize geometrical properties of: 
#'     * A **single layer** (e.g. area, length)
#'     * A **pair of layers** (e.g. distance)
#'     
#' * **Logical** values: Functions that evaluate whether a certain condition holds true, regarding:
#'     * A **single layer** (e.g. geometry is valid) 
#'     * A **pair of layers** (e.g. feature A intersects feature B)
#'     
#' * **Spatial** layers: Functions that create a new layer based on: 
#'     * A **single layer** (e.g. centroids) 
#'     * A **pair of layers** (e.g. intersection area)
#' 
#' ---
#' 
#' ## Numeric
#' 
#' * Several functions to calculate **numeric geometric properties** of vector layers: 
#'     * `st_length`
#'     * `st_area`
#'     * `st_distance`
#'     * `st_bbox`
#'     * ...
#' 
#' ---
#' 
#' ## Logical
#' 
#' * Given two layers, `x` and `y`, the following **logical geometric functions** check whether each feature in `x` maintains the specified **relation** with each feature in `y`:
#'     * `st_intersects`
#'     * `st_disjoint`
#'     * `st_touches`
#'     * `st_crosses`
#'     * `st_within`
#'     * `st_contains`
#'     * `st_overlaps`
#'     * `st_covers`
#'     * `st_equals`
#'     * ...
#' 
#' ---
#' 
#' ## Spatial
#' 
#' * Common **geometry-generating** functions applicable to **individual** geometries:
#'     * `st_centroid`
#'     * `st_buffer`
#'     * `st_union`
#'     * `st_sample`
#'     * `st_convex_hull`
#'     * `st_voronoi`
#'     * ...
#'     
#'     
#'     
#' ---
#' 
#' ## All `sf` methods
#' 
## ---- echo=FALSE----------------------------------------------------------------------------------------------------
methods(class='sf')

#' 
#' 
#' ---
#' class: inverse, middle, center
#' # To go further
#' ---
#' 
#' 
#' # To dive even deeper into sf
#' 
#' * Detailed sf package [vignettes](https://r-spatial.github.io/sf/articles/)
#' 
#' * Blog posts: [here](https://www.r-spatial.org/r/2016/02/15/simple-features-for-r.html), [here](https://www.r-spatial.org/r/2016/07/18/sf2.html), [here](https://www.r-spatial.org/r/2016/11/02/sfcran.html), [here](https://www.r-spatial.org/r/2017/01/12/newssf.html) and [there](https://statnmap.com/fr/2018-07-14-initiation-a-la-cartographie-avec-sf-et-compagnie/) (in French)
#' 
#' * [wiki page](https://github.com/r-spatial/sf/wiki/Migrating) describing sp-sf migration
#' 
#' * Awesome online book [Geocomputation with R](https://geocompr.robinlovelace.net/) by Lovelace, Nowosad and Muenchow
#' 
## ----echo=FALSE, message=FALSE, warning=FALSE, paged.print=FALSE, out.width = "150px", fig.align = "center"---------
knitr::include_graphics("img/lovelacebookcover.png")

#' 
#' ---
#' 
#' # The [RStudio Cheat Sheets](https://www.rstudio.com/resources/cheatsheets/)
#' 
## ----echo=FALSE, message=FALSE, warning=FALSE, paged.print=FALSE, out.width = "600px", fig.align = "center"---------
knitr::include_graphics("img/sf_Page_1.png")

#' 
#' ---
#' 
#' # The [RStudio Cheat Sheets](https://www.rstudio.com/resources/cheatsheets/)
#' 
## ----echo=FALSE, message=FALSE, warning=FALSE, paged.print=FALSE, out.width = "600px", fig.align = "center"---------
knitr::include_graphics("img/sf_Page_2.png")

#' 
#' 
#' ---
#' class: title-slide-final, middle
#' background-size: 55px
#' background-position: 9% 15%
#' 
#' # Thanks!
#' 
#' ### I created these slides with [xaringan](https://github.com/yihui/xaringan) and [RMarkdown](https://rmarkdown.rstudio.com/) using the [rutgers css](https://github.com/jvcasillas/ru_xaringan) that I slightly modified.
#' 
#' ### Credits: @cyber_nard contributed a few slides, and I used material from @StrimasMackey, @jafflerbach, @StatnMap, @SharpSightLabs and @edzerpebesma