Redo the runway database scheme to use a flat/ascii file and load the entire
database into memory at the start. This should completely eliminate any dependencies we have on metakit.
This commit is contained in:
parent
f0ddd9048f
commit
e6859e4fe0
13 changed files with 142 additions and 455 deletions
|
@ -97,13 +97,9 @@ void FGAILocalTraffic::GetRwyDetails() {
|
|||
|
||||
// Now we need to get the threshold position and rwy heading
|
||||
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "Airports" );
|
||||
path.append( "runways.mk4" );
|
||||
FGRunways runways( path.c_str() );
|
||||
|
||||
FGRunway runway;
|
||||
bool rwyGood = runways.search(airportID, rwy.rwyID, &runway);
|
||||
bool rwyGood = globals->get_runways()->search(airportID, rwy.rwyID,
|
||||
&runway);
|
||||
if(rwyGood) {
|
||||
// Get the threshold position
|
||||
hdg = runway.heading; // TODO - check - is this our heading we are setting here, and if so should we be?
|
||||
|
|
|
@ -274,7 +274,7 @@ bool dclFindAirportID( const string& id, FGAirport *a ) {
|
|||
result = globals->get_airports()->search( id );
|
||||
if ( result.id.empty() ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||
"Failed to find " << id << " in simple.apt.gz" );
|
||||
"Failed to find " << id << " in basic.dat.gz" );
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -544,11 +544,6 @@ void FGApproach::get_active_runway() {
|
|||
->getEnvironment(lat, lon, elev);
|
||||
#endif
|
||||
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "Airports" );
|
||||
path.append( "runways.mk4" );
|
||||
FGRunways runways( path.c_str() );
|
||||
|
||||
#ifdef FG_WEATHERCM
|
||||
//Set the heading to into the wind
|
||||
double wind_x = stationweather.Wind[0];
|
||||
|
@ -573,7 +568,7 @@ void FGApproach::get_active_runway() {
|
|||
#endif
|
||||
|
||||
FGRunway runway;
|
||||
if ( runways.search( ident, int(hdg), &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;
|
||||
|
|
|
@ -214,11 +214,7 @@ void FGATIS::UpdateTransmission() {
|
|||
|
||||
// Based on the airport-id and wind get the active runway
|
||||
//FGRunway *r;
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "Airports" );
|
||||
path.append( "runways.mk4" );
|
||||
FGRunways runways( path.c_str() );
|
||||
|
||||
|
||||
#ifdef FG_WEATHERCM
|
||||
//Set the heading to into the wind
|
||||
double wind_x = stationweather.Wind[0];
|
||||
|
@ -269,7 +265,7 @@ void FGATIS::UpdateTransmission() {
|
|||
}
|
||||
#endif
|
||||
|
||||
string rwy_no = runways.search(ident, int(hdg));
|
||||
string rwy_no = globals->get_runways()->search(ident, int(hdg));
|
||||
if(rwy_no != (string)"NN") {
|
||||
transmission += " / Landing_and_departing_runway ";
|
||||
transmission += ConvertRwyNumToSpokenString(atoi(rwy_no.c_str()));
|
||||
|
|
|
@ -356,10 +356,6 @@ void FGGround::DoRwyDetails() {
|
|||
//cout << "GetRwyDetails called" << endl;
|
||||
|
||||
// Based on the airport-id and wind get the active runway
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "Airports" );
|
||||
path.append( "runways.mk4" );
|
||||
FGRunways r_ways( path.c_str() );
|
||||
|
||||
//wind
|
||||
double hdg = wind_from_hdg->getDoubleValue();
|
||||
|
@ -368,7 +364,7 @@ void FGGround::DoRwyDetails() {
|
|||
//cout << "Heading = " << hdg << '\n';
|
||||
|
||||
FGRunway runway;
|
||||
bool rwyGood = r_ways.search(ident, int(hdg), &runway);
|
||||
bool rwyGood = globals->get_runways()->search(ident, int(hdg), &runway);
|
||||
if(rwyGood) {
|
||||
activeRwy = runway.rwy_no;
|
||||
rwy.rwyID = runway.rwy_no;
|
||||
|
|
|
@ -524,10 +524,6 @@ void FGTower::DoRwyDetails() {
|
|||
//cout << "GetRwyDetails called" << endl;
|
||||
|
||||
// Based on the airport-id and wind get the active runway
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "Airports" );
|
||||
path.append( "runways.mk4" );
|
||||
FGRunways runways( path.c_str() );
|
||||
|
||||
//wind
|
||||
double hdg = wind_from_hdg->getDoubleValue();
|
||||
|
@ -536,7 +532,7 @@ void FGTower::DoRwyDetails() {
|
|||
//cout << "Heading = " << hdg << '\n';
|
||||
|
||||
FGRunway runway;
|
||||
bool rwyGood = runways.search(ident, int(hdg), &runway);
|
||||
bool rwyGood = globals->get_runways()->search(ident, int(hdg), &runway);
|
||||
if(rwyGood) {
|
||||
activeRwy = runway.rwy_no;
|
||||
rwy.rwyID = runway.rwy_no;
|
||||
|
@ -605,16 +601,12 @@ bool FGTower::OnAnyRunway(Point3D pt) {
|
|||
return(false);
|
||||
}
|
||||
// Based on the airport-id, go through all the runways and check for a point in them
|
||||
SGPath spath( globals->get_fg_root() );
|
||||
spath.append( "Airports" );
|
||||
spath.append( "runways.mk4" );
|
||||
FGRunways runways( spath.c_str() );
|
||||
|
||||
// TODO - do we actually need to search for the airport - surely we already know our ident and
|
||||
// can just search runways of our airport???
|
||||
//cout << "Airport ident is " << ad.ident << '\n';
|
||||
FGRunway runway;
|
||||
bool rwyGood = runways.search(ad.ident, &runway);
|
||||
bool rwyGood = globals->get_runways()->search(ad.ident, &runway);
|
||||
if(!rwyGood) {
|
||||
SG_LOG(SG_ATC, SG_WARN, "Unable to find any runways for airport ID " << ad.ident << " in FGTower");
|
||||
}
|
||||
|
@ -623,7 +615,7 @@ bool FGTower::OnAnyRunway(Point3D pt) {
|
|||
on = OnRunway(pt, runway);
|
||||
//cout << "Runway " << runway.rwy_no << ": On = " << (on ? "true\n" : "false\n");
|
||||
if(on) return(true);
|
||||
runways.next(&runway);
|
||||
globals->get_runways()->next(&runway);
|
||||
}
|
||||
return(on);
|
||||
}
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
noinst_LIBRARIES = libAirports.a
|
||||
|
||||
noinst_PROGRAMS = genrunways calc_loc
|
||||
noinst_PROGRAMS = calc_loc
|
||||
|
||||
libAirports_a_SOURCES = \
|
||||
runways.cxx runways.hxx \
|
||||
simple.cxx simple.hxx
|
||||
|
||||
genrunways_SOURCES = genrunways.cxx
|
||||
genrunways_LDADD = libAirports.a -lsgdebug -lsgmisc -lsgxml -lmk4 -lz
|
||||
|
||||
calc_loc_SOURCES = calc_loc.cxx
|
||||
calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lz
|
||||
|
||||
|
|
|
@ -34,59 +34,53 @@
|
|||
#include <simgear/misc/sgstream.hxx>
|
||||
|
||||
#include STL_STRING
|
||||
#include STL_FUNCTIONAL
|
||||
#include STL_ALGORITHM
|
||||
#include STL_IOSTREAM
|
||||
#include <map>
|
||||
|
||||
#include "runways.hxx"
|
||||
|
||||
SG_USING_NAMESPACE(std);
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define NDEBUG // MSVC needs this
|
||||
#endif // !_MSC_VER
|
||||
|
||||
#include <mk4.h>
|
||||
#include <mk4str.h>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#undef NDEBUG
|
||||
#endif // !_MSC_VER
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <istream>
|
||||
#elif defined( __BORLANDC__ ) || defined (__APPLE__)
|
||||
# include <iostream>
|
||||
#else
|
||||
# include <istream.h>
|
||||
#endif
|
||||
|
||||
SG_USING_STD(istream);
|
||||
SG_USING_STD(multimap);
|
||||
|
||||
inline istream&
|
||||
operator >> ( istream& in, FGRunway& a )
|
||||
{
|
||||
string type;
|
||||
int tmp;
|
||||
|
||||
return in >> 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;
|
||||
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 {
|
||||
in >> a.id >> a.rwy_no >> a.lat >> a.lon >> a.heading
|
||||
>> a.length >> a.width >> a.surface_flags;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
FGRunways::FGRunways( const string& file ) {
|
||||
// open the specified database readonly
|
||||
storage = new c4_Storage( file.c_str(), false );
|
||||
FGRunwayList::FGRunwayList( const string& file ) {
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Reading runway list: " << file );
|
||||
|
||||
if ( !storage->Strategy().IsValid() ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
|
||||
// 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);
|
||||
}
|
||||
|
||||
vRunway = new c4_View;
|
||||
*vRunway =
|
||||
storage->GetAs("runway[ID:S,Rwy:S,Longitude:F,Latitude:F,Heading:F,Length:F,Width:F,SurfaceFlags:S,End1Flags:S,End2Flags:S]");
|
||||
// skip header line
|
||||
in >> skipeol;
|
||||
|
||||
next_index = 0;
|
||||
FGRunway rwy;
|
||||
while ( in ) {
|
||||
in >> rwy;
|
||||
runways.insert(pair<const string, FGRunway>(rwy.id, rwy));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,183 +125,74 @@ static string GetReverseRunwayNo(string rwyno) {
|
|||
}
|
||||
|
||||
|
||||
// search for the specified apt id
|
||||
bool FGRunways::search( const string& aptid, FGRunway* r ) {
|
||||
c4_StringProp pID ("ID");
|
||||
c4_StringProp pRwy ("Rwy");
|
||||
c4_FloatProp pLon ("Longitude");
|
||||
c4_FloatProp pLat ("Latitude");
|
||||
c4_FloatProp pHdg ("Heading");
|
||||
c4_FloatProp pLen ("Length");
|
||||
c4_FloatProp pWid ("Width");
|
||||
c4_StringProp pSurf ("SurfaceFlags");
|
||||
c4_StringProp pEnd1 ("End1Flags");
|
||||
c4_StringProp pEnd2 ("End2Flags");
|
||||
// search for the specified apt id (wierd!)
|
||||
bool FGRunwayList::search( const string& aptid, FGRunway* r ) {
|
||||
runway_map_iterator pos;
|
||||
|
||||
int index = vRunway->Find(pID[aptid.c_str()]);
|
||||
c4_RowRef row = vRunway->GetAt(index);
|
||||
|
||||
// cout << "index = " << index " row = " << row << endl;
|
||||
|
||||
// explicitly check if we got what we were asking for
|
||||
// because metakit is canse insensitive!
|
||||
if ( strcmp(aptid.c_str(), pID(row)) ) {
|
||||
return false;
|
||||
pos = runways.lower_bound(aptid);
|
||||
if ( pos != runways.end() ) {
|
||||
current = pos;
|
||||
*r = pos->second;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
next_index = index + 1;
|
||||
|
||||
r->id = (const char *) pID(row);
|
||||
r->rwy_no = (const char *) pRwy(row);
|
||||
r->lon = (double) pLon(row);
|
||||
r->lat = (double) pLat(row);
|
||||
r->heading = (double) pHdg(row);
|
||||
r->length = (double) pLen(row);
|
||||
r->width = (double) pWid(row);
|
||||
r->surface_flags = (const char *) pSurf(row);
|
||||
r->end1_flags = (const char *) pEnd1(row);
|
||||
r->end2_flags = (const char *) pEnd2(row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// search for the specified apt id and runway no
|
||||
bool FGRunways::search( const string& aptid, const string& rwyno, FGRunway* r )
|
||||
bool FGRunwayList::search( const string& aptid, const string& rwyno,
|
||||
FGRunway *r )
|
||||
{
|
||||
string runwayno = rwyno;
|
||||
c4_StringProp pID ("ID");
|
||||
c4_StringProp pRwy ("Rwy");
|
||||
c4_FloatProp pLon ("Longitude");
|
||||
c4_FloatProp pLat ("Latitude");
|
||||
c4_FloatProp pHdg ("Heading");
|
||||
c4_FloatProp pLen ("Length");
|
||||
c4_FloatProp pWid ("Width");
|
||||
c4_StringProp pSurf ("SurfaceFlags");
|
||||
c4_StringProp pEnd1 ("End1Flags");
|
||||
c4_StringProp pEnd2 ("End2Flags");
|
||||
|
||||
int index = vRunway->Find(pID[aptid.c_str()]);
|
||||
c4_RowRef row = vRunway->GetAt(index);
|
||||
// cout << "index = " << index " row = " << row << endl;
|
||||
|
||||
// explicitly check if we got what we were asking for
|
||||
// because metakit is canse insensitive!
|
||||
if ( strcmp(aptid.c_str(), pID(row)) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// standardize input number
|
||||
string runwayno = rwyno;
|
||||
string tmp = runwayno.substr(1, 1);
|
||||
if (( tmp == "L" || tmp == "R" || tmp == "C" ) || (runwayno.size() == 1)) {
|
||||
tmp = runwayno;
|
||||
runwayno = "0" + tmp;
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Standardising rwy number from " << tmp
|
||||
<< " to " << runwayno );
|
||||
SG_LOG( SG_GENERAL, SG_INFO,
|
||||
"Standardising rwy number from " << tmp << " to " << runwayno );
|
||||
}
|
||||
string revrwyno = GetReverseRunwayNo(runwayno);
|
||||
|
||||
string rowid = (const char *) pID(row);
|
||||
string rowrwyno = (const char *) pRwy(row);
|
||||
while ( rowid == aptid ) {
|
||||
next_index = index + 1;
|
||||
|
||||
if ( rowrwyno == runwayno ) {
|
||||
r->id = (const char *) pID(row);
|
||||
r->rwy_no = (const char *) pRwy(row);
|
||||
r->lon = (double) pLon(row);
|
||||
r->lat = (double) pLat(row);
|
||||
r->heading = (double) pHdg(row);
|
||||
r->length = (double) pLen(row);
|
||||
r->width = (double) pWid(row);
|
||||
r->surface_flags = (const char *) pSurf(row);
|
||||
r->end1_flags = (const char *) pEnd1(row);
|
||||
r->end2_flags = (const char *) pEnd2(row);
|
||||
|
||||
runway_map_iterator pos;
|
||||
for ( pos = runways.lower_bound( aptid );
|
||||
pos != runways.upper_bound( aptid ); ++pos)
|
||||
{
|
||||
if ( pos->second.rwy_no == runwayno ) {
|
||||
current = pos;
|
||||
*r = pos->second;
|
||||
return true;
|
||||
} 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
|
||||
current = pos;
|
||||
*r = pos->second;
|
||||
r->rwy_no = revrwyno;
|
||||
r->heading += 180.0;
|
||||
string tmp = r->end1_flags;
|
||||
r->end1_flags = r->end2_flags;
|
||||
r->end2_flags = tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Search again with the other-end runway number
|
||||
// Remember we have to munge the heading and rwy_no results if this one matches
|
||||
rowrwyno = GetReverseRunwayNo(rowrwyno);
|
||||
// cout << "New rowrwyno = " << rowrwyno << '\n';
|
||||
if ( rowrwyno == runwayno ) {
|
||||
r->id = (const char *) pID(row);
|
||||
r->rwy_no = rowrwyno;
|
||||
r->lon = (double) pLon(row);
|
||||
r->lat = (double) pLat(row);
|
||||
r->heading = (double) pHdg(row) + 180.0;
|
||||
r->length = (double) pLen(row);
|
||||
r->width = (double) pWid(row);
|
||||
r->surface_flags = (const char *) pSurf(row);
|
||||
r->end1_flags = (const char *) pEnd2(row);
|
||||
r->end2_flags = (const char *) pEnd1(row);
|
||||
// I've swapped the end flags as well
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
index++;
|
||||
row = vRunway->GetAt(index);
|
||||
rowid = (const char *) pID(row);
|
||||
rowrwyno = (const char *) pRwy(row);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
FGRunway FGRunways::search( const string& aptid ) {
|
||||
// (wierd!)
|
||||
FGRunway FGRunwayList::search( const string& aptid ) {
|
||||
FGRunway a;
|
||||
search( aptid, &a );
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
// search for the specified id
|
||||
bool FGRunways::next( FGRunway* r ) {
|
||||
c4_StringProp pID ("ID");
|
||||
c4_StringProp pRwy ("Rwy");
|
||||
c4_FloatProp pLon ("Longitude");
|
||||
c4_FloatProp pLat ("Latitude");
|
||||
c4_FloatProp pHdg ("Heading");
|
||||
c4_FloatProp pLen ("Length");
|
||||
c4_FloatProp pWid ("Width");
|
||||
c4_StringProp pSurf ("SurfaceFlags");
|
||||
c4_StringProp pEnd1 ("End1Flags");
|
||||
c4_StringProp pEnd2 ("End2Flags");
|
||||
|
||||
int size = vRunway->GetSize();
|
||||
// cout << "total records = " << size << endl;
|
||||
|
||||
int index = next_index;
|
||||
// cout << "index = " << index << endl;
|
||||
|
||||
if ( index == -1 || index >= size ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
next_index = index + 1;
|
||||
|
||||
c4_RowRef row = vRunway->GetAt(index);
|
||||
|
||||
r->id = (const char *) pID(row);
|
||||
r->rwy_no = (const char *) pRwy(row);
|
||||
r->lon = (double) pLon(row);
|
||||
r->lat = (double) pLat(row);
|
||||
r->heading = (double) pHdg(row);
|
||||
r->length = (double) pLen(row);
|
||||
r->width = (double) pWid(row);
|
||||
r->surface_flags = (const char *) pSurf(row);
|
||||
r->end1_flags = (const char *) pEnd1(row);
|
||||
r->end2_flags = (const char *) pEnd2(row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Return the runway closest to a given heading
|
||||
bool FGRunways::search( const string& aptid, const int tgt_hdg,
|
||||
FGRunway* runway )
|
||||
bool FGRunwayList::search( const string& aptid, const int tgt_hdg,
|
||||
FGRunway *runway )
|
||||
{
|
||||
string rwyNo = search(aptid, tgt_hdg);
|
||||
return(rwyNo == "NN" ? false : search(aptid, rwyNo, runway));
|
||||
|
@ -315,7 +200,7 @@ bool FGRunways::search( const string& aptid, const int tgt_hdg,
|
|||
|
||||
|
||||
// Return the runway number of the runway closest to a given heading
|
||||
string FGRunways::search( const string& aptid, const int tgt_hdg ) {
|
||||
string FGRunwayList::search( const string& aptid, const int tgt_hdg ) {
|
||||
FGRunway r;
|
||||
FGRunway tmp_r;
|
||||
string rn;
|
||||
|
@ -378,160 +263,29 @@ string FGRunways::search( const string& aptid, const int tgt_hdg ) {
|
|||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
FGRunways::~FGRunways( void ) {
|
||||
delete storage;
|
||||
}
|
||||
|
||||
|
||||
// Constructor
|
||||
FGRunwaysUtil::FGRunwaysUtil() {
|
||||
}
|
||||
|
||||
|
||||
// load the data
|
||||
int FGRunwaysUtil::load( const string& file ) {
|
||||
FGRunway r;
|
||||
string apt_id;
|
||||
|
||||
runways.erase( runways.begin(), runways.end() );
|
||||
|
||||
sg_gzifstream in( file );
|
||||
if ( !in.is_open() ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// skip first line of file
|
||||
char tmp[2048];
|
||||
in.getline( tmp, 2048 );
|
||||
|
||||
// read in each line of the file
|
||||
|
||||
#ifdef __MWERKS__
|
||||
|
||||
in >> ::skipws;
|
||||
char c = 0;
|
||||
while ( in.get(c) && c != '\0' ) {
|
||||
if ( c == 'A' ) {
|
||||
in >> apt_id;
|
||||
in >> skipeol;
|
||||
} else if ( c == 'R' ) {
|
||||
in >> r;
|
||||
r.id = apt_id;
|
||||
runways.push_back(r);
|
||||
} else {
|
||||
in >> skipeol;
|
||||
}
|
||||
in >> ::skipws;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
in >> ::skipws;
|
||||
while ( ! in.eof() ) {
|
||||
char c = 0;
|
||||
in.get(c);
|
||||
if ( c == 'A' ) {
|
||||
in >> apt_id;
|
||||
in >> skipeol;
|
||||
} else if ( c == 'R' ) {
|
||||
in >> r;
|
||||
r.id = apt_id;
|
||||
// cout << apt_id << " " << r.rwy_no << endl;
|
||||
runways.push_back(r);
|
||||
} else {
|
||||
in >> skipeol;
|
||||
}
|
||||
in >> ::skipws;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// save the data in gdbm format
|
||||
bool FGRunwaysUtil::dump_mk4( const string& file ) {
|
||||
// open database for writing
|
||||
c4_Storage storage( file.c_str(), true );
|
||||
|
||||
// need to do something about error handling here!
|
||||
|
||||
// define the properties
|
||||
c4_StringProp pID ("ID");
|
||||
c4_StringProp pRwy ("Rwy");
|
||||
c4_FloatProp pLon ("Longitude");
|
||||
c4_FloatProp pLat ("Latitude");
|
||||
c4_FloatProp pHdg ("Heading");
|
||||
c4_FloatProp pLen ("Length");
|
||||
c4_FloatProp pWid ("Width");
|
||||
c4_StringProp pSurf ("SurfaceFlags");
|
||||
c4_StringProp pEnd1 ("End1Flags");
|
||||
c4_StringProp pEnd2 ("End2Flags");
|
||||
|
||||
// Start with an empty view of the proper structure.
|
||||
c4_View vRunway =
|
||||
storage.GetAs("runway[ID:S,Rwy:S,Longitude:F,Latitude:F,Heading:F,Length:F,Width:F,SurfaceFlags:S,End1Flags:S,End2Flags:S]");
|
||||
|
||||
c4_Row row;
|
||||
|
||||
iterator current = runways.begin();
|
||||
const_iterator end = runways.end();
|
||||
while ( current != end ) {
|
||||
// add each runway record
|
||||
pID (row) = current->id.c_str();
|
||||
pRwy (row) = current->rwy_no.c_str();
|
||||
pLon (row) = current->lon;
|
||||
pLat (row) = current->lat;
|
||||
pHdg (row) = current->heading;
|
||||
pLen (row) = current->length;
|
||||
pWid (row) = current->width;
|
||||
pSurf (row) = current->surface_flags.c_str();
|
||||
pEnd1 (row) = current->end1_flags.c_str();
|
||||
pEnd2 (row) = current->end2_flags.c_str();
|
||||
vRunway.Add(row);
|
||||
|
||||
++current;
|
||||
}
|
||||
|
||||
// commit our changes
|
||||
storage.Commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// search for the specified id
|
||||
bool
|
||||
FGRunwaysUtil::search( const string& id, FGRunway* a ) const
|
||||
{
|
||||
const_iterator it = runways.find( FGRunway(id) );
|
||||
if ( it != runways.end() )
|
||||
{
|
||||
*a = *it;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
bool FGRunwayList::next( FGRunway* runway ) {
|
||||
++current;
|
||||
if ( current != runways.end() ) {
|
||||
*runway = current->second;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FGRunway
|
||||
FGRunwaysUtil::search( const string& id ) const
|
||||
{
|
||||
FGRunway a;
|
||||
this->search( id, &a );
|
||||
return a;
|
||||
FGRunway FGRunwayList::next() {
|
||||
FGRunway result;
|
||||
|
||||
++current;
|
||||
if ( current != runways.end() ) {
|
||||
result = current->second;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Destructor
|
||||
FGRunwaysUtil::~FGRunwaysUtil( void ) {
|
||||
FGRunwayList::~FGRunwayList( void ) {
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
// $Id$
|
||||
|
||||
|
||||
#ifndef _RUNWAYS_HXX
|
||||
#define _RUNWAYS_HXX
|
||||
#ifndef _FG_RUNWAYS_HXX
|
||||
#define _FG_RUNWAYS_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
@ -37,20 +37,22 @@
|
|||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
// Forward declarations.
|
||||
class c4_Storage;
|
||||
class c4_View;
|
||||
#include <map>
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(multimap);
|
||||
|
||||
|
||||
class FGRunway {
|
||||
struct ltstr {
|
||||
bool operator()(const string s1, const string s2) const {
|
||||
return s1 < s2;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
struct FGRunway {
|
||||
|
||||
string type;
|
||||
string id;
|
||||
string rwy_no;
|
||||
|
||||
|
@ -64,28 +66,32 @@ public:
|
|||
string end1_flags;
|
||||
string end2_flags;
|
||||
|
||||
public:
|
||||
double end1_displaced_threshold;
|
||||
double end2_displaced_threshold;
|
||||
|
||||
FGRunway() {}
|
||||
~FGRunway() {}
|
||||
double end1_stopway;
|
||||
double end2_stopway;
|
||||
|
||||
};
|
||||
|
||||
class FGRunways {
|
||||
typedef multimap < string, FGRunway, ltstr > runway_map;
|
||||
typedef runway_map::iterator runway_map_iterator;
|
||||
typedef runway_map::const_iterator const_runway_map_iterator;
|
||||
|
||||
class FGRunwayList {
|
||||
|
||||
private:
|
||||
|
||||
c4_Storage *storage;
|
||||
c4_View *vRunway;
|
||||
int next_index;
|
||||
runway_map runways;
|
||||
runway_map_iterator current;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
FGRunways( const string& file );
|
||||
FGRunwayList( const string& file );
|
||||
|
||||
// Destructor
|
||||
~FGRunways();
|
||||
~FGRunwayList();
|
||||
|
||||
// search for the specified apt id.
|
||||
// Returns true if successful, otherwise returns false.
|
||||
|
@ -106,36 +112,4 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class FGRunwaysUtil {
|
||||
public:
|
||||
typedef vector< FGRunway > container;
|
||||
typedef container::iterator iterator;
|
||||
typedef container::const_iterator const_iterator;
|
||||
|
||||
private:
|
||||
container runways;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
FGRunwaysUtil();
|
||||
|
||||
// Destructor
|
||||
~FGRunwaysUtil();
|
||||
|
||||
// load the data
|
||||
int load( const string& file );
|
||||
|
||||
// save the data in metakit format
|
||||
bool dump_mk4( const string& file );
|
||||
|
||||
// search for the specified id.
|
||||
// Returns true if successful, otherwise returns false.
|
||||
// On success, runway data is returned thru "runway" pointer.
|
||||
// "runway" is not changed if "id" is not found.
|
||||
// bool search( const string& id, FGRunway* runway ) const;
|
||||
// FGRunway search( const string& id ) const;
|
||||
};
|
||||
|
||||
|
||||
#endif // _RUNWAYS_HXX
|
||||
#endif // _FG_RUNWAYS_HXX
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include <simgear/misc/sgstream.hxx>
|
||||
|
||||
#include STL_STRING
|
||||
#include STL_FUNCTIONAL
|
||||
#include STL_ALGORITHM
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#include "simple.hxx"
|
||||
|
@ -71,8 +69,8 @@ FGAirportList::FGAirportList( const string& file ) {
|
|||
// skip header line
|
||||
in >> skipeol;
|
||||
|
||||
FGAirport a;
|
||||
while ( in ) {
|
||||
FGAirport a;
|
||||
in >> a;
|
||||
airports[a.id] = a;
|
||||
}
|
||||
|
|
|
@ -45,9 +45,7 @@ SG_USING_STD(string);
|
|||
SG_USING_STD(map);
|
||||
|
||||
|
||||
class FGAirport {
|
||||
|
||||
public:
|
||||
struct FGAirport {
|
||||
|
||||
string id;
|
||||
double longitude;
|
||||
|
@ -56,18 +54,6 @@ public:
|
|||
string code;
|
||||
string name;
|
||||
|
||||
public:
|
||||
|
||||
FGAirport( const string& name = "",
|
||||
double lon = 0.0,
|
||||
double lat = 0.0,
|
||||
double ele = 0.0 )
|
||||
: id(name), longitude(lon), latitude(lat), elevation(ele) {}
|
||||
|
||||
bool operator < ( const FGAirport& a ) const {
|
||||
return id < a.id;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef map < string, FGAirport > airport_map;
|
||||
|
|
|
@ -564,7 +564,7 @@ bool fgFindAirportID( const string& id, FGAirport *a ) {
|
|||
|
||||
if ( result.id.empty() ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||
"Failed to find " << id << " in simple.apt.gz" );
|
||||
"Failed to find " << id << " in basic.dat.gz" );
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -656,16 +656,11 @@ static bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
|
|||
if ( id.length() ) {
|
||||
// set initial position from runway and heading
|
||||
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "Airports" );
|
||||
path.append( "runways.mk4" );
|
||||
FGRunways runways( path.c_str() );
|
||||
|
||||
SG_LOG( SG_GENERAL, SG_INFO,
|
||||
"Attempting to set starting position from airport code "
|
||||
<< id << " heading " << tgt_hdg );
|
||||
|
||||
if ( ! runways.search( id, (int)tgt_hdg, &r ) ) {
|
||||
if ( ! globals->get_runways()->search( id, (int)tgt_hdg, &r ) ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||
"Failed to find a good runway for " << id << '\n' );
|
||||
return false;
|
||||
|
@ -730,16 +725,11 @@ static bool fgSetPosFromAirportIDandRwy( const string& id, const string& rwy ) {
|
|||
if ( id.length() ) {
|
||||
// set initial position from airport and runway number
|
||||
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "Airports" );
|
||||
path.append( "runways.mk4" );
|
||||
FGRunways runways( path.c_str() );
|
||||
|
||||
SG_LOG( SG_GENERAL, SG_INFO,
|
||||
"Attempting to set starting position for "
|
||||
<< id << ":" << rwy );
|
||||
|
||||
if ( ! runways.search( id, rwy, &r ) ) {
|
||||
if ( ! globals->get_runways()->search( id, rwy, &r ) ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||
"Failed to find runway " << rwy <<
|
||||
" at airport " << id );
|
||||
|
@ -951,10 +941,16 @@ fgInitNav ()
|
|||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Loading Simple Airport List");
|
||||
SGPath p_simple( globals->get_fg_root() );
|
||||
p_simple.append( "Airports/simple.apt" );
|
||||
p_simple.append( "Airports/basic.dat" );
|
||||
FGAirportList *airports = new FGAirportList( p_simple.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() );
|
||||
globals->set_runways( runways );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Loading Navaids");
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, " VOR/NDB");
|
||||
|
|
|
@ -60,6 +60,7 @@ class SGTime;
|
|||
class SGSoundMgr;
|
||||
|
||||
class FGAirportList;
|
||||
class FGRunwayList;
|
||||
class FGAIMgr;
|
||||
class FGATCMgr;
|
||||
class FGATCDisplay;
|
||||
|
@ -138,6 +139,9 @@ private:
|
|||
// Simple Airport List
|
||||
FGAirportList *airports;
|
||||
|
||||
// Runway List
|
||||
FGRunwayList *runways;
|
||||
|
||||
// ATC manager
|
||||
FGATCMgr *ATC_mgr;
|
||||
|
||||
|
@ -247,6 +251,9 @@ public:
|
|||
inline FGAirportList *get_airports() const { return airports; }
|
||||
inline void set_airports( FGAirportList *a ) {airports = a; }
|
||||
|
||||
inline FGRunwayList *get_runways() const { return runways; }
|
||||
inline void set_runways( FGRunwayList *r ) {runways = r; }
|
||||
|
||||
inline FGATCMgr *get_ATC_mgr() const { return ATC_mgr; }
|
||||
inline void set_ATC_mgr( FGATCMgr *a ) {ATC_mgr = a; }
|
||||
|
||||
|
|
Loading…
Reference in a new issue