flightpathr

Tools to analyze aircraft and flight path data.
git clone https://git.eamoncaddigan.net/flightpathr.git
Log | Files | Refs | README | LICENSE

commit d11aebdb6b1aa186d7e4e5c5c275389d788815c3
parent 654b56bdc2c306b81f1a9689063fcb2c9ef5477f
Author: eamoncaddigan <eamon.caddigan@gmail.com>
Date:   Mon, 18 Apr 2016 13:52:05 -0400

Working (and passing tests) for the simplest case.

Diffstat:
MR/distanceFromPath.R | 24+++++++++++++-----------
Atests/testthat/test_distanceFromPath.R | 17+++++++++++++++++
2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/R/distanceFromPath.R b/R/distanceFromPath.R @@ -18,8 +18,10 @@ distanceFromPath <- function(trajectory, path) { numLegs <- nrow(pathCoords)-1 # Given n points and m legs, store horizontal and vertical distance in an - # n x m x 2 array - distanceToLeg <- array(NA, dim = c(nrow(trajectory), 2, numLegs)) + # n x m arrays + hDistanceToLeg <- array(NA, dim = c(nrow(trajectoryCoords), numLegs)) + vDistanceToLeg <- array(NA, dim = c(nrow(trajectoryCoords), numLegs)) + # And the squared "slant range" (euclidean distance) in an n x m array slantToLeg <- array(NA, dim = c(nrow(trajectoryCoords), numLegs)) @@ -27,21 +29,21 @@ distanceFromPath <- function(trajectory, path) { # For each pair of adjascent waypoints, calculate the horizontal distance # from the great circle defined by the pair and all points in the # trajectory. - distanceToLeg[, i, 1] <- geosphere::dist2gc(path[i, c(1,2)], - path[i+1, c(1,2)], - trajectory[, c(1,2)], - r = 2.0904e+7) + hDistanceToLeg[, legIdx] <- geosphere::dist2gc(pathCoords[legIdx, c(1,2)], + pathCoords[legIdx+1, c(1,2)], + trajectoryCoords[, c(1,2)], + r = 2.0904e+7) # If the waypoints are at the same altitude, just calculate the deviation # from this altitude. Easy. # XXX - Not actually handling the case where they don't match. - if (!isTRUE(all.equal(altitudes(path[i]), altitudes(path[i+1])))) { + if (!isTRUE(all.equal(pathCoords[legIdx, 3], pathCoords[legIdx+1, 3]))) { warning("Pretending that waypoint altitudes match when they don't") } - distanceToLeg[, i, 2] <- trajectory[, 3] - path[i, 3] + vDistanceToLeg[, legIdx] <- trajectoryCoords[, 3] - pathCoords[legIdx, 3] # Squared euclidean distance - slantToLeg[, i] <- distanceToLeg[, i, 1]^2 + distanceToLeg[, i, 2]^2 + slantToLeg[, legIdx] <- hDistanceToLeg[, legIdx]^2 + vDistanceToLeg[, legIdx]^2 } # Figure out which leg is closer to each point in the trajectory. @@ -51,7 +53,7 @@ distanceFromPath <- function(trajectory, path) { # Return the horizontal and vertical distance to the flight path (distance to # the closest leg) as a data.frame. - distanceToPath <- as.data.frame(drop(distanceToLeg[, closestLeg, ])) - colnames(distanceToPath) <- c("horizontal", "vertical") + distanceToPath <- data.frame(horizontal = hDistanceToLeg[cbind(1:nrow(trajectoryCoords), closestLeg)], + vertical = vDistanceToLeg[cbind(1:nrow(trajectoryCoords), closestLeg)]) return(distanceToPath) } diff --git a/tests/testthat/test_distanceFromPath.R b/tests/testthat/test_distanceFromPath.R @@ -0,0 +1,17 @@ +library(flightpathr) +context("distanceFromPath") + +# Flying from 17N to KACY with a stop over N81. Flying VFR at 3500 msl + +path <- matrix(c(-75.0268, 39.7065, + -74.7577, 39.6675, + -74.5722, 39.4513), + nrow = 3, byrow = TRUE, + dimnames = list(c("17N", "N81", "KACY"), + c("lon", "lat"))) +trajectory <- rbind(geosphere::gcIntermediate(path[1, ], path[2, ], 5), + geosphere::gcIntermediate(path[2, ], path[3, ], 6)) + +test_that("non-deviating paths have small distances", { + expect_true(all(distanceFromPath(trajectory, path) < 1)) +})