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
|
// 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;
|
FGRunway runway;
|
||||||
bool rwyGood = runways.search(airportID, rwy.rwyID, &runway);
|
bool rwyGood = globals->get_runways()->search(airportID, rwy.rwyID,
|
||||||
|
&runway);
|
||||||
if(rwyGood) {
|
if(rwyGood) {
|
||||||
// Get the threshold position
|
// Get the threshold position
|
||||||
hdg = runway.heading; // TODO - check - is this our heading we are setting here, and if so should we be?
|
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 );
|
result = globals->get_airports()->search( id );
|
||||||
if ( result.id.empty() ) {
|
if ( result.id.empty() ) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
"Failed to find " << id << " in simple.apt.gz" );
|
"Failed to find " << id << " in basic.dat.gz" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -544,11 +544,6 @@ void FGApproach::get_active_runway() {
|
||||||
->getEnvironment(lat, lon, elev);
|
->getEnvironment(lat, lon, elev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SGPath path( globals->get_fg_root() );
|
|
||||||
path.append( "Airports" );
|
|
||||||
path.append( "runways.mk4" );
|
|
||||||
FGRunways runways( path.c_str() );
|
|
||||||
|
|
||||||
#ifdef FG_WEATHERCM
|
#ifdef FG_WEATHERCM
|
||||||
//Set the heading to into the wind
|
//Set the heading to into the wind
|
||||||
double wind_x = stationweather.Wind[0];
|
double wind_x = stationweather.Wind[0];
|
||||||
|
@ -573,7 +568,7 @@ void FGApproach::get_active_runway() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FGRunway runway;
|
FGRunway runway;
|
||||||
if ( runways.search( ident, int(hdg), &runway) ) {
|
if ( globals->get_runways()->search( ident, int(hdg), &runway) ) {
|
||||||
active_runway = runway.rwy_no;
|
active_runway = runway.rwy_no;
|
||||||
active_rw_hdg = runway.heading;
|
active_rw_hdg = runway.heading;
|
||||||
active_rw_lon = runway.lon;
|
active_rw_lon = runway.lon;
|
||||||
|
|
|
@ -214,11 +214,7 @@ void FGATIS::UpdateTransmission() {
|
||||||
|
|
||||||
// Based on the airport-id and wind get the active runway
|
// Based on the airport-id and wind get the active runway
|
||||||
//FGRunway *r;
|
//FGRunway *r;
|
||||||
SGPath path( globals->get_fg_root() );
|
|
||||||
path.append( "Airports" );
|
|
||||||
path.append( "runways.mk4" );
|
|
||||||
FGRunways runways( path.c_str() );
|
|
||||||
|
|
||||||
#ifdef FG_WEATHERCM
|
#ifdef FG_WEATHERCM
|
||||||
//Set the heading to into the wind
|
//Set the heading to into the wind
|
||||||
double wind_x = stationweather.Wind[0];
|
double wind_x = stationweather.Wind[0];
|
||||||
|
@ -269,7 +265,7 @@ void FGATIS::UpdateTransmission() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string rwy_no = runways.search(ident, int(hdg));
|
string rwy_no = globals->get_runways()->search(ident, int(hdg));
|
||||||
if(rwy_no != (string)"NN") {
|
if(rwy_no != (string)"NN") {
|
||||||
transmission += " / Landing_and_departing_runway ";
|
transmission += " / Landing_and_departing_runway ";
|
||||||
transmission += ConvertRwyNumToSpokenString(atoi(rwy_no.c_str()));
|
transmission += ConvertRwyNumToSpokenString(atoi(rwy_no.c_str()));
|
||||||
|
|
|
@ -356,10 +356,6 @@ void FGGround::DoRwyDetails() {
|
||||||
//cout << "GetRwyDetails called" << endl;
|
//cout << "GetRwyDetails called" << endl;
|
||||||
|
|
||||||
// Based on the airport-id and wind get the active runway
|
// 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
|
//wind
|
||||||
double hdg = wind_from_hdg->getDoubleValue();
|
double hdg = wind_from_hdg->getDoubleValue();
|
||||||
|
@ -368,7 +364,7 @@ void FGGround::DoRwyDetails() {
|
||||||
//cout << "Heading = " << hdg << '\n';
|
//cout << "Heading = " << hdg << '\n';
|
||||||
|
|
||||||
FGRunway runway;
|
FGRunway runway;
|
||||||
bool rwyGood = r_ways.search(ident, int(hdg), &runway);
|
bool rwyGood = globals->get_runways()->search(ident, int(hdg), &runway);
|
||||||
if(rwyGood) {
|
if(rwyGood) {
|
||||||
activeRwy = runway.rwy_no;
|
activeRwy = runway.rwy_no;
|
||||||
rwy.rwyID = runway.rwy_no;
|
rwy.rwyID = runway.rwy_no;
|
||||||
|
|
|
@ -524,10 +524,6 @@ void FGTower::DoRwyDetails() {
|
||||||
//cout << "GetRwyDetails called" << endl;
|
//cout << "GetRwyDetails called" << endl;
|
||||||
|
|
||||||
// Based on the airport-id and wind get the active runway
|
// 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
|
//wind
|
||||||
double hdg = wind_from_hdg->getDoubleValue();
|
double hdg = wind_from_hdg->getDoubleValue();
|
||||||
|
@ -536,7 +532,7 @@ void FGTower::DoRwyDetails() {
|
||||||
//cout << "Heading = " << hdg << '\n';
|
//cout << "Heading = " << hdg << '\n';
|
||||||
|
|
||||||
FGRunway runway;
|
FGRunway runway;
|
||||||
bool rwyGood = runways.search(ident, int(hdg), &runway);
|
bool rwyGood = globals->get_runways()->search(ident, int(hdg), &runway);
|
||||||
if(rwyGood) {
|
if(rwyGood) {
|
||||||
activeRwy = runway.rwy_no;
|
activeRwy = runway.rwy_no;
|
||||||
rwy.rwyID = runway.rwy_no;
|
rwy.rwyID = runway.rwy_no;
|
||||||
|
@ -605,16 +601,12 @@ bool FGTower::OnAnyRunway(Point3D pt) {
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
// Based on the airport-id, go through all the runways and check for a point in them
|
// 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
|
// TODO - do we actually need to search for the airport - surely we already know our ident and
|
||||||
// can just search runways of our airport???
|
// can just search runways of our airport???
|
||||||
//cout << "Airport ident is " << ad.ident << '\n';
|
//cout << "Airport ident is " << ad.ident << '\n';
|
||||||
FGRunway runway;
|
FGRunway runway;
|
||||||
bool rwyGood = runways.search(ad.ident, &runway);
|
bool rwyGood = globals->get_runways()->search(ad.ident, &runway);
|
||||||
if(!rwyGood) {
|
if(!rwyGood) {
|
||||||
SG_LOG(SG_ATC, SG_WARN, "Unable to find any runways for airport ID " << ad.ident << " in FGTower");
|
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);
|
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);
|
if(on) return(true);
|
||||||
runways.next(&runway);
|
globals->get_runways()->next(&runway);
|
||||||
}
|
}
|
||||||
return(on);
|
return(on);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
noinst_LIBRARIES = libAirports.a
|
noinst_LIBRARIES = libAirports.a
|
||||||
|
|
||||||
noinst_PROGRAMS = genrunways calc_loc
|
noinst_PROGRAMS = calc_loc
|
||||||
|
|
||||||
libAirports_a_SOURCES = \
|
libAirports_a_SOURCES = \
|
||||||
runways.cxx runways.hxx \
|
runways.cxx runways.hxx \
|
||||||
simple.cxx simple.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_SOURCES = calc_loc.cxx
|
||||||
calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lz
|
calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lz
|
||||||
|
|
||||||
|
|
|
@ -34,59 +34,53 @@
|
||||||
#include <simgear/misc/sgstream.hxx>
|
#include <simgear/misc/sgstream.hxx>
|
||||||
|
|
||||||
#include STL_STRING
|
#include STL_STRING
|
||||||
#include STL_FUNCTIONAL
|
#include STL_IOSTREAM
|
||||||
#include STL_ALGORITHM
|
#include <map>
|
||||||
|
|
||||||
#include "runways.hxx"
|
#include "runways.hxx"
|
||||||
|
|
||||||
SG_USING_NAMESPACE(std);
|
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(istream);
|
||||||
|
SG_USING_STD(multimap);
|
||||||
|
|
||||||
inline istream&
|
inline istream&
|
||||||
operator >> ( istream& in, FGRunway& a )
|
operator >> ( istream& in, FGRunway& a )
|
||||||
{
|
{
|
||||||
|
string type;
|
||||||
int tmp;
|
int tmp;
|
||||||
|
|
||||||
return in >> a.rwy_no >> a.lat >> a.lon >> a.heading >> a.length >> a.width
|
in >> a.type;
|
||||||
>> a.surface_flags >> a.end1_flags >> tmp >> tmp >> a.end2_flags
|
if ( a.type == "R" ) {
|
||||||
>> tmp >> tmp;
|
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 ) {
|
FGRunwayList::FGRunwayList( const string& file ) {
|
||||||
// open the specified database readonly
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Reading runway list: " << file );
|
||||||
storage = new c4_Storage( file.c_str(), false );
|
|
||||||
|
|
||||||
if ( !storage->Strategy().IsValid() ) {
|
// open the specified file for reading
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
|
sg_gzifstream in( file );
|
||||||
|
if ( !in.is_open() ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
vRunway = new c4_View;
|
// skip header line
|
||||||
*vRunway =
|
in >> skipeol;
|
||||||
storage->GetAs("runway[ID:S,Rwy:S,Longitude:F,Latitude:F,Heading:F,Length:F,Width:F,SurfaceFlags:S,End1Flags:S,End2Flags:S]");
|
|
||||||
|
|
||||||
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
|
// search for the specified apt id (wierd!)
|
||||||
bool FGRunways::search( const string& aptid, FGRunway* r ) {
|
bool FGRunwayList::search( const string& aptid, FGRunway* r ) {
|
||||||
c4_StringProp pID ("ID");
|
runway_map_iterator pos;
|
||||||
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()]);
|
pos = runways.lower_bound(aptid);
|
||||||
c4_RowRef row = vRunway->GetAt(index);
|
if ( pos != runways.end() ) {
|
||||||
|
current = pos;
|
||||||
// cout << "index = " << index " row = " << row << endl;
|
*r = pos->second;
|
||||||
|
return true;
|
||||||
// explicitly check if we got what we were asking for
|
} else {
|
||||||
// because metakit is canse insensitive!
|
return false;
|
||||||
if ( strcmp(aptid.c_str(), pID(row)) ) {
|
|
||||||
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
|
// 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
|
// standardize input number
|
||||||
|
string runwayno = rwyno;
|
||||||
string tmp = runwayno.substr(1, 1);
|
string tmp = runwayno.substr(1, 1);
|
||||||
if (( tmp == "L" || tmp == "R" || tmp == "C" ) || (runwayno.size() == 1)) {
|
if (( tmp == "L" || tmp == "R" || tmp == "C" ) || (runwayno.size() == 1)) {
|
||||||
tmp = runwayno;
|
tmp = runwayno;
|
||||||
runwayno = "0" + tmp;
|
runwayno = "0" + tmp;
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Standardising rwy number from " << tmp
|
SG_LOG( SG_GENERAL, SG_INFO,
|
||||||
<< " to " << runwayno );
|
"Standardising rwy number from " << tmp << " to " << runwayno );
|
||||||
}
|
}
|
||||||
|
string revrwyno = GetReverseRunwayNo(runwayno);
|
||||||
|
|
||||||
string rowid = (const char *) pID(row);
|
runway_map_iterator pos;
|
||||||
string rowrwyno = (const char *) pRwy(row);
|
for ( pos = runways.lower_bound( aptid );
|
||||||
while ( rowid == aptid ) {
|
pos != runways.upper_bound( aptid ); ++pos)
|
||||||
next_index = index + 1;
|
{
|
||||||
|
if ( pos->second.rwy_no == runwayno ) {
|
||||||
if ( rowrwyno == runwayno ) {
|
current = pos;
|
||||||
r->id = (const char *) pID(row);
|
*r = pos->second;
|
||||||
r->rwy_no = (const char *) pRwy(row);
|
return true;
|
||||||
r->lon = (double) pLon(row);
|
} else if ( pos->second.rwy_no == revrwyno ) {
|
||||||
r->lat = (double) pLat(row);
|
// Search again with the other-end runway number.
|
||||||
r->heading = (double) pHdg(row);
|
// Remember we have to munge the heading and rwy_no
|
||||||
r->length = (double) pLen(row);
|
// results if this one matches
|
||||||
r->width = (double) pWid(row);
|
current = pos;
|
||||||
r->surface_flags = (const char *) pSurf(row);
|
*r = pos->second;
|
||||||
r->end1_flags = (const char *) pEnd1(row);
|
r->rwy_no = revrwyno;
|
||||||
r->end2_flags = (const char *) pEnd2(row);
|
r->heading += 180.0;
|
||||||
|
string tmp = r->end1_flags;
|
||||||
|
r->end1_flags = r->end2_flags;
|
||||||
|
r->end2_flags = tmp;
|
||||||
return true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FGRunway FGRunways::search( const string& aptid ) {
|
// (wierd!)
|
||||||
|
FGRunway FGRunwayList::search( const string& aptid ) {
|
||||||
FGRunway a;
|
FGRunway a;
|
||||||
search( aptid, &a );
|
search( aptid, &a );
|
||||||
return 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
|
// Return the runway closest to a given heading
|
||||||
bool FGRunways::search( const string& aptid, const int tgt_hdg,
|
bool FGRunwayList::search( const string& aptid, const int tgt_hdg,
|
||||||
FGRunway* runway )
|
FGRunway *runway )
|
||||||
{
|
{
|
||||||
string rwyNo = search(aptid, tgt_hdg);
|
string rwyNo = search(aptid, tgt_hdg);
|
||||||
return(rwyNo == "NN" ? false : search(aptid, rwyNo, runway));
|
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
|
// 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 r;
|
||||||
FGRunway tmp_r;
|
FGRunway tmp_r;
|
||||||
string rn;
|
string rn;
|
||||||
|
@ -378,160 +263,29 @@ string FGRunways::search( const string& aptid, const int tgt_hdg ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
bool FGRunwayList::next( FGRunway* runway ) {
|
||||||
FGRunways::~FGRunways( void ) {
|
++current;
|
||||||
delete storage;
|
if ( current != runways.end() ) {
|
||||||
}
|
*runway = current->second;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
// Constructor
|
return false;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FGRunway
|
FGRunway FGRunwayList::next() {
|
||||||
FGRunwaysUtil::search( const string& id ) const
|
FGRunway result;
|
||||||
{
|
|
||||||
FGRunway a;
|
++current;
|
||||||
this->search( id, &a );
|
if ( current != runways.end() ) {
|
||||||
return a;
|
result = current->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
FGRunwaysUtil::~FGRunwaysUtil( void ) {
|
FGRunwayList::~FGRunwayList( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
|
|
||||||
|
|
||||||
#ifndef _RUNWAYS_HXX
|
#ifndef _FG_RUNWAYS_HXX
|
||||||
#define _RUNWAYS_HXX
|
#define _FG_RUNWAYS_HXX
|
||||||
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
|
@ -37,20 +37,22 @@
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
#include STL_STRING
|
#include STL_STRING
|
||||||
#include <vector>
|
#include <map>
|
||||||
|
|
||||||
// Forward declarations.
|
|
||||||
class c4_Storage;
|
|
||||||
class c4_View;
|
|
||||||
|
|
||||||
SG_USING_STD(string);
|
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 id;
|
||||||
string rwy_no;
|
string rwy_no;
|
||||||
|
|
||||||
|
@ -64,28 +66,32 @@ public:
|
||||||
string end1_flags;
|
string end1_flags;
|
||||||
string end2_flags;
|
string end2_flags;
|
||||||
|
|
||||||
public:
|
double end1_displaced_threshold;
|
||||||
|
double end2_displaced_threshold;
|
||||||
|
|
||||||
FGRunway() {}
|
double end1_stopway;
|
||||||
~FGRunway() {}
|
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:
|
private:
|
||||||
|
|
||||||
c4_Storage *storage;
|
runway_map runways;
|
||||||
c4_View *vRunway;
|
runway_map_iterator current;
|
||||||
int next_index;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
FGRunways( const string& file );
|
FGRunwayList( const string& file );
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~FGRunways();
|
~FGRunwayList();
|
||||||
|
|
||||||
// search for the specified apt id.
|
// search for the specified apt id.
|
||||||
// Returns true if successful, otherwise returns false.
|
// Returns true if successful, otherwise returns false.
|
||||||
|
@ -106,36 +112,4 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class FGRunwaysUtil {
|
#endif // _FG_RUNWAYS_HXX
|
||||||
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
|
|
||||||
|
|
|
@ -33,8 +33,6 @@
|
||||||
#include <simgear/misc/sgstream.hxx>
|
#include <simgear/misc/sgstream.hxx>
|
||||||
|
|
||||||
#include STL_STRING
|
#include STL_STRING
|
||||||
#include STL_FUNCTIONAL
|
|
||||||
#include STL_ALGORITHM
|
|
||||||
#include STL_IOSTREAM
|
#include STL_IOSTREAM
|
||||||
|
|
||||||
#include "simple.hxx"
|
#include "simple.hxx"
|
||||||
|
@ -71,8 +69,8 @@ FGAirportList::FGAirportList( const string& file ) {
|
||||||
// skip header line
|
// skip header line
|
||||||
in >> skipeol;
|
in >> skipeol;
|
||||||
|
|
||||||
|
FGAirport a;
|
||||||
while ( in ) {
|
while ( in ) {
|
||||||
FGAirport a;
|
|
||||||
in >> a;
|
in >> a;
|
||||||
airports[a.id] = a;
|
airports[a.id] = a;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,7 @@ SG_USING_STD(string);
|
||||||
SG_USING_STD(map);
|
SG_USING_STD(map);
|
||||||
|
|
||||||
|
|
||||||
class FGAirport {
|
struct FGAirport {
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
string id;
|
string id;
|
||||||
double longitude;
|
double longitude;
|
||||||
|
@ -56,18 +54,6 @@ public:
|
||||||
string code;
|
string code;
|
||||||
string name;
|
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;
|
typedef map < string, FGAirport > airport_map;
|
||||||
|
|
|
@ -564,7 +564,7 @@ bool fgFindAirportID( const string& id, FGAirport *a ) {
|
||||||
|
|
||||||
if ( result.id.empty() ) {
|
if ( result.id.empty() ) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
"Failed to find " << id << " in simple.apt.gz" );
|
"Failed to find " << id << " in basic.dat.gz" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -656,16 +656,11 @@ static bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
|
||||||
if ( id.length() ) {
|
if ( id.length() ) {
|
||||||
// set initial position from runway and heading
|
// 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,
|
SG_LOG( SG_GENERAL, SG_INFO,
|
||||||
"Attempting to set starting position from airport code "
|
"Attempting to set starting position from airport code "
|
||||||
<< id << " heading " << tgt_hdg );
|
<< 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,
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
"Failed to find a good runway for " << id << '\n' );
|
"Failed to find a good runway for " << id << '\n' );
|
||||||
return false;
|
return false;
|
||||||
|
@ -730,16 +725,11 @@ static bool fgSetPosFromAirportIDandRwy( const string& id, const string& rwy ) {
|
||||||
if ( id.length() ) {
|
if ( id.length() ) {
|
||||||
// set initial position from airport and runway number
|
// 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,
|
SG_LOG( SG_GENERAL, SG_INFO,
|
||||||
"Attempting to set starting position for "
|
"Attempting to set starting position for "
|
||||||
<< id << ":" << rwy );
|
<< id << ":" << rwy );
|
||||||
|
|
||||||
if ( ! runways.search( id, rwy, &r ) ) {
|
if ( ! globals->get_runways()->search( id, rwy, &r ) ) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
"Failed to find runway " << rwy <<
|
"Failed to find runway " << rwy <<
|
||||||
" at airport " << id );
|
" at airport " << id );
|
||||||
|
@ -951,10 +941,16 @@ fgInitNav ()
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Loading Simple Airport List");
|
SG_LOG(SG_GENERAL, SG_INFO, "Loading Simple Airport List");
|
||||||
SGPath p_simple( globals->get_fg_root() );
|
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() );
|
FGAirportList *airports = new FGAirportList( p_simple.str() );
|
||||||
globals->set_airports( airports );
|
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, "Loading Navaids");
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, " VOR/NDB");
|
SG_LOG(SG_GENERAL, SG_INFO, " VOR/NDB");
|
||||||
|
|
|
@ -60,6 +60,7 @@ class SGTime;
|
||||||
class SGSoundMgr;
|
class SGSoundMgr;
|
||||||
|
|
||||||
class FGAirportList;
|
class FGAirportList;
|
||||||
|
class FGRunwayList;
|
||||||
class FGAIMgr;
|
class FGAIMgr;
|
||||||
class FGATCMgr;
|
class FGATCMgr;
|
||||||
class FGATCDisplay;
|
class FGATCDisplay;
|
||||||
|
@ -138,6 +139,9 @@ private:
|
||||||
// Simple Airport List
|
// Simple Airport List
|
||||||
FGAirportList *airports;
|
FGAirportList *airports;
|
||||||
|
|
||||||
|
// Runway List
|
||||||
|
FGRunwayList *runways;
|
||||||
|
|
||||||
// ATC manager
|
// ATC manager
|
||||||
FGATCMgr *ATC_mgr;
|
FGATCMgr *ATC_mgr;
|
||||||
|
|
||||||
|
@ -247,6 +251,9 @@ public:
|
||||||
inline FGAirportList *get_airports() const { return airports; }
|
inline FGAirportList *get_airports() const { return airports; }
|
||||||
inline void set_airports( FGAirportList *a ) {airports = a; }
|
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 FGATCMgr *get_ATC_mgr() const { return ATC_mgr; }
|
||||||
inline void set_ATC_mgr( FGATCMgr *a ) {ATC_mgr = a; }
|
inline void set_ATC_mgr( FGATCMgr *a ) {ATC_mgr = a; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue