Csaba "Jester" HALASZ:
Attached patch adds support for multiple FIXes with the same name. Applies to both branches. New functionality is in query_and_offset, which now returns the FIX closest to the passed in location. Updated route manager to take advantage of this. Otherwise, query functions return an unspecified member from the set of identically named FIXes. (This was previously the one occurring last in the database file, but I don't think anybody counted on that.)
This commit is contained in:
parent
3fa32b1fcc
commit
3842fa0edc
3 changed files with 43 additions and 29 deletions
|
@ -332,15 +332,6 @@ int FGRouteMgr::make_waypoint( SGWayPoint **wp, const string& tgt ) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for fix id
|
|
||||||
FGFix f;
|
|
||||||
if ( globals->get_fixlist()->query( target, &f ) ) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (fix) = " << target );
|
|
||||||
*wp = new SGWayPoint( f.get_lon(), f.get_lat(), alt, SGWayPoint::WGS84, target );
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try finding a nav matching the ID
|
|
||||||
double lat, lon;
|
double lat, lon;
|
||||||
// The base lon/lat are determined by the last WP,
|
// The base lon/lat are determined by the last WP,
|
||||||
// or the current pos if the WP list is empty.
|
// or the current pos if the WP list is empty.
|
||||||
|
@ -355,6 +346,18 @@ int FGRouteMgr::make_waypoint( SGWayPoint **wp, const string& tgt ) {
|
||||||
lon = fgGetNode("/position/longitude-deg")->getDoubleValue();
|
lon = fgGetNode("/position/longitude-deg")->getDoubleValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for fix id
|
||||||
|
FGFix f;
|
||||||
|
double heading;
|
||||||
|
double dist;
|
||||||
|
|
||||||
|
if ( globals->get_fixlist()->query_and_offset( target, lon, lat, 0, &f, &heading, &dist ) ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (fix) = " << target );
|
||||||
|
*wp = new SGWayPoint( f.get_lon(), f.get_lat(), alt, SGWayPoint::WGS84, target );
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try finding a nav matching the ID
|
||||||
lat *= SGD_DEGREES_TO_RADIANS;
|
lat *= SGD_DEGREES_TO_RADIANS;
|
||||||
lon *= SGD_DEGREES_TO_RADIANS;
|
lon *= SGD_DEGREES_TO_RADIANS;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
#include "fixlist.hxx"
|
#include "fixlist.hxx"
|
||||||
|
SG_USING_STD(pair);
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -76,7 +77,7 @@ bool FGFixList::init( SGPath path ) {
|
||||||
<< ", lat=" << fix.get_lat()
|
<< ", lat=" << fix.get_lat()
|
||||||
<< ", lon=" << fix.get_lon() << endl; */
|
<< ", lon=" << fix.get_lon() << endl; */
|
||||||
|
|
||||||
fixlist[fix.get_ident()] = fix;
|
fixlist.insert(pair<string, FGFix>(fix.get_ident(), fix));
|
||||||
in >> skipcomment;
|
in >> skipcomment;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -86,9 +87,10 @@ bool FGFixList::init( SGPath path ) {
|
||||||
// query the database for the specified fix, lon and lat are in
|
// query the database for the specified fix, lon and lat are in
|
||||||
// degrees, elev is in meters
|
// degrees, elev is in meters
|
||||||
bool FGFixList::query( const string& ident, FGFix *fix ) {
|
bool FGFixList::query( const string& ident, FGFix *fix ) {
|
||||||
*fix = fixlist[ident];
|
fix_map_const_iterator it = fixlist.find(ident);
|
||||||
if ( ! fix->get_ident().empty() ) {
|
if ( it != fixlist.end() ) {
|
||||||
return true;
|
*fix = it->second;
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -101,18 +103,27 @@ bool FGFixList::query_and_offset( const string& ident, double lon, double lat,
|
||||||
double elev, FGFix *fix, double *heading,
|
double elev, FGFix *fix, double *heading,
|
||||||
double *dist )
|
double *dist )
|
||||||
{
|
{
|
||||||
*fix = fixlist[ident];
|
pair<fix_map_const_iterator, fix_map_const_iterator> range = fixlist.equal_range(ident);
|
||||||
if ( fix->get_ident().empty() ) {
|
|
||||||
return false;
|
if (range.first == range.second) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double min_s = -1.0;
|
||||||
|
for (fix_map_const_iterator current = range.first; current != range.second; ++current) {
|
||||||
|
double az1, az2, s;
|
||||||
|
geo_inverse_wgs_84( elev, lat, lon,
|
||||||
|
current->second.get_lat(), current->second.get_lon(),
|
||||||
|
&az1, &az2, &s );
|
||||||
|
// cout << " dist = " << s << endl;
|
||||||
|
if (min_s < 0 || s < min_s) {
|
||||||
|
*heading = az2;
|
||||||
|
*dist = s;
|
||||||
|
min_s = s;
|
||||||
|
*fix = current->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double az1, az2, s;
|
|
||||||
geo_inverse_wgs_84( elev, lat, lon,
|
|
||||||
fix->get_lat(), fix->get_lon(),
|
|
||||||
&az1, &az2, &s );
|
|
||||||
// cout << " dist = " << s << endl;
|
|
||||||
*heading = az2;
|
|
||||||
*dist = s;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,12 @@
|
||||||
|
|
||||||
#include "fix.hxx"
|
#include "fix.hxx"
|
||||||
|
|
||||||
SG_USING_STD(map);
|
SG_USING_STD(multimap);
|
||||||
SG_USING_STD(vector);
|
SG_USING_STD(vector);
|
||||||
SG_USING_STD(string);
|
SG_USING_STD(string);
|
||||||
|
|
||||||
// TODO - fix names may be globally non-unique. Allow for this.
|
// fix names may be globally non-unique. Allow for this.
|
||||||
typedef map < string, FGFix > fix_map_type;
|
typedef multimap < string, FGFix > fix_map_type;
|
||||||
typedef fix_map_type::iterator fix_map_iterator;
|
typedef fix_map_type::iterator fix_map_iterator;
|
||||||
typedef fix_map_type::const_iterator fix_map_const_iterator;
|
typedef fix_map_type::const_iterator fix_map_const_iterator;
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ public:
|
||||||
|
|
||||||
// query the database for the specified fix
|
// query the database for the specified fix
|
||||||
bool query( const string& ident, FGFix *f );
|
bool query( const string& ident, FGFix *f );
|
||||||
|
|
||||||
// Find fix of requested type with closest exact or following ident
|
// Find fix of requested type with closest exact or following ident
|
||||||
// (by ACSII values) to that supplied (ie. a lower-bound lookup).
|
// (by ACSII values) to that supplied (ie. a lower-bound lookup).
|
||||||
// Supplying true for exact forces only exact matches to be returned (similar to above function)
|
// Supplying true for exact forces only exact matches to be returned (similar to above function)
|
||||||
// Returns NULL if no match found.
|
// Returns NULL if no match found.
|
||||||
|
@ -69,7 +69,7 @@ public:
|
||||||
bool query_and_offset( const string& ident, double lon, double lat,
|
bool query_and_offset( const string& ident, double lon, double lat,
|
||||||
double elev, FGFix *f, double *heading,
|
double elev, FGFix *f, double *heading,
|
||||||
double *dist );
|
double *dist );
|
||||||
|
|
||||||
// Return a pointer to the master fixlist
|
// Return a pointer to the master fixlist
|
||||||
inline const fix_map_type* getFixList() { return(&fixlist); }
|
inline const fix_map_type* getFixList() { return(&fixlist); }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue