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.
//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;
// 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();
// 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;
//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;
//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();
// 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;
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;
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;
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;
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;
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;
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,
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);
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();
//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;
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);
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;
SG_LOG( SG_GENERAL, SG_INFO,
"Position for " << id << " is ("
- << a->longitude << ", "
- << a->latitude << ")" );
+ << a->_longitude << ", "
+ << a->_latitude << ")" );
return true;
}
"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;
}
"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);
}
// 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);
//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);
}
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
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()) {
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
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
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
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
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);
}
noinst_PROGRAMS = calc_loc
libAirports_a_SOURCES = \
+ apt_loader.cxx apt_loader.hxx \
runways.cxx runways.hxx \
simple.cxx simple.hxx
--- /dev/null
+// 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 <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include <stdlib.h> // atof(), atoi()
+
+#include <simgear/constants.h>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/misc/sgstream.hxx>
+#include <simgear/misc/strutils.hxx>
+
+#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<string> 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<string> 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<string> 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<string> 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;
+}
--- /dev/null
+// 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 <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#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
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/sgstream.hxx>
#include STL_STRING
-#include STL_IOSTREAM
#include <map>
#include "runways.hxx"
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<const string, FGRunway>(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<const string, FGRunway>(rwy._id, rwy));
}
}
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
*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;
}
}
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);
// " 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);
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;
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.
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/sgstream.hxx>
#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 );
}
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;
}
* 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;
}
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;
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.
*/
void no_metar( const string &id );
+ /**
+ * Mark the specified airport record as (yes) having metar
+ */
+ void has_metar( const string &id );
+
};
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 );
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++)
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;
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;
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);
->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 );
} 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 );
}
}
}
->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 {
// 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 {
_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);
char *
AirportList::getStringValue ()
{
- return (char *)_airports->getAirport(getIntegerValue())->id.c_str();
+ return (char *)_airports->getAirport(getIntegerValue())->_id.c_str();
}
// end of AirportList.cxx
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
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") {
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") {
#include <Aircraft/aircraft.hxx>
#include <FDM/UIUCModel/uiuc_aircraftdir.h>
+#include <Airports/apt_loader.hxx>
#include <Airports/runways.hxx>
#include <Airports/simple.hxx>
#include <ATC/ATCdisplay.hxx>
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;
SG_LOG( SG_GENERAL, SG_INFO,
"Position for " << id << " is ("
- << a->longitude << ", "
- << a->latitude << ")" );
+ << a->_longitude << ", "
+ << a->_latitude << ")" );
return true;
}
"Finding elevation for airport: " << id );
if ( fgFindAirportID( id, &a ) ) {
- return a.elevation;
+ return a._elevation;
} else {
return -9999.0;
}
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;
}
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 ) {
}
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 )
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;
// 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;
}
}
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;
// 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;
// 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 ) {
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 );
}
}
{
callsign = cs;
fltRules = fr;
- departurePort.id = depPrt;
- arrivalPort.id = arrPrt;
+ departurePort._id = depPrt;
+ arrivalPort._id = arrPrt;
//departureTime = processTimeString(deptime);
//arrivalTime = processTimeString(arrtime);
cruiseAltitude = cruiseAlt;
// 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;
}
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();
}
else
{
- lat = dep->latitude;
- lon = dep->longitude;
+ lat = dep->_latitude;
+ lon = dep->_longitude;
}
SGWayPoint current (lon,
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
// 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))
// }
//else
//{
- // alt = dep->elevation+19;
+ // alt = dep->_elevation+19;
// }
FGAIModelEntity entity;