forked from HeritageNetwork/Regional_SDM
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path2_attributePoints.R
122 lines (97 loc) · 4.41 KB
/
2_attributePoints.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File: 2_attributePoints.r
# Purpose: attribute environmental data to presence points
## start with a fresh workspace with no objects loaded
library(raster)
library(sf)
# library(rgdal)
library(RSQLite)
# library(maptools)
# load data, QC ----
setwd(loc_envVars)
# create a stack
# if using TIFFs, use this line
raslist <- list.files(pattern = ".tif$", recursive = TRUE)
# if using native R rasters, use this line
#raslist <- list.files(pattern = ".grd$")
# find temporal vars (placed in subfolders)
raslist.t <- raslist[grep("/",raslist,fixed = TRUE)]
# exclude temporal vars, for the moment
# raslist <- raslist[-grep("/",raslist,fixed = TRUE)]
gridlist <- as.list(paste(loc_envVars,raslist,sep = "/"))
nm <- substr(raslist,1,nchar(raslist) - 4)
names(gridlist) <- nm
# check to make sure there are no names greater than 10 chars
nmLen <- unlist(lapply(nm, nchar))
max(nmLen) # if this result is greater than 10, you've got a renegade
# Set working directory to the random points location
setwd(paste0(loc_model, "/", model_species, "/inputs"))
shpf <- st_read(paste0("presence/", baseName, "_RanPts.shp"),quiet = T)
# subset input env. vars by model type (terrestrial, shore, etc)
db <- dbConnect(SQLite(),dbname=nm_db_file)
# get MODTYPE
SQLQuery <- paste0("SELECT MODTYPE m FROM lkpSpecies WHERE sp_code = '", model_species, "';")
modType <- dbGetQuery(db, SQLQuery)$m
SQLQuery <- paste0("SELECT gridName g FROM lkpEnvVars WHERE use_",modType," = 1;")
gridlistSub <- dbGetQuery(db, SQLQuery)$g
# get just names of grids (removes folder for temporal vars)
justTheNames <- unlist(lapply(strsplit(names(gridlist), "/", fixed = TRUE), FUN = function(x) {x[length(x)]}))
## account for add/remove vars
if (!is.null(add_vars)) {
add_vars1 <- add_vars
add_vars <- tolower(add_vars)
db <- dbConnect(SQLite(),dbname=nm_db_file)
SQLQuery <- paste0("SELECT gridName g FROM lkpEnvVars;")
gridlistAll <- tolower(dbGetQuery(db, SQLQuery)$g)
dbDisconnect(db)
if (!all(add_vars %in% gridlistAll)) {
stop("Some environmental variables listed in `add_vars` were not found in `nm_EnvVars` dataset: ",
paste(add_vars1[!add_vars %in% gridlistSub], collapse = ", "), ".")
}
gridlistSub <- c(gridlistSub, add_vars)
}
if (!is.null(remove_vars)) {
remove_vars1 <- remove_vars
remove_vars <- tolower(remove_vars)
if (!all(remove_vars %in% gridlistSub)) {
message("Some environmental variables listed in `remove_vars` were not found in the `nm_EnvVars` dataset: ",
paste(remove_vars1[!remove_vars %in% gridlistSub], collapse = ", "), ".")
}
gridlistSub <- gridlistSub[!tolower(gridlistSub) %in% tolower(remove_vars)]
}
# make grid stack with subset
envStack <- stack(gridlist[tolower(justTheNames) %in% tolower(gridlistSub)]) # points are transformed to raster CRS, if not matching
rm(justTheNames, gridlistSub, modType)
# extract raster data to points ----
## Bilinear interpolation is a *huge* memory hog.
## Do it all as 'simple'
points_attributed <- extract(envStack, shpf, method="simple", sp=TRUE)
# temporal variables data handling
pa <- points_attributed
tv <- names(pa)[grep(".",names(pa), fixed = TRUE)]
if (length(tv) > 0) {
tvDataYear <- do.call(rbind.data.frame, strsplit(tv, "_|\\."))
names(tvDataYear) <- c("dataset", "date", "envvar")
tvDataYear$date <- as.numeric(as.character(tvDataYear$date))
# loop over temporal variables
for (i in unique(tvDataYear$envvar)) {
tvDataYear.s <- subset(tvDataYear, tvDataYear$envvar == i)
yrs <- sort(unique(tvDataYear.s$date))
# add 0.1 to occurrence date/year, avoiding cases where date is exactly between two years
closestYear <- unlist(lapply(as.numeric(pa$date) + 0.1, FUN = function(x) {
y <- abs(x - yrs)
yrs[which.min(y)]}))
# DECIDE IF THERE SHOULD BE A CUTOFF FOR WHEN OBSERVATION YEAR IS NOT CLOSE TO ANY OF THE DATES #
vals <- unlist(lapply(1:length(pa), FUN = function(x) {
eval(parse(text = paste0("pa$", tvDataYear.s$dataset[1],"_",closestYear[x],".",i, "[", x , "]")
))
}))
# add to pa
eval(parse(text = paste0("pa$", i, " <- vals")))
}
points_attributed <- pa[-grep(".", names(pa), fixed = TRUE)]
}
suppressWarnings(rm(tv,tvDataYear,tvDataYear.s, yrs, closestYear, vals, pa))
# write it out ----
filename <- paste(baseName, "_att.shp", sep="")
points_attributed <- st_as_sf(points_attributed)
st_write(points_attributed, paste0("model_input/", filename), delete_layer = T)