commit 152321e10b81ebe610a9ba5e3c8aa907c3fc5938
parent 52ba6c6c844aff0316ffaf68a4a139b9afe6221a
Author: eamoncaddigan <eamon.caddigan@gmail.com>
Date: Tue, 19 Apr 2016 10:14:31 -0400
maxDistanceFromPath() helper.
Diffstat:
4 files changed, 78 insertions(+), 21 deletions(-)
diff --git a/NAMESPACE b/NAMESPACE
@@ -1,3 +1,4 @@
# Generated by roxygen2: do not edit by hand
export(distanceFromPath)
+export(maxDistanceFromPath)
diff --git a/R/maxDistanceFromPath.R b/R/maxDistanceFromPath.R
@@ -0,0 +1,18 @@
+#' Find the maximum distance of a flight trajectory from a flight path.
+#'
+#' @param trajectory A matrix or SpatialPoints object indicating the trajectory
+#' of an aircraft.
+#' @param path A matrix or SpatialPoints object indicating the ordered waypoints
+#' a pre-defined flight path.
+#' @return A named vector indicating the horizontal and vertical distance from
+#' the fligh path at which the aircraft reached the maximum slant (euclidean)
+#' distance.
+#'
+#' @export
+maxDistanceFromPath <- function(trajectory, path) {
+ distanceFromPathVals <- distanceFromPath(trajectory, path)
+ slantDistanceFromPath <- distanceFromPathVals$horizontal^2 +
+ distanceFromPathVals$vertical^2
+ farthestPoint <- which.max(slantDistanceFromPath)
+ return(unlist(distanceFromPathVals[farthestPoint, ]))
+}
diff --git a/man/maxDistanceFromPath.Rd b/man/maxDistanceFromPath.Rd
@@ -0,0 +1,24 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/maxDistanceFromPath.R
+\name{maxDistanceFromPath}
+\alias{maxDistanceFromPath}
+\title{Find the maximum distance of a flight trajectory from a flight path.}
+\usage{
+maxDistanceFromPath(trajectory, path)
+}
+\arguments{
+\item{trajectory}{A matrix or SpatialPoints object indicating the trajectory
+of an aircraft.}
+
+\item{path}{A matrix or SpatialPoints object indicating the ordered waypoints
+a pre-defined flight path.}
+}
+\value{
+A named vector indicating the horizontal and vertical distance from
+ the fligh path at which the aircraft reached the maximum slant (euclidean)
+ distance.
+}
+\description{
+Find the maximum distance of a flight trajectory from a flight path.
+}
+
diff --git a/tests/testthat/test_distanceFromPath.R b/tests/testthat/test_distanceFromPath.R
@@ -1,15 +1,7 @@
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")))
-
+distancePrecision <- 10
numPoints <- 5
fakeTrajectory <- function(waypoints, n = numPoints) {
@@ -23,13 +15,20 @@ fakeTrajectory <- function(waypoints, n = numPoints) {
return(do.call(rbind, trajectoryList))
}
+# 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 <- fakeTrajectory(path)
test_that("non-deviating paths have small distances for all input types", {
- expect_true(all(distanceFromPath(trajectory, path) < 1))
- expect_true(all(distanceFromPath(cbind(trajectory, 3500), cbind(path, 3500)) < 1))
- expect_true(all(distanceFromPath(sp::SpatialPoints(trajectory), sp::SpatialPoints(path)) < 1))
- expect_true(all(distanceFromPath(as.data.frame(trajectory), as.data.frame(path)) < 1))
+ expect_true(all(distanceFromPath(trajectory, path) < distancePrecision))
+ expect_true(all(distanceFromPath(cbind(trajectory, 3500), cbind(path, 3500)) < distancePrecision))
+ expect_true(all(distanceFromPath(sp::SpatialPoints(trajectory), sp::SpatialPoints(path)) < distancePrecision))
+ expect_true(all(distanceFromPath(as.data.frame(trajectory), as.data.frame(path)) < distancePrecision))
})
test_that("small deviations look OK", {
@@ -41,8 +40,11 @@ test_that("small deviations look OK", {
farthestPoint <- which.max(abs(trajectoryDistance))
expect_equal(farthestPoint, numPoints*2+3)
- # left of course
- expect_lt(trajectoryDistance[farthestPoint], 0)
+
+ expect_lt(abs(maxDistanceFromPath(flownTrajectory, path)["horizontal"] - -42015.6),
+ distancePrecision)
+ expect_lt(abs(maxDistanceFromPath(flownTrajectory, flownPath)["horizontal"] - 0),
+ distancePrecision)
})
test_that("simple altitude deviation is handled", {
@@ -54,11 +56,23 @@ test_that("simple altitude deviation is handled", {
seq(5500, 3500,
length.out = nrow(trajectory)-(numPoints+2))))
+ expect_lt(abs(maxDistanceFromPath(flownTrajectory, flownPath1)["vertical"] - 2000),
+ distancePrecision)
+ expect_lt(abs(maxDistanceFromPath(flownTrajectory, flownPath2)["vertical"] - 1000),
+ distancePrecision)
+ expect_lt(abs(maxDistanceFromPath(flownTrajectory, flownPath3)["vertical"] - 0000),
+ distancePrecision)
+})
+
+test_that("reproducing geosphere vignette example", {
+ LA <- c(-118.40, 33.95)
+ NY <- c(-73.78, 40.63)
+ MS <- c(-93.26, 44.98)
+ plannedPath <- rbind(LA, NY)
+ flownTrajectory <- fakeTrajectory(rbind(LA, MS, NY), n = 1000)
+ feetToMeters <- 0.3048
- expect_equal(max(distanceFromPath(flownTrajectory, flownPath1)$vertical),
- 2000.0)
- expect_equal(max(distanceFromPath(flownTrajectory, flownPath2)$vertical),
- 1000.0)
- expect_equal(max(distanceFromPath(flownTrajectory, flownPath3)$vertical),
- 0)
+ expect_lt(abs(maxDistanceFromPath(flownTrajectory, plannedPath)["horizontal"]*feetToMeters -
+ -547448.8),
+ 1)
})