From 8b711a5782d94a0009d49ae390cc0caa2e8348b5 Mon Sep 17 00:00:00 2001 From: curt Date: Fri, 7 Jun 2002 21:03:27 +0000 Subject: [PATCH] James Turner: Modifications to support querying navaid database by station ID (not just frequency.) Some corresponding changes to testnavs.cxx to test new functionality. --- src/Navaids/navlist.cxx | 52 ++++++++++++++++++++++++++++++---------- src/Navaids/navlist.hxx | 21 ++++++++++++---- src/Navaids/testnavs.cxx | 39 +++++++++++++++++++++++++----- 3 files changed, 89 insertions(+), 23 deletions(-) diff --git a/src/Navaids/navlist.cxx b/src/Navaids/navlist.cxx index 005668913..d0fcbe77a 100644 --- a/src/Navaids/navlist.cxx +++ b/src/Navaids/navlist.cxx @@ -1,4 +1,4 @@ -// navaids.cxx -- navaids management class +// navlist.cxx -- navaids management class // // Written by Curtis Olson, started April 2000. // @@ -72,9 +72,9 @@ bool FGNavList::init( SGPath path ) { while ( ! in.eof() ) { #endif - FGNav n; - in >> n; - if ( n.get_type() == '[' ) { + FGNav *n = new FGNav; + in >> (*n); + if ( n->get_type() == '[' ) { break; } @@ -86,7 +86,9 @@ bool FGNavList::init( SGPath path ) { cout << " freq = " << n.get_freq() << endl; cout << " range = " << n.get_range() << endl << endl; */ - navaids[n.get_freq()].push_back(n); + navaids [n->get_freq() ].push_back(n); + ident_navaids[n->get_ident()].push_back(n); + in >> skipcomment; /* if ( n.get_type() != 'N' ) { @@ -116,25 +118,49 @@ bool FGNavList::query( double lon, double lat, double elev, double freq, nav_list_iterator current = stations.begin(); nav_list_iterator last = stations.end(); - // double az1, az2, s; Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) ); + return findNavFromList(aircraft, current, last, n); +} + + +bool FGNavList::findByIdent(const char* ident, double lon, double lat, + FGNav *nav) +{ + nav_list_type stations = ident_navaids[ident]; + + nav_list_iterator current = stations.begin(); + nav_list_iterator last = stations.end(); + + Point3D aircraft = sgGeodToCart( Point3D(lon, lat, 0.0) ); + return findNavFromList(aircraft, current, last, nav); +} + + +bool FGNavList::findNavFromList(const Point3D &aircraft, + nav_list_iterator current, + nav_list_iterator end, FGNav *n) +{ + // double az1, az2, s; + Point3D station; double d; - for ( ; current != last ; ++current ) { + for ( ; current != end ; ++current ) { // cout << "testing " << current->get_ident() << endl; - station = Point3D(current->get_x(), current->get_y(), current->get_z()); + station = Point3D((*current)->get_x(), (*current)->get_y(), + (*current)->get_z()); d = aircraft.distance3Dsquared( station ); // cout << " dist = " << sqrt(d) - // << " range = " << current->get_range() * SG_NM_TO_METER << endl; + // << " range = " << current->get_range() * SG_NM_TO_METER + // << endl; - // match up to twice the published range so we can model + // match up to 2 * range^2 the published range so we can model // reduced signal strength - if ( d < (2 * current->get_range() * SG_NM_TO_METER - * 2 * current->get_range() * SG_NM_TO_METER ) ) { + double twiceRange = 2 * (*current)->get_range() * SG_NM_TO_METER; + if ( d < (twiceRange * twiceRange)) { // cout << "matched = " << current->get_ident() << endl; - *n = *current; + *n = (**current); return true; } } diff --git a/src/Navaids/navlist.hxx b/src/Navaids/navlist.hxx index e46521b73..1d6bea2c6 100644 --- a/src/Navaids/navlist.hxx +++ b/src/Navaids/navlist.hxx @@ -30,27 +30,37 @@ #include #include +#include STL_STRING #include "nav.hxx" SG_USING_STD(map); SG_USING_STD(vector); - +SG_USING_STD(string); class FGNavList { // convenience types - typedef vector < FGNav > nav_list_type; + typedef vector < FGNav* > nav_list_type; typedef nav_list_type::iterator nav_list_iterator; typedef nav_list_type::const_iterator nav_list_const_iterator; - // typedef map < int, nav_list_type, less > nav_map_type; typedef map < int, nav_list_type > nav_map_type; typedef nav_map_type::iterator nav_map_iterator; typedef nav_map_type::const_iterator nav_map_const_iterator; + typedef map < string, nav_list_type > nav_ident_map_type; + nav_map_type navaids; - + nav_ident_map_type ident_navaids; + + // internal helper to pick a Nav item from a nav_list based on + // distance from the aircraft point + bool findNavFromList(const Point3D &aircraft, + nav_list_iterator current, + nav_list_iterator last, + FGNav *n); + public: FGNavList(); @@ -62,6 +72,9 @@ public: // query the database for the specified frequency, lon and lat are // in degrees, elev is in meters bool query( double lon, double lat, double elev, double freq, FGNav *n ); + + // locate closest item in the DB matching the requested ident + bool findByIdent(const char* ident, double lon, double lat, FGNav *nav); }; diff --git a/src/Navaids/testnavs.cxx b/src/Navaids/testnavs.cxx index 920249a3a..a6b839f44 100644 --- a/src/Navaids/testnavs.cxx +++ b/src/Navaids/testnavs.cxx @@ -3,13 +3,19 @@ #include "fixlist.hxx" #include "ilslist.hxx" #include "navlist.hxx" +#include "mkrbeacons.hxx" + +// change this! +const string FG_DATA_DIR("/usr/local/lib/FlightGear"); int main() { double heading, dist; current_navlist = new FGNavList; - SGPath p_nav( "/home/curt/FlightGear/Navaids/default.nav" ); + SGPath p_nav( FG_DATA_DIR + "/Navaids/default.nav" ); + current_navlist->init( p_nav ); + FGNav n; if ( current_navlist->query( -93.2 * SG_DEGREES_TO_RADIANS, 45.14 * SG_DEGREES_TO_RADIANS, @@ -21,8 +27,24 @@ int main() { cout << "not picking up vor. :-(" << endl; } + FGNav dcs; + if (current_navlist->findByIdent("DCS", -3.3 * SG_DEGREES_TO_RADIANS, + 55.9 * SG_DEGREES_TO_RADIANS, &dcs)) { + + cout << "Found DCS by ident" << endl; + if (dcs.get_freq() != 11520) + cout << "Frequency for DCS VOR is wrong (should be 115.20), it's " + << dcs.get_freq() << endl; + } else { + cout << "couldn't locate DCS (Dean-Cross) VOR" << endl; + } + + // we have to init the marker beacon storage before we parse the ILS file + current_beacons = new FGMarkerBeacons; + current_beacons->init(); + current_ilslist = new FGILSList; - SGPath p_ils( "/home/curt/FlightGear/Navaids/default.ils" ); + SGPath p_ils( FG_DATA_DIR + "/Navaids/default.ils" ); current_ilslist->init( p_ils ); FGILS i; if ( current_ilslist->query( -93.1 * SG_DEGREES_TO_RADIANS, @@ -37,16 +59,21 @@ int main() { } current_fixlist = new FGFixList; - SGPath p_fix( "/home/curt/FlightGear/Navaids/default.fix" ); + SGPath p_fix( FG_DATA_DIR + "/Navaids/default.fix" ); current_fixlist->init( p_fix ); FGFix fix; - if ( current_fixlist->query( "SHELL", -82 * SG_DEGREES_TO_RADIANS, - 41 * SG_DEGREES_TO_RADIANS, 3000, + + // attempting to get the position relative to the OTR VOR; heading + // should be 108 degrees, distance 74nm (according to my SimCharts + // v1.5) + if ( current_fixlist->query( "DOGGA", -0.103 * SG_DEGREES_TO_RADIANS, + 53.698 * SG_DEGREES_TO_RADIANS, 3000, &fix, &heading, &dist) ) { cout << "Found a matching fix" << endl; cout << " id = " << fix.get_ident() << endl; - cout << " heading = " << heading << " dist = " << dist << endl; + cout << " heading = " << heading << " dist = " << dist * SG_METER_TO_NM + << endl; } else { cout << "did not find fix. :-(" << endl; }