commit 7db9165f9f86a4b184ecf95788e1f340aab157d5
parent 207bc493c6e269dad55a1dd108c290d0bb96c0a1
Author: eamoncaddigan <eamon.caddigan@gmail.com>
Date: Fri, 16 Sep 2016 15:50:28 -0400
Looks good for a new, flightpathr::createTrajectory() world
Diffstat:
12 files changed, 7 insertions(+), 243 deletions(-)
diff --git a/NAMESPACE b/NAMESPACE
@@ -2,9 +2,6 @@
export(calculateSLoWC)
export(calculateTCPA)
-export(createTrajectory)
export(identifyLoWC)
export(identifyNMAC)
-export(interpolateTrajectory)
export(is.flattrajectory)
-export(is.flighttrajectory)
diff --git a/R/checkTrajectories.R b/R/checkTrajectories.R
@@ -10,8 +10,8 @@
#' of samples and origin.
checkTrajectories <- function(trajectory1, trajectory2) {
# Two flight trajectories
- if (is.flighttrajectory(trajectory1)) {
- if (!is.flighttrajectory(trajectory2)) {
+ if (flightpathr::is.flighttrajectory(trajectory1)) {
+ if (!flightpathr::is.flighttrajectory(trajectory2)) {
stop("'trajectory1' is a flighttrajectory; 'trajectory2' must match this type")
}
if (!isTRUE(all.equal(trajectory1$timestamp, trajectory2$timestamp))) {
diff --git a/R/createTrajectory.R b/R/createTrajectory.R
@@ -1,90 +0,0 @@
-#' Create a flighttrajectory object from the flight info.
-#'
-#' @param longitude Required; numeric vector giving aircraft longitude in
-#' degrees.
-#' @param latitude Required; numeric vector giving aircraft latitude in degrees.
-#' @param altitude Optional; numeric vector giving aircraft altitude (AGL) in
-#' feet. If missing, it will be set to 0.
-#' @param timestamp Optional; numeric vector giving the time of each observation
-#' in seconds. If missing, the observation period is assumed to be 1 s.
-#' @param bearing Optional; numeric vector giving the current bearing in
-#' degrees. If missing, it is estimated using pairs of successive lon/lat
-#' observations.
-#' @param groundspeed Optional; numeric vector giving the current ground speed
-#' of the aircraft in knots. If missing, it is estimated using pairs of
-#' successive lon/lat observations.
-#' @return A flighttrajectory object encapsulating these parameters (with
-#' default values substituded as necessary).
-#'
-#' @details \code{longitude} and \code{latitude} must be the same length.
-#' \code{timestamp}, \code{bearing}, and \code{groundspeed}, if present, must
-#' also match this length. \code{altitude} must also have a length equal to
-#' these parameters or be scalar.
-#'
-#' @export
-createTrajectory <- function(longitude, latitude, altitude = 0, timestamp = NULL,
- bearing = NULL, groundspeed = NULL) {
- if (!is.numeric(longitude)) stop("\"longitude\" must be a numeric vector")
- nCoord <- length(longitude)
-
- # Helper function to throw an error if the length of a vector is incorrect.
- checkLength <- function(x) {
- if (!is.numeric(x)) {
- stop("\"", deparse(substitute(x)), "\" must be a numeric vector")
- } else if (length(x) != nCoord) {
- stop("Vector \"", deparse(substitute(x)), "\" has length = ", length(x),
- ", expected length = ", nCoord)
- }
- return(TRUE)
- }
-
- checkLength(latitude)
- coords <- cbind(longitude, latitude)
-
- if (length(altitude) == 1) {
- altitude <- rep(altitude, nCoord)
- } else {
- checkLength(altitude)
- }
-
- if (is.null(timestamp)) {
- timestamp <- seq(1, nCoord)
- } else {
- checkLength(timestamp)
- }
-
- # Use flightpathr to calculate bearing between successive points if not
- # specified.
- if (is.null(bearing)) {
- bearing <- flightpathr::coordsToBearing(cbind(coords, altitude))
- bearing[nCoord] <- bearing[nCoord-1]
- } else {
- checkLength(bearing)
- }
-
- # Use geosphere to find the distance between points and use the timestamps to
- # calculate groundspeed if not specified.
- if (is.null(groundspeed)) {
- distNM <- geosphere::distCosine(coords[1:(nCoord-1), ],
- coords[2:nCoord, ],
- r = 3444)
- groundspeed <- distNM / diff(timestamp) * 3600
- groundspeed <- c(groundspeed, groundspeed[nCoord-1])
- } else{
- checkLength(groundspeed)
- }
-
- flighttrajectory <- list(longitude = longitude,
- latitude = latitude,
- altitude = altitude,
- timestamp = timestamp,
- bearing = bearing,
- groundspeed = groundspeed)
- class(flighttrajectory) <- "flighttrajectory"
-
- return(flighttrajectory)
-}
-
-#' Check if an object is a flighttrajectory
-#' @export
-is.flighttrajectory <- function(x) inherits(x, "flighttrajectory")
diff --git a/R/identifyViolations.R b/R/identifyViolations.R
@@ -13,7 +13,8 @@
#'
#' @export
identifyNMAC <- function(trajectory1, trajectory2) {
- if (!is.flighttrajectory(trajectory1) || !is.flighttrajectory(trajectory2)) {
+ if (!flightpathr::is.flighttrajectory(trajectory1) ||
+ !flightpathr::is.flighttrajectory(trajectory2)) {
stop("Both arguments must be instances of flighttrajectory")
}
if (!isTRUE(all.equal(trajectory1$timestamp, trajectory2$timestamp))) {
diff --git a/R/interpolateTrajectory.R b/R/interpolateTrajectory.R
@@ -1,31 +0,0 @@
-#' Interpolate a trajectory (in time)
-#'
-#' @param trajectory A \code{flighttrajectory} object.
-#' @param timestamp The new timestamp along which the data should be
-#' interpolated.
-#' @return A new \code{flighttrajectory} with the given \code{timestamp}
-#'
-#' @details This just performs linear interpolation for all of the values in the
-#' trajectory. A better approach would make use of the bearing and velocity
-#' information to smoothly interpolate the coordinates.
-#'
-#' @export
-interpolateTrajectory <- function(trajectory, timestamp) {
- # We'll interpolate all of the features (except the timestamp, which is
- # specified).
- trajectoryFeatures <- names(trajectory)
- trajectoryFeatures <- trajectoryFeatures[trajectoryFeatures != "timestamp"]
-
- # Create a new trajectory with
- newTrajectory <- list()
- for (trajectoryFeature in trajectoryFeatures) {
- newTrajectory[[trajectoryFeature]] <- approx(x = trajectory$timestamp,
- y = trajectory[[trajectoryFeature]],
- xout = timestamp,
- method = "linear",
- rule = 2)$y
- }
- newTrajectory[["timestamp"]] <- timestamp
-
- return(do.call(createTrajectory, newTrajectory))
-}
diff --git a/R/trajectoryToXYZ.R b/R/trajectoryToXYZ.R
@@ -5,7 +5,7 @@
#' conversion.
#' @return A flattrajectory object.
trajectoryToXYZ <- function(trajectory, origin) {
- if (!is.flighttrajectory(trajectory)) {
+ if (!flightpathr::is.flighttrajectory(trajectory)) {
stop("'trajectory' must be an instance of flighttrajectory")
}
if (!is.numeric(origin) || length(origin) != 2) {
diff --git a/man/createTrajectory.Rd b/man/createTrajectory.Rd
@@ -1,43 +0,0 @@
-% Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/createTrajectory.R
-\name{createTrajectory}
-\alias{createTrajectory}
-\title{Create a flighttrajectory object from the flight info.}
-\usage{
-createTrajectory(longitude, latitude, altitude = 0, timestamp = NULL,
- bearing = NULL, groundspeed = NULL)
-}
-\arguments{
-\item{longitude}{Required; numeric vector giving aircraft longitude in
-degrees.}
-
-\item{latitude}{Required; numeric vector giving aircraft latitude in degrees.}
-
-\item{altitude}{Optional; numeric vector giving aircraft altitude (AGL) in
-feet. If missing, it will be set to 0.}
-
-\item{timestamp}{Optional; numeric vector giving the time of each observation
-in seconds. If missing, the observation period is assumed to be 1 s.}
-
-\item{bearing}{Optional; numeric vector giving the current bearing in
-degrees. If missing, it is estimated using pairs of successive lon/lat
-observations.}
-
-\item{groundspeed}{Optional; numeric vector giving the current ground speed
-of the aircraft in knots. If missing, it is estimated using pairs of
-successive lon/lat observations.}
-}
-\value{
-A flighttrajectory object encapsulating these parameters (with
- default values substituded as necessary).
-}
-\description{
-Create a flighttrajectory object from the flight info.
-}
-\details{
-\code{longitude} and \code{latitude} must be the same length.
- \code{timestamp}, \code{bearing}, and \code{groundspeed}, if present, must
- also match this length. \code{altitude} must also have a length equal to
- these parameters or be scalar.
-}
-
diff --git a/man/interpolateTrajectory.Rd b/man/interpolateTrajectory.Rd
@@ -1,26 +0,0 @@
-% Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/interpolateTrajectory.R
-\name{interpolateTrajectory}
-\alias{interpolateTrajectory}
-\title{Interpolate a trajectory (in time)}
-\usage{
-interpolateTrajectory(trajectory, timestamp)
-}
-\arguments{
-\item{trajectory}{A \code{flighttrajectory} object.}
-
-\item{timestamp}{The new timestamp along which the data should be
-interpolated.}
-}
-\value{
-A new \code{flighttrajectory} with the given \code{timestamp}
-}
-\description{
-Interpolate a trajectory (in time)
-}
-\details{
-This just performs linear interpolation for all of the values in the
- trajectory. A better approach would make use of the bearing and velocity
- information to smoothly interpolate the coordinates.
-}
-
diff --git a/man/is.flighttrajectory.Rd b/man/is.flighttrajectory.Rd
@@ -1,12 +0,0 @@
-% Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/createTrajectory.R
-\name{is.flighttrajectory}
-\alias{is.flighttrajectory}
-\title{Check if an object is a flighttrajectory}
-\usage{
-is.flighttrajectory(x)
-}
-\description{
-Check if an object is a flighttrajectory
-}
-
diff --git a/tests/testthat/test_calculateSLoWC.R b/tests/testthat/test_calculateSLoWC.R
@@ -2,6 +2,7 @@ library(flightconflicts)
context("calculateSLoWC")
library(geosphere)
+library(flightpathr)
# I'll attempt to replicate the values in Appendix A of SC-228.
diff --git a/tests/testthat/test_calculateTCPA.R b/tests/testthat/test_calculateTCPA.R
@@ -2,6 +2,7 @@ library(flightconflicts)
context("calculateTCPA")
library(geosphere)
+library(flightpathr)
kacy <- c(-74.5771667, 39.4575833)
kphl <- c(-75.2408658, 39.8722494)
diff --git a/tests/testthat/test_interpolateTrajectory.R b/tests/testthat/test_interpolateTrajectory.R
@@ -1,34 +0,0 @@
-library(flightconflicts)
-context("interpolateTrajectory")
-
-library(geosphere)
-
-kacy <- c(-74.5771667, 39.4575833)
-k17n <- c(-75.0330031, 39.7054758)
-
-# Two identical trajectories with different sampling rates
-coords1 <- gcIntermediate(kacy, k17n, n = 61)
-trajectory1 <-createTrajectory(coords1[, 1], coords1[, 2], altitude = 3500,
- timestamp = seq(0, 800, length.out = 61))
-coords2 <- gcIntermediate(kacy, k17n, n = 229)
-trajectory2 <-createTrajectory(coords2[, 1], coords2[, 2], altitude = 3500,
- timestamp = seq(0, 800, length.out = 229))
-
-test_that("Interpolated trajectory is close to correct", {
- trajectoryInterpolated <- interpolateTrajectory(trajectory1,
- trajectory2$timestamp)
-
- for (tf in names(trajectoryInterpolated)) {
- expect_equal(trajectoryInterpolated[[tf]], trajectory2[[tf]], tolerance = 1)
- }
-})
-
-test_that("Correctly handling times outside original range", {
- trajectoryInterpolated <- interpolateTrajectory(trajectory1,
- c(-100, 0, 800, 900))
-
- for (tf in names(trajectoryInterpolated)[names(trajectoryInterpolated) != "timestamp"]) {
- expect_equal(trajectoryInterpolated[[tf]][1], trajectoryInterpolated[[tf]][2])
- expect_equal(trajectoryInterpolated[[tf]][3], trajectoryInterpolated[[tf]][4])
- }
-})