Skip to content

Commit 3228cbf

Browse files
dirkhhiakat
authored andcommitted
Change the distance helper program
Given a bug in the C++ code that does the spherical calculations, flights crossing the dateline had the distance from their route calculated incorrectly. To work around this, we now pass in an absolute and relative (percentage of route length) distance into the helper app and it returns whether the plane position is within that threshold from the great circle route. Also, based on some real world examples, I ended up increasing the threshold percentage from 5% to 10% (NRT-DEN flight right above PDX). Signed-off-by: Dirk Hohndel <[email protected]>
1 parent 926de2c commit 3228cbf

File tree

2 files changed

+22
-36
lines changed

2 files changed

+22
-36
lines changed

distance/distance.cpp

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,33 @@
66
#include "PolyUtil.hpp"
77

88
void usage() {
9-
std::cout << "Usage:\n\n\tdistance latP lngP latA lngA [latB lngB]\n\n\tprint the sperical distance of point P from point A or of P from the great circle between A and B\n";
9+
std::cout << "Usage:\n\n\tdistance latP lngP latA lngA latB lngB absoluteDelta relativeDelta\n\n\tcheck if a point P is within the given thresholdsa (in meters or percentage of the distance A-B) of the great circle route between A and B.\n";
1010
}
1111

1212
int main(int argc, char** argv) {
13-
if (argc != 5 && argc != 7) {
13+
if (argc != 9) {
1414
usage();
1515
exit(1);
1616
}
17-
std::string pLat = argv[1];
18-
std::string pLng = argv[2];
19-
std::string aLat = argv[3];
20-
std::string aLng = argv[4];
21-
22-
LatLng p = { std::stod(pLat), std::stod(pLng) };
23-
LatLng a = { std::stod(aLat), std::stod(aLng) };
24-
25-
std::string bLat, bLng;
26-
LatLng b = { 0.0, 0.0 };
17+
LatLng p = { std::stod(argv[1]), std::stod(argv[2]) };
18+
LatLng a = { std::stod(argv[3]), std::stod(argv[4]) };
19+
LatLng b = { std::stod(argv[5]), std::stod(argv[6]) };
20+
double distThreshold = std::stod(argv[7]) * 1852;
21+
double distPercentage = std::stod(argv[8]);
2722

2823
double distPA = SphericalUtil::computeDistanceBetween(p, a);
24+
double distPB = SphericalUtil::computeDistanceBetween(p, b);
25+
double distAB = SphericalUtil::computeDistanceBetween(a, b);
2926

30-
std::cout << "{\"distPA\": " << distPA / 1852.0;
31-
32-
if (argc ==7) {
33-
std::string bLat = argv[5];
34-
std::string bLng = argv[6];
35-
LatLng b = { std::stod(bLat), std::stod(bLng) };
27+
// calculate if the point is within the given tolerance of the route
28+
std::vector<LatLng> route = { a, b};
29+
double threshold = std::max(distThreshold, distPercentage * distAB / 100.0);
30+
bool withinThreshold = PolyUtil::isLocationOnPath(p, route, threshold);
3631

37-
double distPB = SphericalUtil::computeDistanceBetween(p, b);
38-
std::cout << ",\"distPB\": " << distPB / 1852.0;
39-
40-
double distAB = SphericalUtil::computeDistanceBetween(a, b);
41-
std::cout << ",\"distAB\": " << distAB / 1852.0;
42-
43-
double distPAB = PolyUtil::distanceToLine(p, a, b);
44-
std::cout << ",\"distPAB\": " << distPAB / 1852.0;
45-
}
46-
std::cout << "}";
32+
std::cout << "{\"distPA\": " << distPA / 1852.0;
33+
std::cout << ",\"distPB\": " << distPB / 1852.0;
34+
std::cout << ",\"distAB\": " << distAB / 1852.0;
35+
std::cout << ",\"withinThreshold\": " << withinThreshold << "}";
4736

4837
return 0;
4938
}

src/adsb_api/utils/plausible.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def plausible(
1010
airportBLat: str,
1111
airportBLon: str,
1212
):
13+
# check if the position is within 50nm or 10% of the total distance of the great circle route
1314
distanceResult = subprocess.run(
1415
[
1516
"/usr/local/bin/distance",
@@ -19,15 +20,11 @@ def plausible(
1920
airportALon,
2021
airportBLat,
2122
airportBLon,
23+
"50",
24+
"10"
2225
],
2326
capture_output=True,
2427
)
2528
distance = orjson.loads(distanceResult.stdout)
26-
# lame assumption that the plane should be within
27-
# 50nm or 5% or route distance of the great circle route
28-
# no concern for direction, no handling of multi segment routes
29-
threshold = 50
30-
fivePercent = distance["distAB"] / 20
31-
if fivePercent > threshold:
32-
threshold = fivePercent
33-
return distance["distPAB"] < threshold, distance["distAB"]
29+
return distance['withinThreshold'], distance['distAB']
30+

0 commit comments

Comments
 (0)