From 222446df29724aa496da85ea334788f59276b922 Mon Sep 17 00:00:00 2001 From: curt Date: Wed, 22 Dec 2004 23:57:07 +0000 Subject: [PATCH] Replace the data/Airports/basic.dat.gz and data/Airports/runways.dat.gz with a single apt.dat.gz file which is in the native X-Plane format. To do this I wrote a front end loader than builds the airport and runway list. Some of the changes I needed to make had a cascading effect, so there are minor naming changes scattered throughout the code. --- src/AIModel/AIFlightPlan.cxx | 76 ++++----- src/ATC/AILocalTraffic.cxx | 10 +- src/ATC/AIMgr.cxx | 2 +- src/ATC/ATCDialog.cxx | 2 +- src/ATC/ATCmgr.cxx | 12 +- src/ATC/ATCutils.cxx | 18 +- src/ATC/approach.cxx | 10 +- src/ATC/commlist.cxx | 2 +- src/ATC/ground.cxx | 16 +- src/ATC/tower.cxx | 22 +-- src/Airports/Makefile.am | 1 + src/Airports/apt_loader.cxx | 245 +++++++++++++++++++++++++++ src/Airports/apt_loader.hxx | 50 ++++++ src/Airports/runways.cxx | 110 ++++++------ src/Airports/runways.hxx | 54 +++--- src/Airports/simple.cxx | 105 +++--------- src/Airports/simple.hxx | 27 ++- src/Autopilot/auto_gui.cxx | 2 +- src/Cockpit/hud_rwy.cxx | 22 +-- src/Environment/environment_ctrl.cxx | 24 +-- src/GUI/AirportList.cxx | 8 +- src/Instrumentation/gps.cxx | 26 +-- src/Main/fg_init.cxx | 54 +++--- src/Navaids/navdb.cxx | 16 +- src/Traffic/SchedFlight.cxx | 8 +- src/Traffic/Schedule.cxx | 22 +-- 26 files changed, 603 insertions(+), 341 deletions(-) create mode 100644 src/Airports/apt_loader.cxx create mode 100644 src/Airports/apt_loader.hxx diff --git a/src/AIModel/AIFlightPlan.cxx b/src/AIModel/AIFlightPlan.cxx index 6369c3cd3..7ba7747f4 100644 --- a/src/AIModel/AIFlightPlan.cxx +++ b/src/AIModel/AIFlightPlan.cxx @@ -376,14 +376,14 @@ double wind_speed; //cerr << "Cruise Alt << " << alt << endl; // Temporary code to add some small random variation to aircraft parking positions; direction = (rand() % 360); -geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, +geo_direct_wgs_84 ( 0, dep->_latitude, dep->_longitude, direction, 100, &lat2, &lon2, &az2 ); waypoint *wpt = new waypoint; - wpt->name = dep->id; //wpt_node->getStringValue("name", "END"); + wpt->name = dep->_id; //wpt_node->getStringValue("name", "END"); wpt->latitude = lat2; wpt->longitude = lon2; - wpt->altitude = dep->elevation + 19; // probably need to add some model height to it + wpt->altitude = dep->_elevation + 19; // probably need to add some model height to it wpt->speed = 15; wpt->crossat = -10000; wpt->gear_down = true; @@ -395,7 +395,7 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, // Get the current active runway, based on code from David Luff FGEnvironment stationweather = ((FGEnvironmentMgr *) globals->get_subsystem("environment")) - ->getEnvironment(dep->latitude, dep->longitude, dep->elevation); + ->getEnvironment(dep->_latitude, dep->_longitude, dep->_elevation); wind_speed = stationweather.get_wind_speed_kt(); wind_heading = stationweather.get_wind_from_heading_deg(); @@ -404,28 +404,28 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, // which is consistent with Flightgear's initial setup. } - string rwy_no = globals->get_runways()->search(dep->id, int(wind_heading)); - if (!(globals->get_runways()->search(dep->id, (int) wind_heading, &rwy ))) + string rwy_no = globals->get_runways()->search(dep->_id, int(wind_heading)); + if (!(globals->get_runways()->search(dep->_id, (int) wind_heading, &rwy ))) { - cout << "Failed to find runway for " << dep->id << endl; + cout << "Failed to find runway for " << dep->_id << endl; // Hmm, how do we handle a potential error like this? exit(1); } - double heading = rwy.heading; + double heading = rwy._heading; double azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth, - rwy.length * SG_FEET_TO_METER * 0.5 - 5.0, + geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, + rwy._length * SG_FEET_TO_METER * 0.5 - 5.0, &lat2, &lon2, &az2 ); //Add the runway startpoint; wpt = new waypoint; - wpt->name = rwy.id; + wpt->name = rwy._id; wpt->latitude = lat2; wpt->longitude = lon2; - wpt->altitude = dep->elevation + 19; + wpt->altitude = dep->_elevation + 19; wpt->speed = 15; wpt->crossat = -10000; wpt->gear_down = true; @@ -437,14 +437,14 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, //Next: The point on the runway where we begin to accelerate to take-off speed //100 meters down the runway seems to work. Shorter distances cause problems with // the turn with larger aircraft - geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth, - rwy.length * SG_FEET_TO_METER * 0.5 - 105.0, + geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, + rwy._length * SG_FEET_TO_METER * 0.5 - 105.0, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "accel"; wpt->latitude = lat2; wpt->longitude = lon2; - wpt->altitude = dep->elevation + 19; + wpt->altitude = dep->_elevation + 19; wpt->speed = speed; wpt->crossat = -10000; wpt->gear_down = true; @@ -496,7 +496,7 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, //Beginning of Decent stationweather = ((FGEnvironmentMgr *)globals->get_subsystem("environment")) - ->getEnvironment(arr->latitude, arr->longitude, arr->elevation); + ->getEnvironment(arr->_latitude, arr->_longitude, arr->_elevation); wind_speed = stationweather.get_wind_speed_kt(); wind_heading = stationweather.get_wind_from_heading_deg(); @@ -506,23 +506,23 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, // which is consistent with Flightgear's initial setup. } - rwy_no = globals->get_runways()->search(arr->id, int(wind_heading)); - //cout << "Using runway # " << rwy_no << " for departure at " << dep->id << endl; + rwy_no = globals->get_runways()->search(arr->_id, int(wind_heading)); + //cout << "Using runway # " << rwy_no << " for departure at " << dep->_id << endl; - if (!(globals->get_runways()->search(arr->id, (int) wind_heading, &rwy ))) + if (!(globals->get_runways()->search(arr->_id, (int) wind_heading, &rwy ))) { - cout << "Failed to find runway for " << arr->id << endl; + cout << "Failed to find runway for " << arr->_id << endl; // Hmm, how do we handle a potential error like this? exit(1); } //cerr << "Done" << endl; - heading = rwy.heading; + heading = rwy._heading; azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth, + geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 100000, &lat2, &lon2, &az2 ); wpt = new waypoint; @@ -539,14 +539,14 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, waypoints.push_back(wpt); // Ten thousand ft. Slowing down to 240 kts - geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth, + geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 20*SG_NM_TO_METER, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "Dec 10000ft"; //wpt_node->getStringValue("name", "END"); wpt->latitude = lat2; wpt->longitude = lon2; - wpt->altitude = arr->elevation + 19; + wpt->altitude = arr->_elevation + 19; wpt->speed = 240; wpt->crossat = 10000; wpt->gear_down = false; @@ -556,14 +556,14 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, waypoints.push_back(wpt); // Three thousand ft. Slowing down to 160 kts - geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth, + geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 8*SG_NM_TO_METER, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "DEC 3000ft"; //wpt_node->getStringValue("name", "END"); wpt->latitude = lat2; wpt->longitude = lon2; - wpt->altitude = arr->elevation + 19; + wpt->altitude = arr->_elevation + 19; wpt->speed = 160; wpt->crossat = 3000; wpt->gear_down = true; @@ -572,16 +572,16 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, wpt->on_ground = false; waypoints.push_back(wpt); //Runway Threshold - geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth, - rwy.length*0.45 * SG_FEET_TO_METER, + geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, + rwy._length*0.45 * SG_FEET_TO_METER, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END"); wpt->latitude = lat2; wpt->longitude = lon2; - wpt->altitude = arr->elevation + 19; + wpt->altitude = arr->_elevation + 19; wpt->speed = 15; - wpt->crossat = arr->elevation + 19; + wpt->crossat = arr->_elevation + 19; wpt->gear_down = true; wpt->flaps_down= true; wpt->finished = false; @@ -589,14 +589,14 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, waypoints.push_back(wpt); //Full stop at the runway centerpoint - geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth, - rwy.length*0.45, + geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, + rwy._length*0.45, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "Center"; //wpt_node->getStringValue("name", "END"); - wpt->latitude = rwy.lat; - wpt->longitude = rwy.lon; - wpt->altitude = arr->elevation + 19; + wpt->latitude = rwy._lat; + wpt->longitude = rwy._lon; + wpt->altitude = arr->_elevation + 19; wpt->speed = 15; wpt->crossat = -10000; wpt->gear_down = true; @@ -606,16 +606,16 @@ geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, waypoints.push_back(wpt); direction = (rand() % 360); -geo_direct_wgs_84 ( 0, arr->latitude, arr->longitude, direction, +geo_direct_wgs_84 ( 0, arr->_latitude, arr->_longitude, direction, 100, &lat2, &lon2, &az2 ); // Add the final destination waypoint wpt = new waypoint; - wpt->name = arr->id; //wpt_node->getStringValue("name", "END"); + wpt->name = arr->_id; //wpt_node->getStringValue("name", "END"); wpt->latitude = lat2; wpt->longitude = lon2; - wpt->altitude = arr->elevation+19; + wpt->altitude = arr->_elevation+19; wpt->speed = 15; wpt->crossat = -10000; wpt->gear_down = true; diff --git a/src/ATC/AILocalTraffic.cxx b/src/ATC/AILocalTraffic.cxx index 2988f2e06..c96a4661f 100644 --- a/src/ATC/AILocalTraffic.cxx +++ b/src/ATC/AILocalTraffic.cxx @@ -179,20 +179,20 @@ void FGAILocalTraffic::GetRwyDetails(string id) { FGRunway runway; bool rwyGood = globals->get_runways()->search(id, rwy.rwyID, &runway); if(rwyGood) { - double hdg = runway.heading; + double hdg = runway._heading; double other_way = hdg - 180.0; while(other_way <= 0.0) { other_way += 360.0; } // move to the +l end/center of the runway - //cout << "Runway center is at " << runway.lon << ", " << runway.lat << '\n'; - Point3D origin = Point3D(runway.lon, runway.lat, aptElev); + //cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n'; + Point3D origin = Point3D(runway._lon, runway._lat, aptElev); Point3D ref = origin; double tshlon, tshlat, tshr; double tolon, tolat, tor; - rwy.length = runway.length * SG_FEET_TO_METER; - rwy.width = runway.width * SG_FEET_TO_METER; + rwy.length = runway._length * SG_FEET_TO_METER; + rwy.width = runway._width * SG_FEET_TO_METER; geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), other_way, rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr ); geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), hdg, diff --git a/src/ATC/AIMgr.cxx b/src/ATC/AIMgr.cxx index 5a9d3f6d3..58e988679 100644 --- a/src/ATC/AIMgr.cxx +++ b/src/ATC/AIMgr.cxx @@ -113,7 +113,7 @@ void FGAIMgr::init() { f_ident = file.substr(0, pos); FGAirport a; if(dclFindAirportID(f_ident, &a)) { - SGBucket sgb(a.longitude, a.latitude); + SGBucket sgb(a._longitude, a._latitude); int idx = sgb.gen_index(); if(facilities.find(idx) != facilities.end()) { facilities[idx]->push_back(f_ident); diff --git a/src/ATC/ATCDialog.cxx b/src/ATC/ATCDialog.cxx index efcde15eb..0c96b36ce 100644 --- a/src/ATC/ATCDialog.cxx +++ b/src/ATC/ATCDialog.cxx @@ -460,7 +460,7 @@ void FGATCDialog::FreqDisplay(string ident) { FGAirport a; if ( dclFindAirportID( ident, &a ) ) { comm_list_type stations; - int found = current_commlist->FindByPos(a.longitude, a.latitude, a.elevation, 20.0, &stations); + int found = current_commlist->FindByPos(a._longitude, a._latitude, a._elevation, 20.0, &stations); if(found) { ostringstream ostr; comm_list_iterator itr = stations.begin(); diff --git a/src/ATC/ATCmgr.cxx b/src/ATC/ATCmgr.cxx index e4a5407c5..26b1bc801 100644 --- a/src/ATC/ATCmgr.cxx +++ b/src/ATC/ATCmgr.cxx @@ -221,9 +221,9 @@ bool FGATCMgr::AIRegisterAirport(string ident) { //cout << "ident = " << ident << '\n'; AirportATC *a = new AirportATC; // I'm not entirely sure that this AirportATC structure business is actually needed - it just duplicates what we can find out anyway! - a->lon = ap.longitude; - a->lat = ap.latitude; - a->elev = ap.elevation; + a->lon = ap._longitude; + a->lat = ap._latitude; + a->elev = ap._elevation; a->atis_freq = GetFrequency(ident, ATIS); //cout << "ATIS freq = " << a->atis_freq << '\n'; a->atis_active = false; @@ -270,9 +270,9 @@ bool FGATCMgr::CommRegisterAirport(string ident, int chan, atc_type tp) { if(dclFindAirportID(ident, &ap)) { AirportATC *a = new AirportATC; // I'm not entirely sure that this AirportATC structure business is actually needed - it just duplicates what we can find out anyway! - a->lon = ap.longitude; - a->lat = ap.latitude; - a->elev = ap.elevation; + a->lon = ap._longitude; + a->lat = ap._latitude; + a->elev = ap._elevation; a->atis_freq = GetFrequency(ident, ATIS); a->atis_active = false; a->tower_freq = GetFrequency(ident, TOWER); diff --git a/src/ATC/ATCutils.cxx b/src/ATC/ATCutils.cxx index fa00be1e4..55e9be7aa 100644 --- a/src/ATC/ATCutils.cxx +++ b/src/ATC/ATCutils.cxx @@ -314,7 +314,7 @@ bool dclFindAirportID( const string& id, FGAirport *a ) { SG_LOG( SG_GENERAL, SG_INFO, "Searching for airport code = " << id ); result = globals->get_airports()->search( id ); - if ( result.id.empty() ) { + if ( result._id.empty() ) { SG_LOG( SG_GENERAL, SG_WARN, "Failed to find " << id << " in basic.dat.gz" ); return false; @@ -327,8 +327,8 @@ bool dclFindAirportID( const string& id, FGAirport *a ) { SG_LOG( SG_GENERAL, SG_INFO, "Position for " << id << " is (" - << a->longitude << ", " - << a->latitude << ")" ); + << a->_longitude << ", " + << a->_latitude << ")" ); return true; } @@ -342,7 +342,7 @@ double dclGetAirportElev( const string& id ) { "Finding elevation for airport: " << id ); if ( dclFindAirportID( id, &a ) ) { - return a.elevation * SG_FEET_TO_METER; + return a._elevation * SG_FEET_TO_METER; } else { return -9999.0; } @@ -357,7 +357,7 @@ Point3D dclGetAirportPos( const string& id ) { "Finding position for airport: " << id ); if ( dclFindAirportID( id, &a ) ) { - return Point3D(a.longitude, a.latitude, a.elevation); + return Point3D(a._longitude, a._latitude, a._elevation); } else { return Point3D(0.0, 0.0, -9999.0); } @@ -367,8 +367,8 @@ Point3D dclGetAirportPos( const string& id ) { // Given a Point3D (lon/lat/elev) and an FGRunway struct, determine if the point lies on the runway bool OnRunway(Point3D pt, const FGRunway& rwy) { FGATCAlignedProjection ortho; - Point3D centre(rwy.lon, rwy.lat, 0.0); // We don't need the elev - ortho.Init(centre, rwy.heading); + Point3D centre(rwy._lon, rwy._lat, 0.0); // We don't need the elev + ortho.Init(centre, rwy._heading); Point3D xyc = ortho.ConvertToLocal(centre); Point3D xyp = ortho.ConvertToLocal(pt); @@ -376,8 +376,8 @@ bool OnRunway(Point3D pt, const FGRunway& rwy) { //cout << "Length offset = " << fabs(xyp.y() - xyc.y()) << '\n'; //cout << "Width offset = " << fabs(xyp.x() - xyc.x()) << '\n'; - if((fabs(xyp.y() - xyc.y()) < ((rwy.length/2.0) + 5.0)) - && (fabs(xyp.x() - xyc.x()) < (rwy.width/2.0))) { + if((fabs(xyp.y() - xyc.y()) < ((rwy._length/2.0) + 5.0)) + && (fabs(xyp.x() - xyc.x()) < (rwy._width/2.0))) { return(true); } diff --git a/src/ATC/approach.cxx b/src/ATC/approach.cxx index ec68db500..a08f571b5 100644 --- a/src/ATC/approach.cxx +++ b/src/ATC/approach.cxx @@ -559,11 +559,11 @@ void FGApproach::get_active_runway() { FGRunway runway; if ( globals->get_runways()->search( ident, int(hdg), &runway) ) { - active_runway = runway.rwy_no; - active_rw_hdg = runway.heading; - active_rw_lon = runway.lon; - active_rw_lat = runway.lat; - active_rw_len = runway.length; + active_runway = runway._rwy_no; + active_rw_hdg = runway._heading; + active_rw_lon = runway._lon; + active_rw_lat = runway._lat; + active_rw_len = runway._length; //cout << "Active runway is: " << active_runway << " heading = " // << active_rw_hdg // << " lon = " << active_rw_lon diff --git a/src/ATC/commlist.cxx b/src/ATC/commlist.cxx index 3dd52b0cb..a88ba3521 100644 --- a/src/ATC/commlist.cxx +++ b/src/ATC/commlist.cxx @@ -276,7 +276,7 @@ bool FGCommList::FindByCode( string ICAO, ATCData& ad, atc_type tp ) { FGAirport a; if ( dclFindAirportID( ICAO, &a ) ) { comm_list_type stations; - int found = FindByPos(a.longitude, a.latitude, a.elevation, 10.0, &stations, tp); + int found = FindByPos(a._longitude, a._latitude, a._elevation, 10.0, &stations, tp); if(found) { comm_list_iterator itr = stations.begin(); while(itr != stations.end()) { diff --git a/src/ATC/ground.cxx b/src/ATC/ground.cxx index 3e2e0f68b..32e01c1dd 100644 --- a/src/ATC/ground.cxx +++ b/src/ATC/ground.cxx @@ -367,25 +367,25 @@ void FGGround::DoRwyDetails() { FGRunway runway; bool rwyGood = globals->get_runways()->search(ident, int(hdg), &runway); if(rwyGood) { - activeRwy = runway.rwy_no; - rwy.rwyID = runway.rwy_no; + activeRwy = runway._rwy_no; + rwy.rwyID = runway._rwy_no; SG_LOG(SG_ATC, SG_INFO, "In FGGround, active runway for airport " << ident << " is " << activeRwy); // Get the threshold position - double other_way = runway.heading - 180.0; + double other_way = runway._heading - 180.0; while(other_way <= 0.0) { other_way += 360.0; } // move to the +l end/center of the runway - //cout << "Runway center is at " << runway.lon << ", " << runway.lat << '\n'; - Point3D origin = Point3D(runway.lon, runway.lat, aptElev); + //cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n'; + Point3D origin = Point3D(runway._lon, runway._lat, aptElev); Point3D ref = origin; double tshlon, tshlat, tshr; double tolon, tolat, tor; - rwy.length = runway.length * SG_FEET_TO_METER; + rwy.length = runway._length * SG_FEET_TO_METER; geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), other_way, rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr ); - geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), runway.heading, + geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), runway._heading, rwy.length / 2.0 - 25.0, &tolat, &tolon, &tor ); // Note - 25 meters in from the runway end is a bit of a hack to put the plane ahead of the user. // now copy what we need out of runway into rwy @@ -393,7 +393,7 @@ void FGGround::DoRwyDetails() { Point3D takeoff_end = Point3D(tolon, tolat, aptElev); //cout << "Threshold position = " << tshlon << ", " << tshlat << ", " << aptElev << '\n'; //cout << "Takeoff position = " << tolon << ", " << tolat << ", " << aptElev << '\n'; - rwy.hdg = runway.heading; + rwy.hdg = runway._heading; // Set the projection for the local area based on this active runway ortho.Init(rwy.threshold_pos, rwy.hdg); rwy.end1ortho = ortho.ConvertToLocal(rwy.threshold_pos); // should come out as zero diff --git a/src/ATC/tower.cxx b/src/ATC/tower.cxx index e5b632f0b..1271e920a 100644 --- a/src/ATC/tower.cxx +++ b/src/ATC/tower.cxx @@ -1385,26 +1385,26 @@ void FGTower::DoRwyDetails() { bool rwyGood = globals->get_runways()->search(ident, int(hdg), &runway); if(rwyGood) { //cout << "RUNWAY GOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOD\n"; - activeRwy = runway.rwy_no; - rwy.rwyID = runway.rwy_no; + activeRwy = runway._rwy_no; + rwy.rwyID = runway._rwy_no; SG_LOG(SG_ATC, SG_INFO, "Active runway for airport " << ident << " is " << activeRwy); // Get the threshold position - double other_way = runway.heading - 180.0; + double other_way = runway._heading - 180.0; while(other_way <= 0.0) { other_way += 360.0; } // move to the +l end/center of the runway - //cout << "Runway center is at " << runway.lon << ", " << runway.lat << '\n'; - Point3D origin = Point3D(runway.lon, runway.lat, aptElev); + //cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n'; + Point3D origin = Point3D(runway._lon, runway._lat, aptElev); Point3D ref = origin; double tshlon, tshlat, tshr; double tolon, tolat, tor; - rwy.length = runway.length * SG_FEET_TO_METER; - rwy.width = runway.width * SG_FEET_TO_METER; + rwy.length = runway._length * SG_FEET_TO_METER; + rwy.width = runway._width * SG_FEET_TO_METER; geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), other_way, rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr ); - geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), runway.heading, + geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), runway._heading, rwy.length / 2.0 - 25.0, &tolat, &tolon, &tor ); // Note - 25 meters in from the runway end is a bit of a hack to put the plane ahead of the user. // now copy what we need out of runway into rwy @@ -1412,7 +1412,7 @@ void FGTower::DoRwyDetails() { Point3D takeoff_end = Point3D(tolon, tolat, aptElev); //cout << "Threshold position = " << tshlon << ", " << tshlat << ", " << aptElev << '\n'; //cout << "Takeoff position = " << tolon << ", " << tolat << ", " << aptElev << '\n'; - rwy.hdg = runway.heading; + rwy.hdg = runway._heading; // Set the projection for the local area based on this active runway ortho.Init(rwy.threshold_pos, rwy.hdg); rwy.end1ortho = ortho.ConvertToLocal(rwy.threshold_pos); // should come out as zero @@ -1471,9 +1471,9 @@ bool FGTower::OnAnyRunway(Point3D pt) { SG_LOG(SG_ATC, SG_WARN, "Unable to find any runways for airport ID " << ad.ident << " in FGTower"); } bool on = false; - while(runway.id == ad.ident) { + while(runway._id == ad.ident) { on = OnRunway(pt, runway); - //cout << "Runway " << runway.rwy_no << ": On = " << (on ? "true\n" : "false\n"); + //cout << "Runway " << runway._rwy_no << ": On = " << (on ? "true\n" : "false\n"); if(on) return(true); globals->get_runways()->next(&runway); } diff --git a/src/Airports/Makefile.am b/src/Airports/Makefile.am index c7ed3669b..7a92691f9 100644 --- a/src/Airports/Makefile.am +++ b/src/Airports/Makefile.am @@ -3,6 +3,7 @@ noinst_LIBRARIES = libAirports.a noinst_PROGRAMS = calc_loc libAirports_a_SOURCES = \ + apt_loader.cxx apt_loader.hxx \ runways.cxx runways.hxx \ simple.cxx simple.hxx diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx new file mode 100644 index 000000000..d978649a6 --- /dev/null +++ b/src/Airports/apt_loader.cxx @@ -0,0 +1,245 @@ +// apt_loader.cxx -- a front end loader of the apt.dat file. This loader +// populates the runway and basic classes. +// +// Written by Curtis Olson, started August 2000. +// +// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include // atof(), atoi() + +#include +#include +#include +#include + +#include STL_STRING + +#include "simple.hxx" +#include "runways.hxx" + +#include "apt_loader.hxx" + + +// Load the airport data base from the specified aptdb file. The +// metar file is used to mark the airports as having metar available +// or not. +bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, + const string &aptdb_file, const string &metar_file ) +{ + // + // Load the apt.dat file + // + + sg_gzifstream in( aptdb_file ); + if ( !in.is_open() ) { + SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << aptdb_file ); + exit(-1); + } + + vector token; + string last_apt_id = ""; + double last_apt_elev = 0.0; + string last_apt_name = ""; + string last_apt_info = ""; + string last_apt_type = ""; + string line; + char tmp[2048]; + + double rwy_lon_accum = 0.0; + double rwy_lat_accum = 0.0; + int rwy_count = 0; + + while ( ! in.eof() ) { + in.getline(tmp, 2048); + line = tmp; + SG_LOG( SG_GENERAL, SG_DEBUG, "-> '" << line << "'" ); + if ( line.length() ) { + token = simgear::strutils::split( line ); + if ( token.size() ) { + SG_LOG( SG_GENERAL, SG_DEBUG, "token[0] " << token[0] ); + } + } else { + token.clear(); + } + + if ( !line.length() || !token.size() ) { + // empty line, skip + } else if ( (token[0] == "#") || (token[0] == "//") ) { + // comment, skip + } else if ( token[0] == "I" ) { + // First line, indicates IBM (i.e. DOS line endings I + // believe.) + + // move past this line and read and discard the next line + // which is the version and copyright information + in.getline(tmp, 2048); + vector vers_token = simgear::strutils::split( tmp ); + SG_LOG( SG_GENERAL, SG_INFO, "Data file version = " + << vers_token[0] ); + } else if ( token[0] == "1" /* Airport */ || + token[0] == "16" /* Seaplane base */ || + token[0] == "17" /* Heliport */ ) { + + string id = token[4]; + double elev = atof( token[1].c_str() ); + SG_LOG( SG_GENERAL, SG_DEBUG, "Next airport = " << id << " " + << elev ); + + if ( !last_apt_id.empty()) { + if ( rwy_count > 0 ) { + double lat = rwy_lat_accum / (double)rwy_count; + double lon = rwy_lon_accum / (double)rwy_count; + airports->add( last_apt_id, lon, lat, last_apt_elev, + last_apt_name, false ); + } else { + if ( !last_apt_id.length() ) { + SG_LOG(SG_GENERAL, SG_ALERT, + "ERROR: No runways for " << last_apt_id + << " skipping." ); + } + } + } + + last_apt_id = id; + last_apt_elev = atof( token[1].c_str() ); + last_apt_name = ""; + + // build the name + for ( unsigned int i = 5; i < token.size() - 1; ++i ) { + last_apt_name += token[i]; + last_apt_name += " "; + } + last_apt_name += token[token.size() - 1]; + + last_apt_info = line; + last_apt_type = token[0]; + + // clear runway list for start of next airport + rwy_lon_accum = 0.0; + rwy_lat_accum = 0.0; + rwy_count = 0; + } else if ( token[0] == "10" ) { + // runway entry + double lat = atof( token[1].c_str() ); + double lon = atof( token[2].c_str() ); + rwy_lat_accum += lat; + rwy_lon_accum += lon; + rwy_count++; + + string rwy_no = token[3]; + + double heading = atof( token[4].c_str() ); + double length = atoi( token[5].c_str() ); + double width = atoi( token[8].c_str() ); + + string rwy_displ_threshold = token[6]; + vector displ + = simgear::strutils::split( rwy_displ_threshold, "." ); + double displ_thresh1 = atof( displ[0].c_str() ); + double displ_thresh2 = atof( displ[1].c_str() ); + + string rwy_stopway = token[7]; + vector stop + = simgear::strutils::split( rwy_stopway, "." ); + double stopway1 = atof( stop[0].c_str() ); + double stopway2 = atof( stop[1].c_str() ); + + string lighting_flags = token[9]; + int surface_code = atoi( token[10].c_str() ); + string shoulder_code = token[11]; + int marking_code = atoi( token[12].c_str() ); + double smoothness = atof( token[13].c_str() ); + bool dist_remaining = (atoi( token[14].c_str() ) == 1 ); + + runways->add( last_apt_id, rwy_no, lon, lat, heading, length, + width, displ_thresh1, displ_thresh2, + stopway1, stopway2, lighting_flags, surface_code, + shoulder_code, marking_code, smoothness, + dist_remaining ); + } else if ( token[0] == "18" ) { + // beacon entry (ignore) + } else if ( token[0] == "14" ) { + // control tower entry (ignore) + } else if ( token[0] == "19" ) { + // windsock entry (ignore) + } else if ( token[0] == "15" ) { + // custom startup locations (ignore) + } else if ( token[0] == "50" || token[0] == "51" || token[0] == "52" + || token[0] == "53" || token[0] == "54" || token[0] == "55" + || token[0] == "56" ) + { + // frequency entries (ignore) + } else if ( token[0] == "99" ) { + SG_LOG( SG_GENERAL, SG_DEBUG, "End of file reached" ); + } else { + SG_LOG( SG_GENERAL, SG_ALERT, + "Unknown line in file: " << line ); + exit(-1); + } + } + + if ( !last_apt_id.empty()) { + if ( rwy_count > 0 ) { + double lat = rwy_lat_accum / (double)rwy_count; + double lon = rwy_lon_accum / (double)rwy_count; + airports->add( last_apt_id, lon, lat, last_apt_elev, + last_apt_name, false ); + } else { + if ( !last_apt_id.length() ) { + SG_LOG(SG_GENERAL, SG_ALERT, + "ERROR: No runways for " << last_apt_id + << " skipping." ); + } + } + } + + // + // Load the metar.dat file and update apt db with stations that + // have metar data. + // + + sg_gzifstream metar_in( metar_file ); + if ( !metar_in.is_open() ) { + SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << metar_file ); + } + + string ident; + while ( metar_in ) { + metar_in >> ident; + if ( ident == "#" || ident == "//" ) { + metar_in >> skipeol; + } else { + FGAirport a = airports->search( ident ); + if ( a._id == ident ) { + airports->has_metar( ident ); + } + } + } + + SG_LOG(SG_GENERAL, SG_INFO, "[FINISHED LOADING]"); + + return true; +} diff --git a/src/Airports/apt_loader.hxx b/src/Airports/apt_loader.hxx new file mode 100644 index 000000000..d9df742e5 --- /dev/null +++ b/src/Airports/apt_loader.hxx @@ -0,0 +1,50 @@ +// apt_loader.hxx -- a front end loader of the apt.dat file. This loader +// populates the runway and basic classes. +// +// Written by Curtis Olson, started December 2004. +// +// Copyright (C) 2004 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _FG_APT_LOADER_HXX +#define _FG_APT_LOADER_HXX + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include STL_STRING + +SG_USING_STD(string); + +#include "simple.hxx" +#include "runways.hxx" + + +// Load the airport data base from the specified aptdb file. The +// metar file is used to mark the airports as having metar available +// or not. +bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, + const string &aptdb_file, const string &metar_file ); + + +#endif // _FG_APT_LOADER_HXX diff --git a/src/Airports/runways.cxx b/src/Airports/runways.cxx index e437dda08..ae32b9fa2 100644 --- a/src/Airports/runways.cxx +++ b/src/Airports/runways.cxx @@ -31,10 +31,8 @@ #include #include -#include #include STL_STRING -#include STL_IOSTREAM #include #include "runways.hxx" @@ -43,48 +41,51 @@ SG_USING_NAMESPACE(std); SG_USING_STD(istream); SG_USING_STD(multimap); -inline istream& -operator >> ( istream& in, FGRunway& a ) -{ - string type; - int tmp; - - in >> a.type; - if ( a.type == "R" ) { - in >> a.id >> a.rwy_no >> a.lat >> a.lon >> a.heading - >> a.length >> a.width >> a.surface_flags >> a.end1_flags - >> tmp >> tmp >> a.end2_flags >> tmp >> tmp; - } else if ( a.type == "T" ) { - // in >> a.id >> a.rwy_no >> a.lat >> a.lon >> a.heading - // >> a.length >> a.width >> a.surface_flags; - in >> skipeol; - } else { - in >> skipeol; - } - - return in; -} - -FGRunwayList::FGRunwayList( const string& file ) { - SG_LOG( SG_GENERAL, SG_DEBUG, "Reading runway list: " << file ); +// add an entry to the list +void FGRunwayList::add( const string id, const string rwy_no, + const double longitude, const double latitude, + const double heading, const double length, + const double width, + const double displ_thresh1, const double displ_thresh2, + const double stopway1, const double stopway2, + const string lighting_flags, const int surface_code, + const string shoulder_code, const int marking_code, + const double smoothness, const bool dist_remaining ) +{ + FGRunway rwy; - // open the specified file for reading - sg_gzifstream in( file ); - if ( !in.is_open() ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file ); - exit(-1); + rwy._id = id; + rwy._rwy_no = rwy_no; + // strip trailing "x" if it exists in runway number + string tmp = rwy._rwy_no.substr(2, 1); + if ( tmp == "x" ) { + rwy._rwy_no = rwy._rwy_no.substr(0, 2); } - // skip header line - in >> skipeol; - - FGRunway rwy; - while ( in ) { - in >> rwy; - if(rwy.type == "R") { - runways.insert(pair(rwy.id, rwy)); - } + rwy._lon = longitude; + rwy._lat = latitude; + rwy._heading = heading; + rwy._length = length; + rwy._width = width; + rwy._displ_thresh1 = displ_thresh1; + rwy._displ_thresh2 = displ_thresh2; + rwy._stopway1 = stopway1; + rwy._stopway2 = stopway2; + + rwy._lighting_flags = lighting_flags; + rwy._surface_code = surface_code; + rwy._shoulder_code = shoulder_code; + rwy._marking_code = marking_code; + rwy._smoothness = smoothness; + rwy._dist_remaining = dist_remaining; + + if ( rwy_no == "xxx" ) { + rwy._type = "taxiway"; + // don't insert taxiways into the DB for now + } else { + rwy._type = "runway"; + runways.insert(pair(rwy._id, rwy)); } } @@ -171,11 +172,11 @@ bool FGRunwayList::search( const string& aptid, const string& rwyno, for ( pos = runways.lower_bound( aptid ); pos != runways.upper_bound( aptid ); ++pos) { - if ( pos->second.rwy_no == runwayno ) { + if ( pos->second._rwy_no == runwayno ) { current = pos; *r = pos->second; return true; - } else if ( pos->second.rwy_no == revrwyno ) { + } else if ( pos->second._rwy_no == revrwyno ) { // Search again with the other-end runway number. // Remember we have to munge the heading and rwy_no // results if this one matches @@ -183,11 +184,8 @@ bool FGRunwayList::search( const string& aptid, const string& rwyno, *r = pos->second; // NOTE - matching revrwyno implies that runwayno was // actually correct. - r->rwy_no = runwayno; - r->heading += 180.0; - string tmp = r->end1_flags; - r->end1_flags = r->end2_flags; - r->end2_flags = tmp; + r->_rwy_no = runwayno; + r->_heading += 180.0; return true; } } @@ -229,11 +227,11 @@ string FGRunwayList::search( const string& aptid, const int tgt_hdg ) { double diff; double min_diff = 360.0; - while ( tmp_r.id == aptid ) { + while ( tmp_r._id == aptid ) { r = tmp_r; // forward direction - diff = tgt_hdg - r.heading; + diff = tgt_hdg - r._heading; while ( diff < -180.0 ) { diff += 360.0; } while ( diff > 180.0 ) { diff -= 360.0; } diff = fabs(diff); @@ -242,31 +240,31 @@ string FGRunwayList::search( const string& aptid, const int tgt_hdg ) { // " diff = " << diff ); if ( diff < min_diff ) { min_diff = diff; - rn = r.rwy_no; + rn = r._rwy_no; found_dir = 0; } // reverse direction - diff = tgt_hdg - r.heading - 180.0; + diff = tgt_hdg - r._heading - 180.0; while ( diff < -180.0 ) { diff += 360.0; } while ( diff > 180.0 ) { diff -= 360.0; } diff = fabs(diff); // SG_LOG( SG_GENERAL, SG_INFO, - // "Runway -" << r.rwy_no << " heading = " << - // r.heading + 180.0 << + // "Runway -" << r._rwy_no << " heading = " << + // r._heading + 180.0 << // " diff = " << diff ); if ( diff < min_diff ) { min_diff = diff; - rn = r.rwy_no; + rn = r._rwy_no; found_dir = 180.0; } next( &tmp_r ); } - // SG_LOG( SG_GENERAL, SG_INFO, "closest runway = " << r.rwy_no + // SG_LOG( SG_GENERAL, SG_INFO, "closest runway = " << r._rwy_no // << " + " << found_dir ); - rn = r.rwy_no; + rn = r._rwy_no; // cout << "In search, rn = " << rn << endl; if ( found_dir == 180 ) { rn = GetReverseRunwayNo(rn); diff --git a/src/Airports/runways.hxx b/src/Airports/runways.hxx index 53d12424f..5fd647811 100644 --- a/src/Airports/runways.hxx +++ b/src/Airports/runways.hxx @@ -52,26 +52,26 @@ struct ltstr { struct FGRunway { - string type; - string id; - string rwy_no; - - double lon; - double lat; - double heading; - double length; - double width; - - string surface_flags; - string end1_flags; - string end2_flags; - - double end1_displaced_threshold; - double end2_displaced_threshold; - - double end1_stopway; - double end2_stopway; - + string _id; + string _rwy_no; + string _type; // runway / taxiway + + double _lon; + double _lat; + double _heading; + double _length; + double _width; + double _displ_thresh1; + double _displ_thresh2; + double _stopway1; + double _stopway2; + + string _lighting_flags; + int _surface_code; + string _shoulder_code; + int _marking_code; + double _smoothness; + bool _dist_remaining; }; typedef multimap < string, FGRunway, ltstr > runway_map; @@ -87,12 +87,22 @@ private: public: - // Constructor - FGRunwayList( const string& file ); + // Constructor (new) + FGRunwayList() {} // Destructor ~FGRunwayList(); + // add an entry to the list + void add( const string id, const string rwy_no, + const double longitude, const double latitude, + const double heading, const double length, const double width, + const double displ_thresh1, const double displ_thresh2, + const double stopway1, const double stopway2, + const string lighting_flags, const int surface_code, + const string shoulder_code, const int marking_code, + const double smoothness, const bool dist_remaining ); + // search for the specified apt id. // Returns true if successful, otherwise returns false. // On success, runway data is returned thru "runway" pointer. diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index e6952df03..a07fec777 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -32,91 +32,30 @@ #include #include -#include #include STL_STRING -#include STL_IOSTREAM #include "simple.hxx" SG_USING_NAMESPACE(std); -SG_USING_STD(istream); -inline istream& -operator >> ( istream& in, FGAirport& a ) +// add an entry to the list +void FGAirportList::add( const string id, const double longitude, + const double latitude, const double elevation, + const string name, const bool has_metar ) { - string junk; - in >> junk >> a.id >> a.latitude >> a.longitude >> a.elevation - >> a.code; - - getline( in,a.name ); - - // Remove the space before the name - if ( a.name.substr(0,1) == " " ) { - a.name = a.name.erase(0,1); - } - - a.has_metar = false; - -#if 0 - // As a quick seed for the has_metar value, only airports with - // four-letter codes can have metar stations - a.has_metar = (isalpha(a.id[0]) && isalpha(a.id[1]) && isalpha(a.id[2]) - && isalpha(a.id[3]) && !a.id[4]); -#endif - - return in; -} - - -FGAirportList::FGAirportList( const string &airport_file, - const string &metar_file ) { - SG_LOG( SG_GENERAL, SG_INFO, "Reading simple airport list: " - << airport_file ); - - // open the specified file for reading - sg_gzifstream apt_in( airport_file ); - if ( !apt_in.is_open() ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << airport_file ); - exit(-1); - } - - // skip header line - apt_in >> skipeol; - FGAirport a; - while ( apt_in ) { - apt_in >> a; - airports_by_id[a.id] = a; - airports_array.push_back( &airports_by_id[a.id] ); - } - - - SG_LOG( SG_GENERAL, SG_INFO, "Reading simple metar station list: " - << metar_file ); - - // open the specified file for reading - sg_gzifstream metar_in( metar_file ); - if ( !metar_in.is_open() ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << metar_file ); - } - - string ident; - while ( metar_in ) { - metar_in >> ident; - if ( ident == "#" || ident == "//" ) { - metar_in >> skipeol; - } else { - airport_map_iterator apt = airports_by_id.find( ident ); - if ( apt == airports_by_id.end() ) { - SG_LOG( SG_GENERAL, SG_DEBUG, "no apt = " << ident ); - } else { - SG_LOG( SG_GENERAL, SG_DEBUG, "metar = " << ident ); - airports_by_id[ident].has_metar = true; - } - } - } + a._id = id; + a._longitude = longitude; + a._latitude = latitude; + a._elevation = elevation; + a._name = name; + a._has_metar = has_metar; + airports_by_id[a._id] = a; + airports_array.push_back( &airports_by_id[a._id] ); + SG_LOG( SG_GENERAL, SG_DEBUG, "Adding " << id << " pos = " << longitude + << ", " << latitude << " elev = " << elevation ); } @@ -134,10 +73,10 @@ FGAirport FGAirportList::search( double lon_deg, double lat_deg, unsigned int i; for ( i = 0; i < airports_array.size(); ++i ) { // crude manhatten distance based on lat/lon difference - double d = fabs(lon_deg - airports_array[i]->longitude) - + fabs(lat_deg - airports_array[i]->latitude); + double d = fabs(lon_deg - airports_array[i]->_longitude) + + fabs(lat_deg - airports_array[i]->_latitude); if ( d < min_dist ) { - if ( !with_metar || (with_metar && airports_array[i]->has_metar) ) { + if ( !with_metar || (with_metar&&airports_array[i]->_has_metar) ) { closest = i; min_dist = d; } @@ -168,5 +107,13 @@ const FGAirport *FGAirportList::getAirport( int index ) const * Mark the specified airport record as not having metar */ void FGAirportList::no_metar( const string &id ) { - airports_by_id[id].has_metar = false; + airports_by_id[id]._has_metar = false; +} + + +/** + * Mark the specified airport record as (yes) having metar + */ +void FGAirportList::has_metar( const string &id ) { + airports_by_id[id]._has_metar = true; } diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index d6c84a7b4..6b76400c9 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -48,13 +48,13 @@ SG_USING_STD(vector); struct FGAirport { - string id; - double longitude; - double latitude; - double elevation; - string code; - string name; - bool has_metar; + string _id; + double _longitude; + double _latitude; + double _elevation; + string _code; // depricated and can be removed + string _name; + bool _has_metar; }; typedef map < string, FGAirport > airport_map; @@ -73,12 +73,16 @@ private: public: - // Constructor - FGAirportList( const string &airport_file, const string &metar_file ); + // Constructor (new) + FGAirportList() {} // Destructor ~FGAirportList(); + // add an entry to the list + void add( const string id, const double longitude, const double latitude, + const double elevation, const string name, const bool has_metar ); + // search for the specified id. // Returns true if successful, otherwise returns false. // On success, airport data is returned thru "airport" pointer. @@ -109,6 +113,11 @@ public: */ void no_metar( const string &id ); + /** + * Mark the specified airport record as (yes) having metar + */ + void has_metar( const string &id ); + }; diff --git a/src/Autopilot/auto_gui.cxx b/src/Autopilot/auto_gui.cxx index a126df2b3..38ddeb215 100644 --- a/src/Autopilot/auto_gui.cxx +++ b/src/Autopilot/auto_gui.cxx @@ -668,7 +668,7 @@ int NewWaypoint( string Tgt_Alt ) sprintf( NewTgtAirportId, "%s", TgtAptId.c_str() ); - SGWayPoint wp( a.longitude, a.latitude, alt, + SGWayPoint wp( a._longitude, a._latitude, alt, SGWayPoint::WGS84, TgtAptId ); rm->add_waypoint( wp ); diff --git a/src/Cockpit/hud_rwy.cxx b/src/Cockpit/hud_rwy.cxx index e2b30c71a..20a3832cf 100644 --- a/src/Cockpit/hud_rwy.cxx +++ b/src/Cockpit/hud_rwy.cxx @@ -162,26 +162,26 @@ void runway_instr::get_rwy_points(sgdVec3 *points3d) { if (center != currentCenter) //if changing tiles tileCenter = center; //use last center double alt = current_aircraft.fdm_state->get_Runway_altitude()*SG_FEET_TO_METER; - double length = (runway.length/2.0)*SG_FEET_TO_METER; - double width = (runway.width/2.0)*SG_FEET_TO_METER; + double length = (runway._length/2.0)*SG_FEET_TO_METER; + double width = (runway._width/2.0)*SG_FEET_TO_METER; double frontLat,frontLon,backLat,backLon,az,tempLat,tempLon; - geo_direct_wgs_84(alt,runway.lat,runway.lon,runway.heading,length,&backLat,&backLon,&az); + geo_direct_wgs_84(alt,runway._lat,runway._lon,runway._heading,length,&backLat,&backLon,&az); sgGeodToCart(backLat*SG_DEGREES_TO_RADIANS,backLon*SG_DEGREES_TO_RADIANS,alt,points3d[4]); - geo_direct_wgs_84(alt,runway.lat,runway.lon,runway.heading+180,length,&frontLat,&frontLon,&az); + geo_direct_wgs_84(alt,runway._lat,runway._lon,runway._heading+180,length,&frontLat,&frontLon,&az); sgGeodToCart(frontLat*SG_DEGREES_TO_RADIANS,frontLon*SG_DEGREES_TO_RADIANS,alt,points3d[5]); - geo_direct_wgs_84(alt,backLat,backLon,runway.heading+90,width,&tempLat,&tempLon,&az); + geo_direct_wgs_84(alt,backLat,backLon,runway._heading+90,width,&tempLat,&tempLon,&az); sgGeodToCart(tempLat*SG_DEGREES_TO_RADIANS,tempLon*SG_DEGREES_TO_RADIANS,alt,points3d[0]); - geo_direct_wgs_84(alt,backLat,backLon,runway.heading-90,width,&tempLat,&tempLon,&az); + geo_direct_wgs_84(alt,backLat,backLon,runway._heading-90,width,&tempLat,&tempLon,&az); sgGeodToCart(tempLat*SG_DEGREES_TO_RADIANS,tempLon*SG_DEGREES_TO_RADIANS,alt,points3d[1]); - geo_direct_wgs_84(alt,frontLat,frontLon,runway.heading-90,width,&tempLat,&tempLon,&az); + geo_direct_wgs_84(alt,frontLat,frontLon,runway._heading-90,width,&tempLat,&tempLon,&az); sgGeodToCart(tempLat*SG_DEGREES_TO_RADIANS,tempLon*SG_DEGREES_TO_RADIANS,alt,points3d[2]); - geo_direct_wgs_84(alt,frontLat,frontLon,runway.heading+90,width,&tempLat,&tempLon,&az); + geo_direct_wgs_84(alt,frontLat,frontLon,runway._heading+90,width,&tempLat,&tempLon,&az); sgGeodToCart(tempLat*SG_DEGREES_TO_RADIANS,tempLon*SG_DEGREES_TO_RADIANS,alt,points3d[3]); for(int i = 0; i < 6; i++) @@ -354,8 +354,8 @@ void runway_instr::drawArrow() { Point3D ac,rwy; ac.setlat(current_aircraft.fdm_state->get_Latitude_deg()); ac.setlon(current_aircraft.fdm_state->get_Longitude_deg()); - rwy.setlat(runway.lat); - rwy.setlon(runway.lon); + rwy.setlat(runway._lat); + rwy.setlon(runway._lon); float theta = GetHeadingFromTo(ac,rwy); theta -= fgGetDouble("/orientation/heading-deg"); theta = -theta; @@ -382,7 +382,7 @@ void runway_instr::drawArrow() { void runway_instr::setLineWidth() { //Calculate the distance from the runway, A double course, distance; - calc_gc_course_dist(Point3D(runway.lon*SGD_DEGREES_TO_RADIANS, runway.lat*SGD_DEGREES_TO_RADIANS, 0.0), + calc_gc_course_dist(Point3D(runway._lon*SGD_DEGREES_TO_RADIANS, runway._lat*SGD_DEGREES_TO_RADIANS, 0.0), Point3D(current_aircraft.fdm_state->get_Longitude(),current_aircraft.fdm_state->get_Latitude(), 0.0 ), &course, &distance); distance *= SG_METER_TO_NM; diff --git a/src/Environment/environment_ctrl.cxx b/src/Environment/environment_ctrl.cxx index d47f8e2d6..d021172eb 100644 --- a/src/Environment/environment_ctrl.cxx +++ b/src/Environment/environment_ctrl.cxx @@ -324,8 +324,8 @@ FGMetarEnvironmentCtrl::FGMetarEnvironmentCtrl () proxy_host( fgGetNode("/sim/presets/proxy/host", true) ), proxy_port( fgGetNode("/sim/presets/proxy/port", true) ), proxy_auth( fgGetNode("/sim/presets/proxy/authentication", true) ), - _error_dt( 0.0 ), - _error_count( 0 ) + _error_count( 0 ), + _error_dt( 0.0 ) { #if defined(ENABLE_THREADS) && ENABLE_THREADS thread = new MetarThread(this); @@ -399,11 +399,11 @@ FGMetarEnvironmentCtrl::init () ->search( longitude->getDoubleValue(), latitude->getDoubleValue(), true ); - FGMetarResult result = fetch_data( a.id ); + FGMetarResult result = fetch_data( a._id ); if ( result.m != NULL ) { - SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = " << a.id); + SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = " << a._id); last_apt = a; - _icao = a.id; + _icao = a._id; search_elapsed = 0.0; fetch_elapsed = 0.0; update_metar_properties( result.m ); @@ -413,8 +413,8 @@ FGMetarEnvironmentCtrl::init () } else { // mark as no metar so it doesn't show up in subsequent // searches. - SG_LOG( SG_GENERAL, SG_INFO, "no metar at metar = " << a.id ); - globals->get_airports()->no_metar( a.id ); + SG_LOG( SG_GENERAL, SG_INFO, "no metar at metar = " << a._id ); + globals->get_airports()->no_metar( a._id ); } } } @@ -456,13 +456,13 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec) ->search( longitude->getDoubleValue(), latitude->getDoubleValue(), true ); - if ( last_apt.id != a.id + if ( last_apt._id != a._id || fetch_elapsed > same_station_interval_sec ) { - SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = " << a.id); - request_queue.push( a.id ); + SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = " << a._id); + request_queue.push( a._id ); last_apt = a; - _icao = a.id; + _icao = a._id; search_elapsed = 0.0; fetch_elapsed = 0.0; } else { @@ -534,7 +534,7 @@ FGMetarEnvironmentCtrl::fetch_data( const string &icao ) // fetch station elevation if exists FGAirport a = globals->get_airports()->search( icao ); - station_elevation_ft = a.elevation; + station_elevation_ft = a._elevation; // fetch current metar data try { diff --git a/src/GUI/AirportList.cxx b/src/GUI/AirportList.cxx index df7c043d3..6ded7f88b 100644 --- a/src/GUI/AirportList.cxx +++ b/src/GUI/AirportList.cxx @@ -17,9 +17,9 @@ AirportList::AirportList (int x, int y, int width, int height) _content = new char *[_nAirports+1]; for (int i = 0; i < _nAirports; i++) { const FGAirport *airport = _airports->getAirport(i); - snprintf(buf, 1023, "%s %s\0", - airport->id.c_str(), - airport->name.c_str()); + snprintf(buf, 1023, "%s %s", + airport->_id.c_str(), + airport->_name.c_str()); unsigned int buf_len = (strlen(buf) > 1023) ? 1023 : strlen(buf); @@ -43,7 +43,7 @@ AirportList::~AirportList () char * AirportList::getStringValue () { - return (char *)_airports->getAirport(getIntegerValue())->id.c_str(); + return (char *)_airports->getAirport(getIntegerValue())->_id.c_str(); } // end of AirportList.cxx diff --git a/src/Instrumentation/gps.cxx b/src/Instrumentation/gps.cxx index b8dcb6d58..e1fe6077b 100644 --- a/src/Instrumentation/gps.cxx +++ b/src/Instrumentation/gps.cxx @@ -325,12 +325,12 @@ GPS::update (double delta_time_sec) FGAirport a; //cout << "Airport found" << endl; a = globals->get_airports()->search(longitude_deg, latitude_deg, false); - _wp1_ID_node->setStringValue(a.id.c_str()); - wp1_longitude_deg = a.longitude; - wp1_latitude_deg = a.latitude; - _wp1_name_node->setStringValue(a.name.c_str()); + _wp1_ID_node->setStringValue(a._id.c_str()); + wp1_longitude_deg = a._longitude; + wp1_latitude_deg = a._latitude; + _wp1_name_node->setStringValue(a._name.c_str()); _get_nearest_airport_node->setBoolValue(false); - _last_wp1_ID = wp1_ID = a.id.c_str(); + _last_wp1_ID = wp1_ID = a._id.c_str(); } // If the waypoint 0 ID has changed, try to find the new ID @@ -341,11 +341,11 @@ GPS::update (double delta_time_sec) if (waypont_type == "airport") { FGAirport a; a = globals->get_airports()->search( wp0_ID ); - if ( a.id == wp0_ID ) { + if ( a._id == wp0_ID ) { //cout << "Airport found" << endl; - wp0_longitude_deg = a.longitude; - wp0_latitude_deg = a.latitude; - _wp0_name_node->setStringValue(a.name.c_str()); + wp0_longitude_deg = a._longitude; + wp0_latitude_deg = a._latitude; + _wp0_name_node->setStringValue(a._name.c_str()); } } else if (waypont_type == "nav") { @@ -380,11 +380,11 @@ GPS::update (double delta_time_sec) if (waypont_type == "airport") { FGAirport a; a = globals->get_airports()->search( wp1_ID ); - if ( a.id == wp1_ID ) { + if ( a._id == wp1_ID ) { //cout << "Airport found" << endl; - wp1_longitude_deg = a.longitude; - wp1_latitude_deg = a.latitude; - _wp1_name_node->setStringValue(a.name.c_str()); + wp1_longitude_deg = a._longitude; + wp1_latitude_deg = a._latitude; + _wp1_name_node->setStringValue(a._name.c_str()); } } else if (waypont_type == "nav") { diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index fe426c178..2215fd295 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -70,6 +70,7 @@ #include #include +#include #include #include #include @@ -629,7 +630,7 @@ bool fgFindAirportID( const string& id, FGAirport *a ) { result = globals->get_airports()->search( id ); - if ( result.id.empty() ) { + if ( result._id.empty() ) { SG_LOG( SG_GENERAL, SG_ALERT, "Failed to find " << id << " in basic.dat.gz" ); return false; @@ -642,8 +643,8 @@ bool fgFindAirportID( const string& id, FGAirport *a ) { SG_LOG( SG_GENERAL, SG_INFO, "Position for " << id << " is (" - << a->longitude << ", " - << a->latitude << ")" ); + << a->_longitude << ", " + << a->_latitude << ")" ); return true; } @@ -658,7 +659,7 @@ static double fgGetAirportElev( const string& id ) { "Finding elevation for airport: " << id ); if ( fgFindAirportID( id, &a ) ) { - return a.elevation; + return a._elevation; } else { return -9999.0; } @@ -711,9 +712,9 @@ static bool fgSetTowerPosFromAirportID( const string& id, double hdg ) { float fudge_lat = .003f - fudge_lon; if ( fgFindAirportID( id, &a ) ) { - fgSetDouble("/sim/tower/longitude-deg", a.longitude + fudge_lon); - fgSetDouble("/sim/tower/latitude-deg", a.latitude + fudge_lat); - fgSetDouble("/sim/tower/altitude-ft", a.elevation + towerheight); + fgSetDouble("/sim/tower/longitude-deg", a._longitude + fudge_lon); + fgSetDouble("/sim/tower/latitude-deg", a._latitude + fudge_lat); + fgSetDouble("/sim/tower/altitude-ft", a._elevation + towerheight); return true; } else { return false; @@ -743,17 +744,17 @@ static bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) { } double lat2, lon2, az2; - double heading = r.heading; + double heading = r._heading; double azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } SG_LOG( SG_GENERAL, SG_INFO, - "runway = " << r.lon << ", " << r.lat - << " length = " << r.length * SG_FEET_TO_METER + "runway = " << r._lon << ", " << r._lat + << " length = " << r._length * SG_FEET_TO_METER << " heading = " << azimuth ); - geo_direct_wgs_84 ( 0, r.lat, r.lon, azimuth, - r.length * SG_FEET_TO_METER * 0.5 - 5.0, + geo_direct_wgs_84 ( 0, r._lat, r._lon, azimuth, + r._length * SG_FEET_TO_METER * 0.5 - 5.0, &lat2, &lon2, &az2 ); if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON ) { @@ -813,18 +814,18 @@ static bool fgSetPosFromAirportIDandRwy( const string& id, const string& rwy ) { } double lat2, lon2, az2; - double heading = r.heading; + double heading = r._heading; double azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } SG_LOG( SG_GENERAL, SG_INFO, - "runway = " << r.lon << ", " << r.lat - << " length = " << r.length * SG_FEET_TO_METER + "runway = " << r._lon << ", " << r._lat + << " length = " << r._length * SG_FEET_TO_METER << " heading = " << azimuth ); - geo_direct_wgs_84 ( 0, r.lat, r.lon, + geo_direct_wgs_84 ( 0, r._lat, r._lon, azimuth, - r.length * SG_FEET_TO_METER * 0.5 - 5.0, + r._length * SG_FEET_TO_METER * 0.5 - 5.0, &lat2, &lon2, &az2 ); if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON ) @@ -1037,20 +1038,21 @@ static void parseWaypoints() { bool fgInitNav () { - SG_LOG(SG_GENERAL, SG_INFO, "Loading Simple Airport List"); - SGPath p_simple( globals->get_fg_root() ); - p_simple.append( "Airports/basic.dat" ); + SG_LOG(SG_GENERAL, SG_INFO, "Loading Airport Database ..."); + + SGPath aptdb( globals->get_fg_root() ); + aptdb.append( "Airports/apt.dat" ); + SGPath p_metar( globals->get_fg_root() ); p_metar.append( "Airports/metar.dat" ); - FGAirportList *airports = new FGAirportList(p_simple.str(), p_metar.str()); - globals->set_airports( airports ); - SG_LOG(SG_GENERAL, SG_INFO, "Loading Runway List"); - SGPath p_runway( globals->get_fg_root() ); - p_runway.append( "Airports/runways.dat" ); - FGRunwayList *runways = new FGRunwayList( p_runway.str() ); + FGAirportList *airports = new FGAirportList(); + globals->set_airports( airports ); + FGRunwayList *runways = new FGRunwayList(); globals->set_runways( runways ); + fgAirportDBLoad( airports, runways, aptdb.str(), p_metar.str() ); + FGNavList *navlist = new FGNavList; FGNavList *loclist = new FGNavList; FGNavList *gslist = new FGNavList; diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index bfb59de09..1595e7a69 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -96,8 +96,8 @@ bool fgNavDBInit( FGAirportList *airports, // cout << r->get_type() << " " << r->get_apt_id() << " zero elev" // << endl; FGAirport a = airports->search( r->get_apt_id() ); - if ( a.id == r->get_apt_id() ) { - r->set_elev_ft( a.elevation ); + if ( a._id == r->get_apt_id() ) { + r->set_elev_ft( a._elevation ); // cout << " setting to " << a.elevation << endl; } } @@ -137,7 +137,7 @@ bool fgNavDBInit( FGAirportList *airports, static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, double threshold ) { - double hdg = rwy->heading; + double hdg = rwy->_heading; hdg += 180.0; if ( hdg > 360.0 ) { hdg -= 360.0; @@ -145,8 +145,8 @@ static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, // 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, + 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; @@ -170,9 +170,9 @@ static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, // cout << "Distance moved = " << dist_m << endl; // cout << "orig heading = " << loc->get_multiuse() << endl; - // cout << "new heading = " << rwy->heading << endl; + // cout << "new heading = " << rwy->_heading << endl; - double hdg_diff = loc->get_multiuse() - rwy->heading; + double hdg_diff = loc->get_multiuse() - rwy->_heading; // clamp to [-180.0 ... 180.0] if ( hdg_diff < -180.0 ) { @@ -184,7 +184,7 @@ static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, if ( fabs(hdg_diff) <= threshold ) { loc->set_lat( nloc_lat ); loc->set_lon( nloc_lon ); - loc->set_multiuse( rwy->heading ); + loc->set_multiuse( rwy->_heading ); } } diff --git a/src/Traffic/SchedFlight.cxx b/src/Traffic/SchedFlight.cxx index b05c7a6a8..245d3db0c 100644 --- a/src/Traffic/SchedFlight.cxx +++ b/src/Traffic/SchedFlight.cxx @@ -100,8 +100,8 @@ FGScheduledFlight::FGScheduledFlight(string cs, { callsign = cs; fltRules = fr; - departurePort.id = depPrt; - arrivalPort.id = arrPrt; + departurePort._id = depPrt; + arrivalPort._id = arrPrt; //departureTime = processTimeString(deptime); //arrivalTime = processTimeString(arrtime); cruiseAltitude = cruiseAlt; @@ -245,11 +245,11 @@ FGAirport * FGScheduledFlight::getArrivalAirport () // of the airports cannot be found. void FGScheduledFlight::initializeAirports() { - if(!(fgFindAirportID(arrivalPort.id, &arrivalPort ))) + if(!(fgFindAirportID(arrivalPort._id, &arrivalPort ))) { //cerr << ": Could not find " << arrivalPort.id << endl; } - if(!(fgFindAirportID(departurePort.id, &departurePort))) + if(!(fgFindAirportID(departurePort._id, &departurePort))) { //cerr << ": Could not find " << departurePort.id << endl; } diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx index 29bd9a743..0c622407e 100644 --- a/src/Traffic/Schedule.cxx +++ b/src/Traffic/Schedule.cxx @@ -190,18 +190,18 @@ void FGAISchedule::update(time_t now) dep = i->getDepartureAirport(); arr = i->getArrivalAirport (); - temp = sgPolarToCart3d(Point3D(dep->longitude * + temp = sgPolarToCart3d(Point3D(dep->_longitude * SG_DEGREES_TO_RADIANS, - dep->latitude * + dep->_latitude * SG_DEGREES_TO_RADIANS, 1.0)); a[0] = temp.x(); a[1] = temp.y(); a[2] = temp.z(); - temp = sgPolarToCart3d(Point3D(arr->longitude * + temp = sgPolarToCart3d(Point3D(arr->_longitude * SG_DEGREES_TO_RADIANS, - arr->latitude * + arr->_latitude * SG_DEGREES_TO_RADIANS, 1.0)); b[0] = temp.x(); @@ -250,8 +250,8 @@ void FGAISchedule::update(time_t now) } else { - lat = dep->latitude; - lon = dep->longitude; + lat = dep->_latitude; + lon = dep->_longitude; } SGWayPoint current (lon, @@ -260,8 +260,8 @@ void FGAISchedule::update(time_t now) SGWayPoint user ( userLongitude, userLatitude, i->getCruiseAlt()); - SGWayPoint dest ( arr->longitude, - arr->latitude, + SGWayPoint dest ( arr->_longitude, + arr->_latitude, i->getCruiseAlt()); // We really only need distance to user // and course to destination @@ -276,11 +276,11 @@ void FGAISchedule::update(time_t now) // one hour flight time, so that would be a good approximate point // to start a more detailed simulation of this aircraft. //cerr << registration << " is currently enroute from " - // << dep->id << " to " << arr->id << "distance : " + // << dep->_id << " to " << arr->_id << "distance : " // << distanceToUser*SG_METER_TO_NM << endl; if ((distanceToUser*SG_METER_TO_NM) < 500.0) { - string flightPlanName = dep->id + string("-") + arr->id + + string flightPlanName = dep->_id + string("-") + arr->_id + string(".xml"); int alt; //if ((i->getDepartureTime() < now)) @@ -289,7 +289,7 @@ void FGAISchedule::update(time_t now) // } //else //{ - // alt = dep->elevation+19; + // alt = dep->_elevation+19; // } FGAIModelEntity entity; -- 2.39.5