createTrajectory.R (3606B)
1 #' Create a flighttrajectory object from the flight info. 2 #' 3 #' @param longitude Required; numeric vector giving aircraft longitude in 4 #' degrees. 5 #' @param latitude Required; numeric vector giving aircraft latitude in degrees. 6 #' @param altitude Optional; numeric vector giving aircraft altitude (AGL) in 7 #' feet. If missing, it will be set to 0. 8 #' @param timestamp Optional; numeric vector giving the time of each observation 9 #' in seconds. If missing, the observation period is assumed to be 1 s. 10 #' @param bearing Optional; numeric vector giving the current bearing in 11 #' degrees. If missing, it is estimated using pairs of successive lon/lat 12 #' observations. 13 #' @param groundspeed Optional; numeric vector giving the current ground speed 14 #' of the aircraft in knots. If missing, it is estimated using pairs of 15 #' successive lon/lat observations. 16 #' @return A flighttrajectory object encapsulating these parameters (with 17 #' default values substituded as necessary). 18 #' 19 #' @details \code{longitude} and \code{latitude} must be the same length. 20 #' \code{timestamp}, \code{bearing}, and \code{groundspeed}, if present, must 21 #' also match this length. \code{altitude} must also have a length equal to 22 #' these parameters or be scalar. 23 #' 24 #' @export 25 createTrajectory <- function(longitude, latitude, altitude = 0, timestamp = NULL, 26 bearing = NULL, groundspeed = NULL) { 27 if (!is.numeric(longitude)) stop("\"longitude\" must be a numeric vector") 28 nCoord <- length(longitude) 29 30 # Helper function to throw an error if the length of a vector is incorrect. 31 checkLength <- function(x) { 32 if (!is.numeric(x)) { 33 stop("\"", deparse(substitute(x)), "\" must be a numeric vector") 34 } else if (length(x) != nCoord) { 35 stop("Vector \"", deparse(substitute(x)), "\" has length = ", length(x), 36 ", expected length = ", nCoord) 37 } 38 return(TRUE) 39 } 40 41 checkLength(latitude) 42 coords <- cbind(longitude, latitude) 43 44 if (length(altitude) == 1) { 45 altitude <- rep(altitude, nCoord) 46 } else { 47 checkLength(altitude) 48 } 49 50 if (is.null(timestamp)) { 51 timestamp <- seq(1, nCoord) 52 } else { 53 checkLength(timestamp) 54 } 55 56 # Use flightpathr to calculate bearing between successive points if not 57 # specified. 58 if (is.null(bearing)) { 59 bearing <- coordsToBearing(longitude, latitude) 60 bearing[nCoord] <- bearing[nCoord-1] 61 } else { 62 checkLength(bearing) 63 } 64 65 # Use geosphere to find the distance between points and use the timestamps to 66 # calculate groundspeed if not specified. 67 if (is.null(groundspeed)) { 68 distNM <- geosphere::distCosine(coords[1:(nCoord-1), ], 69 coords[2:nCoord, ], 70 r = 3444) 71 groundspeed <- distNM / diff(timestamp) * 3600 72 groundspeed <- c(groundspeed, groundspeed[nCoord-1]) 73 } else{ 74 checkLength(groundspeed) 75 } 76 77 flighttrajectory <- list(longitude = longitude, 78 latitude = latitude, 79 altitude = altitude, 80 timestamp = timestamp, 81 bearing = bearing, 82 groundspeed = groundspeed) 83 class(flighttrajectory) <- "flighttrajectory" 84 85 return(flighttrajectory) 86 } 87 88 #' Check if an object is a flighttrajectory 89 #' @export 90 is.flighttrajectory <- function(x) inherits(x, "flighttrajectory") 91 92 #' Convert a trajectory to a data.frame 93 #' @method as.data.frame flighttrajectory 94 #' @export 95 as.data.frame.flighttrajectory <- function(x) { 96 class(x) <- NULL 97 return(as.data.frame(x)) 98 }