# install.packages(c("maps","sf", "raster"))

library(maps)     # convinient pkg for maps of the world
library(sf)
## Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 8.2.1; sf_use_s2() is TRUE
# First, make some maps. The "maps" package has databases="world","usa","state",
# or "county". (There are also a few for foreign countries like France and
# Italy.) In each database, you can plot any region or group of regions.

world <- map(database="world")

names(world)
## [1] "x"     "y"     "range" "names"
head(world$names)
## [1] "Aruba"          "Afghanistan"    "Angola"         "Angola:Cabinda"
## [5] "Anguilla"       "Albania"
# names in world database can all be plot as a region. For example:
map(database="world", regions=c("Cambodia","Thailand","Vietnam","Laos"))

map(database="state",regions=c("virginia","north carolina","south carolina"))

# you can add cities using map.cities command.

nc_county <- map(database="county",regions="north carolina")

head(nc_county$names)
## [1] "north carolina,alamance"  "north carolina,alexander"
## [3] "north carolina,alleghany" "north carolina,anson"    
## [5] "north carolina,ashe"      "north carolina,avery"
triangle <- map(database="county",
               regions=c("north carolina,orange","north carolina,wake","north carolina,durham"),
               fill=T, plot=F)
triangle$names
## [1] "north carolina,durham" "north carolina,orange" "north carolina,wake"
# We can turn a map into a spatial polygons object and fill it with data,
# turning it into a spatial polygon dataframe.

tri_sf <- st_as_sf(triangle)

plot(tri_sf, axes=T)

# add data to make spatial polygons data frame
population <- c(266132, 132272, 892409) 

tri_sf$pop <- population

plot(tri_sf['pop'])

# If your data are in different projections, you need to change the projection
# so that they are all in 
# the same coordinate reference system.

world <- map(database="world", fill=T, plot=F)
world_longlat <- st_as_sf(world) 

# use fucntion spTransform to transform to mercator
world_merc <- st_transform(world_longlat, crs=st_crs("+proj=merc"))
# Lambert Azimuthal Equal Area
world_laea <- st_transform(world_longlat, crs=st_crs("+proj=laea"))
# sinusoidal
world_sinusoidal <- st_transform(world_longlat,
                                 crs=st_crs("+proj=sinu"))

# plot the four together to see the difference. Mercator projection distorts
# area far from the equator. LAEA is accurately represents area but not angles.
# Sinusoidal is equal area and conserves distances along parallels.
par(mfrow=c(1,1))
plot(world_longlat)

plot(world_merc)

plot(world_laea)

plot(world_sinusoidal)

# A four page cheat sheet about coordinate reference systems (CRSs), including
# projections, datums, and coordinate systems, and the use of these in R.
#https://www.nceas.ucsb.edu/sites/default/files/2020-04/OverviewCoordinateReferenceSystems.pdf
# A fun projection link
# http://xkcd.com/977/

# OK, some slightly more complicated stuff. Data from MODIS fire detections in
# the US in 2010.
# metadata for MODIS fire data available at:
# http://firemapper.sc.egov.usda.gov/data/fireptdata/modisfire_2010_conus.htm

fire2010 <- sf::st_read(dsn = './data/MODISfire2010',
                        layer = 'modis_fire_2010_365_conus')
## Reading layer `modis_fire_2010_365_conus' from data source 
##   `/home/mcglinndj/quant_methods/data/MODISfire2010' using driver `ESRI Shapefile'
## Simple feature collection with 131586 features and 16 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -124.883 ymin: 25.165 xmax: -67.379 ymax: 49.454
## Geodetic CRS:  NAD83
class(fire2010)
## [1] "sf"         "data.frame"
names(fire2010)  
##  [1] "AREA"      "PERIMETER" "FIRE_"     "FIRE_ID"   "LAT"       "LONG"     
##  [7] "DATE"      "JULIAN"    "GMT"       "TEMP"      "SPIX"      "TPIX"     
## [13] "SRC"       "SAT_SRC"   "CONF"      "FRP"       "geometry"
st_crs(fire2010)  # retrieves coordinate reference system
## Coordinate Reference System:
##   User input: NAD83 
##   wkt:
## GEOGCRS["NAD83",
##     DATUM["North American Datum 1983",
##         ELLIPSOID["GRS 1980",6378137,298.257222101,
##             LENGTHUNIT["metre",1]]],
##     PRIMEM["Greenwich",0,
##         ANGLEUNIT["degree",0.0174532925199433]],
##     CS[ellipsoidal,2],
##         AXIS["latitude",north,
##             ORDER[1],
##             ANGLEUNIT["degree",0.0174532925199433]],
##         AXIS["longitude",east,
##             ORDER[2],
##             ANGLEUNIT["degree",0.0174532925199433]],
##     ID["EPSG",4269]]
dim(fire2010)
## [1] 131586     17
# make a map of Julian day of each fire
plot(fire2010["JULIAN"], cex = 0.25)

# get summary statistics for each attribute

summary(fire2010)
##       AREA     PERIMETER     FIRE_           FIRE_ID            LAT       
##  Min.   :0   Min.   :0   Min.   :     1   Min.   :    63   Min.   :25.16  
##  1st Qu.:0   1st Qu.:0   1st Qu.: 32897   1st Qu.: 76054   1st Qu.:32.02  
##  Median :0   Median :0   Median : 65794   Median :302178   Median :34.91  
##  Mean   :0   Mean   :0   Mean   : 65794   Mean   :249912   Mean   :36.01  
##  3rd Qu.:0   3rd Qu.:0   3rd Qu.: 98690   3rd Qu.:391697   3rd Qu.:38.70  
##  Max.   :0   Max.   :0   Max.   :131586   Max.   :482122   Max.   :49.45  
##       LONG              DATE                JULIAN           GMT      
##  Min.   :-124.88   Min.   :2010-01-01   Min.   :  1.0   Min.   : 233  
##  1st Qu.:-100.07   1st Qu.:2010-04-16   1st Qu.:106.0   1st Qu.:1805  
##  Median : -92.73   Median :2010-08-31   Median :243.0   Median :1858  
##  Mean   : -95.71   Mean   :2010-07-27   Mean   :208.4   Mean   :1803  
##  3rd Qu.: -87.06   3rd Qu.:2010-10-08   3rd Qu.:281.0   3rd Qu.:1931  
##  Max.   : -67.38   Max.   :2010-12-31   Max.   :365.0   Max.   :2210  
##       TEMP            SPIX            TPIX           SRC           
##  Min.   :305.0   Min.   :1.000   Min.   :1.000   Length:131586     
##  1st Qu.:315.0   1st Qu.:1.100   1st Qu.:1.000   Class :character  
##  Median :320.9   Median :1.300   Median :1.100   Mode  :character  
##  Mean   :326.1   Mean   :1.564   Mean   :1.193                     
##  3rd Qu.:330.9   3rd Qu.:1.700   3rd Qu.:1.300                     
##  Max.   :502.6   Max.   :4.800   Max.   :2.000                     
##    SAT_SRC               CONF             FRP                    geometry     
##  Length:131586      Min.   :  0.00   Min.   :-9999.00   POINT        :131586  
##  Class :character   1st Qu.: 56.00   1st Qu.:   16.60   epsg:4269    :     0  
##  Mode  :character   Median : 70.00   Median :   29.60   +proj=long...:     0  
##                     Mean   : 68.52   Mean   :   44.01                         
##                     3rd Qu.: 83.00   3rd Qu.:   60.10                         
##                     Max.   :100.00   Max.   : 5317.30
# subsetting: select fires that occurred in the last 6 months (days 182 to 365)
# of 2010

fire <- subset(fire2010, JULIAN > 182)
class(fire)
## [1] "sf"         "data.frame"
names(fire)
##  [1] "AREA"      "PERIMETER" "FIRE_"     "FIRE_ID"   "LAT"       "LONG"     
##  [7] "DATE"      "JULIAN"    "GMT"       "TEMP"      "SPIX"      "TPIX"     
## [13] "SRC"       "SAT_SRC"   "CONF"      "FRP"       "geometry"
dim(fire)
## [1] 82802    17
summary(fire)
##       AREA     PERIMETER     FIRE_           FIRE_ID            LAT       
##  Min.   :0   Min.   :0   Min.   :     4   Min.   :190935   Min.   :25.36  
##  1st Qu.:0   1st Qu.:0   1st Qu.: 32126   1st Qu.:309123   1st Qu.:32.31  
##  Median :0   Median :0   Median : 65616   Median :356566   Median :34.94  
##  Mean   :0   Mean   :0   Mean   : 64651   Mean   :359921   Mean   :36.19  
##  3rd Qu.:0   3rd Qu.:0   3rd Qu.: 95393   3rd Qu.:418602   3rd Qu.:38.93  
##  Max.   :0   Max.   :0   Max.   :131580   Max.   :482122   Max.   :49.45  
##       LONG              DATE                JULIAN         GMT      
##  Min.   :-124.88   Min.   :2010-07-02   Min.   :183   Min.   : 233  
##  1st Qu.:-110.42   1st Qu.:2010-09-06   1st Qu.:249   1st Qu.:1700  
##  Median : -92.50   Median :2010-09-30   Median :273   Median :1840  
##  Mean   : -97.42   Mean   :2010-10-01   Mean   :274   Mean   :1752  
##  3rd Qu.: -89.33   3rd Qu.:2010-10-23   3rd Qu.:296   3rd Qu.:1923  
##  Max.   : -68.04   Max.   :2010-12-31   Max.   :365   Max.   :2210  
##       TEMP            SPIX            TPIX           SRC           
##  Min.   :305.0   Min.   :1.000   Min.   :1.000   Length:82802      
##  1st Qu.:315.2   1st Qu.:1.100   1st Qu.:1.000   Class :character  
##  Median :321.4   Median :1.300   Median :1.100   Mode  :character  
##  Mean   :326.7   Mean   :1.571   Mean   :1.195                     
##  3rd Qu.:331.6   3rd Qu.:1.700   3rd Qu.:1.300                     
##  Max.   :502.6   Max.   :4.800   Max.   :2.000                     
##    SAT_SRC               CONF             FRP                   geometry    
##  Length:82802       Min.   :  0.00   Min.   :   0.00   POINT        :82802  
##  Class :character   1st Qu.: 57.00   1st Qu.:  17.10   epsg:4269    :    0  
##  Mode  :character   Median : 71.00   Median :  30.90   +proj=long...:    0  
##                     Mean   : 69.47   Mean   :  62.36                        
##                     3rd Qu.: 84.00   3rd Qu.:  62.60                        
##                     Max.   :100.00   Max.   :5317.30
plot(fire['JULIAN'], cex = 0.25)

# select the fires in NC. First we'll identify which state each fire occurred
# in, then subset the ones from NC. 
USA <- map(database='state', plot=F, fill=T)
names(USA)
## [1] "x"     "y"     "range" "names"
USA$names
##  [1] "alabama"                         "arizona"                        
##  [3] "arkansas"                        "california"                     
##  [5] "colorado"                        "connecticut"                    
##  [7] "delaware"                        "district of columbia"           
##  [9] "florida"                         "georgia"                        
## [11] "idaho"                           "illinois"                       
## [13] "indiana"                         "iowa"                           
## [15] "kansas"                          "kentucky"                       
## [17] "louisiana"                       "maine"                          
## [19] "maryland"                        "massachusetts:martha's vineyard"
## [21] "massachusetts:main"              "massachusetts:nantucket"        
## [23] "michigan:north"                  "michigan:south"                 
## [25] "minnesota"                       "mississippi"                    
## [27] "missouri"                        "montana"                        
## [29] "nebraska"                        "nevada"                         
## [31] "new hampshire"                   "new jersey"                     
## [33] "new mexico"                      "new york:manhattan"             
## [35] "new york:main"                   "new york:staten island"         
## [37] "new york:long island"            "north carolina:knotts"          
## [39] "north carolina:main"             "north carolina:spit"            
## [41] "north dakota"                    "ohio"                           
## [43] "oklahoma"                        "oregon"                         
## [45] "pennsylvania"                    "rhode island"                   
## [47] "south carolina"                  "south dakota"                   
## [49] "tennessee"                       "texas"                          
## [51] "utah"                            "vermont"                        
## [53] "virginia:chesapeake"             "virginia:chincoteague"          
## [55] "virginia:main"                   "washington:san juan island"     
## [57] "washington:lopez island"         "washington:orcas island"        
## [59] "washington:whidbey island"       "washington:main"                
## [61] "west virginia"                   "wisconsin"                      
## [63] "wyoming"
USA_sf <- st_as_sf(USA)

# make sure projection of USA polygon is same as fire points
USA_sf <- st_transform(USA_sf, st_crs(fire))

# overlay performs a "point in polygon" operation--meaning that it will return
# us a vector giving the index of which polygon in USA_sp each point in firehot
# is. We then index that to names(USA_sp) to get the name of the state for that
# index.
sf_use_s2(FALSE)
## Spherical geometry (s2) switched off
fire_state <- st_intersection(fire, USA_sf)
## although coordinates are longitude/latitude, st_intersection assumes that they
## are planar
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
# Then, subset the ones from NC. We have to use grep because there are actually
# three polygons for NC.
firenc <- fire_state[grep("north carolina", fire_state$ID), ]
dim(firenc)
## [1] 1188   18
# make a map of fires by temperature. 
addLegendToSFPlot <- function(values = c(0, 1), labels = c("Low", "High"), 
                              palette = c("blue", "red"), ...){

    # Get the axis limits and calculate size
    axisLimits <- par()$usr
    xLength <- axisLimits[2] - axisLimits[1]
    yLength <- axisLimits[4] - axisLimits[3]

    # Define the colour palette
    colourPalette <- leaflet::colorNumeric(palette, range(values))

    # Add the legend
    plotrix::color.legend(xl=axisLimits[2] - 0.1*xLength, xr=axisLimits[2],
                          yb=axisLimits[3], yt=axisLimits[3] + 0.1 * yLength,
                          legend = labels, rect.col = colourPalette(values), 
                          gradient="y", ...)
}

#First make an NC spatial polygon to put
# around the fire points.

NC <- map(database='state', regions='north carolina', fill=T,
          plot=F)
                            
NC_st <- st_as_sf(NC)
NC_st <- st_transform(NC_st, crs=st_crs(firenc))

cuts <- cut(firenc$JULIAN, 10)
colors <- heat.colors(10)[as.numeric(cuts)] 

plot(st_geometry(NC_st))
plot(st_geometry(firenc['JULIAN']), add = TRUE,
     col = colors, pch = 19, cex = 0.5)


addLegendToSFPlot(values = seq(from = 183, to = 363, length.out = 10), 
                  labels = c("Low", "", "", "", "Medium", "", "", "", "", "High"),
                  palette = heat.colors(10))

# cannot figure out how to combine in ggplot nicely. 
#ggplot(NC_st) + geom_sf()
#ggplot(firenc['JULIAN']) + geom_sf() 
#geom_point(st_geometry(firenc['JULIAN']))

# for the last step, let's export this as a KML (readable by google earth) using
# write OGR and plot the locations of fires in NC in google earth. The first
# argument is the object we want to export, the second is the filename (by
# default it will go in our working directory), the layer we want to export, and
# the file format.
write_sf(firenc, "firenctemp.kml", "TEMP", driver="kml")

## Rasters ----------------------------------------
## download Rdata file here:
## https://www.dropbox.com/s/gafxazc9575nf3j/bioclim_10m.Rdata?dl=0
library(raster)
## Loading required package: sp
load('./data/bioclim_10m.Rdata')
plot(bioStack, "mat")

?extract
## Help on topic 'extract' was found in the following packages:
## 
##   Package               Library
##   magrittr              /home/mcglinndj/R/x86_64-pc-linux-gnu-library/4.3
##   raster                /home/mcglinndj/R/x86_64-pc-linux-gnu-library/4.3
##   terra                 /home/mcglinndj/R/x86_64-pc-linux-gnu-library/4.3
## 
## 
## Using the first match ...
fire_climate <- extract(bioStack, firenc)
class(fire_climate)
## [1] "matrix" "array"
head(fire_climate)
##       mat  mdr iso tseas tmax tmin  tar twetq tdryq twarmq tcoldq   ap pwet
## [1,] 14.1 13.5 3.8 787.9 31.7 -3.3 35.0  24.1   5.4   24.1    3.7 1112  111
## [2,] 11.3 13.2 3.9 742.2 27.8 -5.6 33.4  18.9   1.4   20.6    1.4 1245  122
## [3,] 11.3 13.2 3.9 742.2 27.8 -5.6 33.4  18.9   1.4   20.6    1.4 1245  122
## [4,] 11.3 13.2 3.9 742.2 27.8 -5.6 33.4  18.9   1.4   20.6    1.4 1245  122
## [5,] 13.1 13.8 3.9 767.0 30.3 -4.3 34.6  21.0   4.5   22.8    2.9 1183  113
## [6,] 13.1 13.8 3.9 767.0 30.3 -4.3 34.6  21.0   4.5   22.8    2.9 1183  113
##      pdry pseas pwetq pdryq pwarmq pcoldq
## [1,]   79     9   304   252    304    259
## [2,]   83    11   345   264    329    264
## [3,]   83    11   345   264    329    264
## [4,]   83    11   345   264    329    264
## [5,]   84    10   328   257    318    264
## [6,]   84    10   328   257    318    264
nrow(fire_climate)
## [1] 1188
firenc <- cbind(firenc, fire_climate)
head(firenc)
## Simple feature collection with 6 features and 36 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -81.108 ymin: 36.421 xmax: -79.374 ymax: 36.543
## Geodetic CRS:  NAD83
##       AREA PERIMETER FIRE_ FIRE_ID    LAT    LONG       DATE JULIAN  GMT  TEMP
## 49833    0         0 49833  259985 36.543 -79.374 2010-08-12    224 1822 322.1
## 50331    0         0 50331  337411 36.490 -81.108 2010-10-20    293 1840 315.8
## 50332    0         0 50332  337410 36.490 -81.108 2010-10-20    293 1840 315.8
## 50350    0         0 50350  337409 36.489 -81.107 2010-10-20    293 1840 315.8
## 51019    0         0 51019  470917 36.421 -80.686 2010-11-22    326 1603 324.2
## 51020    0         0 51020  470918 36.421 -80.686 2010-11-22    326 1604 324.2
##       SPIX TPIX      SRC SAT_SRC CONF  FRP             ID  mat  mdr iso tseas
## 49833  1.0    1 gsfc_drl       A   51 12.2 north carolina 14.1 13.5 3.8 787.9
## 50331  1.1    1 gsfc_drl       A   64 21.9 north carolina 11.3 13.2 3.9 742.2
## 50332  1.1    1     ssec       A   64 21.9 north carolina 11.3 13.2 3.9 742.2
## 50350  1.1    1     gsfc       A   64 21.9 north carolina 11.3 13.2 3.9 742.2
## 51019  1.1    1     ssec       T   77 31.7 north carolina 13.1 13.8 3.9 767.0
## 51020  1.1    1 gsfc_drl       T   77 31.7 north carolina 13.1 13.8 3.9 767.0
##       tmax tmin  tar twetq tdryq twarmq tcoldq   ap pwet pdry pseas pwetq pdryq
## 49833 31.7 -3.3 35.0  24.1   5.4   24.1    3.7 1112  111   79     9   304   252
## 50331 27.8 -5.6 33.4  18.9   1.4   20.6    1.4 1245  122   83    11   345   264
## 50332 27.8 -5.6 33.4  18.9   1.4   20.6    1.4 1245  122   83    11   345   264
## 50350 27.8 -5.6 33.4  18.9   1.4   20.6    1.4 1245  122   83    11   345   264
## 51019 30.3 -4.3 34.6  21.0   4.5   22.8    2.9 1183  113   84    10   328   257
## 51020 30.3 -4.3 34.6  21.0   4.5   22.8    2.9 1183  113   84    10   328   257
##       pwarmq pcoldq               geometry
## 49833    304    259 POINT (-79.374 36.543)
## 50331    329    264  POINT (-81.108 36.49)
## 50332    329    264  POINT (-81.108 36.49)
## 50350    329    264 POINT (-81.107 36.489)
## 51019    318    264 POINT (-80.686 36.421)
## 51020    318    264 POINT (-80.686 36.421)
plot(TEMP ~ ap, data=firenc) 

Here is a quick demo of a new R package called leaflet

https://rstudio.github.io/leaflet

library(leaflet)
mapStates = map("state", fill = TRUE, plot = FALSE)
leaflet(data = mapStates) %>% addTiles() %>%
  addPolygons(fillColor = topo.colors(10, alpha = NULL), stroke = FALSE)
m <- leaflet(data = firenc) %>% addTiles() %>%
  addCircleMarkers(radius = 2, label = ~as.character(firenc$TEMP))
## Warning: sf layer has inconsistent datum (+proj=longlat +datum=NAD83 +no_defs).
## Need '+proj=longlat +datum=WGS84'
m %>% addProviderTiles(providers$Esri.NatGeoWorldMap)
m = leaflet() %>% addTiles()
df = data.frame(
  lat = rnorm(100),
  lng = rnorm(100),
  size = runif(100, 5, 20),
  color = sample(colors(), 100)
)
m = leaflet(df) %>% addTiles()
m %>% addCircleMarkers(radius = ~size, color = ~color, fill = FALSE)
## Assuming "lng" and "lat" are longitude and latitude, respectively
m %>% addCircleMarkers(radius = runif(100, 4, 10), color = c('red'))
## Assuming "lng" and "lat" are longitude and latitude, respectively
m %>% addProviderTiles(providers$Esri.NatGeoWorldMap)