#' make_lines()
#'
#' Converts GPS data/ waypoints to line features. Attribute data is maintained.
#' Currently, this function generates points to transect by converting the _POINT_
#' feature data to LINES sf features.
#' A placeholder has been made to generate transect lines via the transect method created by M. Coghill.
#'
#' @param GPSPoints is a _simple features_ POINT object.
#' Minimum attributes in this file include fields named _'id'_ and _'time'_.
#' Waypoints will be sorted by these two entries.
#' @param Transects is the original planned transect simple feature.
#' The _'id'_ attribute in this feature will be used to group points by their transect id.
#' This transect id will be named 'TID' in the output data.
#' @param method Multiple methods to be made available:
#' - _pts2lines_ takes a sf POINT object and converts it to lines.
#' _This is currently the only function available
#' - _tracklog_ uses the tracklog and the sample points to generate the lines. _Not implemented yet_.
#' @param sortby Field in the points data to sort the points by. Defaults to _"none"_ (i.e. assumes no sorting of data)
#' @param tBuffer is optional with a default of 20m. This is the buffer distance to place around the transect. Waypoints outside this distance will not be considered.
#' @param PROJ is an optional the epsg projection code with a default of BC Albers (3005). Data imported will be transfored to this projection and final data will be exported in this projection.
#' @keywords points, lines, convertion
#' @export
#' @examples
#' ## Convert GPS waypoints to line features (i.e. transect data)
#' transects <- convert_pts2lines(gpsData, PlannedTransects)
make_lines <- function(GPSPoints, Transects, method = "pts2lines", sortby = "none", tBuffer = 20, PROJ = 3005) {
library(sf) ## shouldn't need this ... but just incase
if (method == "pts2lines") {
## Transects
planT <- Transects %>%
dplyr::mutate(TID = row_number()) %>%
# rename(TID = id) %>% ## rename the id to not conflict with the GPS id field
sf::st_buffer(.,tBuffer) %>% dplyr::select(TID)
## Transform data to PROJ
planT <- planT %>% sf::st_transform(PROJ)
GPSPoints <- GPSPoints %>% sf::st_transform(PROJ)
## Spatial join attributes
GPSPoints <- st_join(GPSPoints, planT)
## TESTING
# PROJ <- 26910
# GPSPoints <- gpsData #%>% dplyr::select(name, time)
## f(n) start
## ADD TRANSECT ID -- and the arrange TID, time
## Sort Data ---------
if (sortby != "none") {
# sortby <- "name"
sortField <- eval(parse(text = paste0("GPSPoints$", sortby)))
GPSPoints <- GPSPoints[order(sortField),]
}
GPSPoints <- GPSPoints %>%
rowid_to_column("ID") # ID is needed table manipulation below
## convert GPSPoints to a table for manipulation
xy <- sf::st_coordinates(GPSPoints)
GPSPoints <- cbind(GPSPoints, xy)
GPSPoints <- GPSPoints %>% st_zm %>% as.data.frame()
## this solves issue where geom is named 'geometry' other times 'geom'
if("geom" %in% names(GPSPoints)) {
GPSPoints <- GPSPoints %>% dplyr::rename(geometry = geom)}
## Define the Line Start and End Coordinates
## Add XY coordinates as
lines <- GPSPoints %>%
dplyr::mutate(Xend = lead(X),
Yend = lead(Y)) %>% # collect the coordinates of the next point
dplyr::filter(!is.na(Yend)) #%>% # drops the last row (start point with no end)
# dplyr::select(-geometry)
## Use data.table with sf to create the line geometry
dt <- data.table::as.data.table(lines)
sf <- dt[,
{
geometry <- sf::st_linestring(x = matrix(c(X, Xend, Y, Yend), ncol = 2))
geometry <- sf::st_sfc(geometry)
geometry <- sf::st_sf(geometry = geometry)
}
, by = ID
]
## Replace the geometry
lines$geometry <- sf$geometry
## Declare as a simple feature
lines <- st_sf(lines)
st_crs(lines) <- PROJ
## Need to remove excess lines -- currently there are lines that run between the plots
lines$within <- as.logical(st_within(lines, planT))
lines <- lines[!is.na(lines$within == TRUE),] ## removes lines not contained in Transect area
## There are a few invalid geometries
lines$valid <- as.logical(st_is_valid(lines))
# lines <- lines[lines$valid == TRUE,] ## removes lines not contained in Transect area
# lines <- lines %>% dplyr::select(TID, id, name, time, SiteSeries:Confidence)
return(lines)
} else {
## Begin transect method ----------------------------------------------------
## ADD MC's code here
if (method == "tracklog") {
print("Not built yet")
print("Copy in MC's code")
}
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.