// $Id$
+#include <simgear/compiler.h>
+
+#include STL_STRING
+
#include <simgear/debug/logstream.hxx>
+#include <Airports/runways.hxx>
#include <Main/globals.hxx>
#include "navrecord.hxx"
-
#include "navdb.hxx"
+SG_USING_STD( string );
+
// load and initialize the navigational databases
bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist,
return true;
}
+
+
+// Given a localizer record and it's corresponding runway record,
+// adjust the localizer position so it is in perfect alignment with
+// the runway.
+static void update_loc_position( FGNavRecord *loc, FGRunway *rwy ) {
+
+ double hdg = rwy->heading;
+ hdg += 180.0;
+ if ( hdg > 360.0 ) {
+ hdg -= 360.0;
+ }
+
+ // calculate runway threshold point
+ double thresh_lat, thresh_lon, return_az;
+ geo_direct_wgs_84 ( 0.0, rwy->lat, rwy->lon, hdg,
+ rwy->length/2.0 * SG_FEET_TO_METER,
+ &thresh_lat, &thresh_lon, &return_az );
+ // cout << "Threshold = " << thresh_lat << "," << thresh_lon << endl;
+
+ // calculate distance from threshold to localizer
+ double az1, az2, dist_m;
+ geo_inverse_wgs_84( 0.0, loc->get_lat(), loc->get_lon(),
+ thresh_lat, thresh_lon,
+ &az1, &az2, &dist_m );
+ // cout << "Distance = " << dist_m << endl;
+
+ // back project that distance along the runway center line
+ double nloc_lat, nloc_lon;
+ geo_direct_wgs_84 ( 0.0, thresh_lat, thresh_lon, hdg + 180.0,
+ dist_m, &nloc_lat, &nloc_lon, &return_az );
+ // printf("New localizer = %.6f %.6f\n", nloc_lat, nloc_lon );
+
+ // sanity check, how far have we moved the localizer?
+ geo_inverse_wgs_84( 0.0, loc->get_lat(), loc->get_lon(),
+ nloc_lat, nloc_lon,
+ &az1, &az2, &dist_m );
+ // cout << "Distance moved = " << dist_m << endl;
+
+ loc->set_lat( nloc_lat );
+ loc->set_lon( nloc_lon );
+ loc->set_multiuse( rwy->heading );
+
+ // cout << "orig heading = " << loc->get_multiuse() << endl;
+ // cout << "new heading = " << rwy->heading << endl;
+}
+
+
+// This routines traverses the localizer list and attempts to match
+// each entry with it's corresponding runway. When it is successful,
+// it then "moves" the localizer and updates it's heading so it
+// *perfectly* aligns with the runway, but is still the same distance
+// from the runway threshold.
+void fgNavDBAlignLOCwithRunway( FGRunwayList *runways, FGNavList *loclist ) {
+ nav_map_type navmap = loclist->get_navaids();
+
+ nav_map_iterator freq = navmap.begin();
+ while ( freq != navmap.end() ) {
+ nav_list_type locs = freq->second;
+ nav_list_iterator loc = locs.begin();
+ while ( loc != locs.end() ) {
+ string name = (*loc)->get_name();
+ string::size_type pos1 = name.find(" ");
+ string id = name.substr(0, pos1);
+ name = name.substr(pos1+1);
+ string::size_type pos2 = name.find(" ");
+ string rwy = name.substr(0, pos2);
+
+ FGRunway r;
+ if ( runways->search(id, rwy, &r) ) {
+ update_loc_position( (*loc), &r );
+ }
+ ++loc;
+ }
+ ++freq;
+ }
+}
inline int get_type() const { return type; }
inline double get_lon() const { return lon; }
+ inline void set_lon( double l ) { lon = l; }
inline double get_lat() const { return lat; }
+ inline void set_lat( double l ) { lat = l; }
inline double get_elev_ft() const { return elev_ft; }
inline double get_x() const { return x; }
inline double get_y() const { return y; }
inline int get_freq() const { return freq; }
inline int get_range() const { return range; }
inline double get_multiuse() const { return multiuse; }
+ inline void set_multiuse( double m ) { multiuse = m; }
inline const char *get_ident() { return ident.c_str(); }
inline string get_name() { return name; }
inline bool get_serviceable() { return serviceable; }
n.freq *= 100;
}
- // Remove the space before the name
- if ( n.name.substr(0,1) == " " ) {
+ // Remove any leading spaces before the name
+ while ( n.name.substr(0,1) == " " ) {
n.name = n.name.erase(0,1);
}