1
0
Fork 0

Expose surface types and taxiways via the airportinfo() Nasal call.

This commit is contained in:
Stuart Buchanan 2012-09-19 22:33:43 +01:00
parent f8b689c040
commit ac1fc699b7
3 changed files with 95 additions and 3 deletions

View file

@ -69,7 +69,7 @@ FGAirport::FGAirport(PositionedID aGuid, const string &id, const SGGeod& locatio
_dynamics(0), _dynamics(0),
mTowerDataLoaded(false), mTowerDataLoaded(false),
mRunwaysLoaded(false), mRunwaysLoaded(false),
mTaxiwaysLoaded(true) mTaxiwaysLoaded(false)
{ {
} }
@ -234,10 +234,27 @@ unsigned int FGAirport::numTaxiways() const
FGTaxiway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const FGTaxiway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const
{ {
loadTaxiways(); loadTaxiways();
assert(aIndex >= 0 && aIndex < mTaxiways.size()); assert(aIndex >= 0 && aIndex < mTaxiways.size());
return (FGTaxiway*) flightgear::NavDataCache::instance()->loadById(mTaxiways[aIndex]); return (FGTaxiway*) flightgear::NavDataCache::instance()->loadById(mTaxiways[aIndex]);
} }
bool FGAirport::hasTaxiwayWithIdent(const string& aIdent) const
{
return flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent) != 0;
}
FGTaxiway* FGAirport::getTaxiwayByIdent(const string& aIdent) const
{
PositionedID id = flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent);
if (id == 0) {
SG_LOG(SG_GENERAL, SG_ALERT, "no such runway '" << aIdent << "' at airport " << ident());
throw sg_range_exception("unknown runway " + aIdent + " at airport:" + ident(), "FGAirport::getTaxiwayByIdent");
}
return (FGTaxiway*) flightgear::NavDataCache::instance()->loadById(id);
}
unsigned int FGAirport::numPavements() const unsigned int FGAirport::numPavements() const
{ {
loadTaxiways(); loadTaxiways();

View file

@ -123,6 +123,9 @@ public:
unsigned int numTaxiways() const; unsigned int numTaxiways() const;
FGTaxiway* getTaxiwayByIndex(unsigned int aIndex) const; FGTaxiway* getTaxiwayByIndex(unsigned int aIndex) const;
bool hasTaxiwayWithIdent(const std::string& aIdent) const;
FGTaxiway* getTaxiwayByIdent(const std::string& aIdent) const;
unsigned int numPavements() const; unsigned int numPavements() const;
FGPavement* getPavementByIndex(unsigned int aIndex) const; FGPavement* getPavementByIndex(unsigned int aIndex) const;
@ -235,7 +238,7 @@ private:
void readThresholdData(SGPropertyNode* aRoot); void readThresholdData(SGPropertyNode* aRoot);
void processThreshold(SGPropertyNode* aThreshold); void processThreshold(SGPropertyNode* aThreshold);
void readILSData(SGPropertyNode* aRoot); void readILSData(SGPropertyNode* aRoot);
void validateTowerData() const; void validateTowerData() const;
@ -256,7 +259,7 @@ private:
mutable bool mRunwaysLoaded; mutable bool mRunwaysLoaded;
mutable bool mTaxiwaysLoaded; mutable bool mTaxiwaysLoaded;
mutable bool mProceduresLoaded; mutable bool mProceduresLoaded;
bool mILSDataLoaded; bool mILSDataLoaded;
mutable PositionedIDVec mRunways; mutable PositionedIDVec mRunways;
mutable PositionedIDVec mTaxiways; mutable PositionedIDVec mTaxiways;

View file

@ -72,6 +72,9 @@ naGhostType NavaidGhostType = { positionedGhostDestroy, "navaid", navaidGhostGet
static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef* out); static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef* out);
naGhostType RunwayGhostType = { positionedGhostDestroy, "runway", runwayGhostGetMember, 0 }; naGhostType RunwayGhostType = { positionedGhostDestroy, "runway", runwayGhostGetMember, 0 };
static const char* taxiwayGhostGetMember(naContext c, void* g, naRef field, naRef* out);
naGhostType TaxiwayGhostType = { positionedGhostDestroy, "taxiway", taxiwayGhostGetMember, 0 };
static const char* fixGhostGetMember(naContext c, void* g, naRef field, naRef* out); static const char* fixGhostGetMember(naContext c, void* g, naRef field, naRef* out);
naGhostType FixGhostType = { positionedGhostDestroy, "fix", fixGhostGetMember, 0 }; naGhostType FixGhostType = { positionedGhostDestroy, "fix", fixGhostGetMember, 0 };
@ -175,6 +178,13 @@ static FGRunway* runwayGhost(naRef r)
return 0; return 0;
} }
static FGTaxiway* taxiwayGhost(naRef r)
{
if (naGhost_type(r) == &TaxiwayGhostType)
return (FGTaxiway*) naGhost_ptr(r);
return 0;
}
static FGFix* fixGhost(naRef r) static FGFix* fixGhost(naRef r)
{ {
if (naGhost_type(r) == &FixGhostType) if (naGhost_type(r) == &FixGhostType)
@ -279,6 +289,16 @@ naRef ghostForRunway(naContext c, const FGRunway* r)
return naNewGhost2(c, &RunwayGhostType, (void*) r); return naNewGhost2(c, &RunwayGhostType, (void*) r);
} }
naRef ghostForTaxiway(naContext c, const FGTaxiway* r)
{
if (!r) {
return naNil();
}
FGPositioned::get(r); // take a ref
return naNewGhost2(c, &TaxiwayGhostType, (void*) r);
}
naRef ghostForFix(naContext c, const FGFix* r) naRef ghostForFix(naContext c, const FGFix* r)
{ {
if (!r) { if (!r) {
@ -359,6 +379,14 @@ static const char* airportGhostGetMember(naContext c, void* g, naRef field, naRe
naHash_set(*out, rwyid, rwydata); naHash_set(*out, rwyid, rwydata);
} }
} else if (!strcmp(fieldName, "taxiways")) {
*out = naNewVector(c);
for(unsigned int r=0; r<apt->numTaxiways(); ++r) {
FGTaxiway* taxi(apt->getTaxiwayByIndex(r));
naRef taxidata = ghostForTaxiway(c, taxi);
naVec_append(*out, taxidata);
}
} else { } else {
return 0; return 0;
} }
@ -704,6 +732,7 @@ static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef
else if (!strcmp(fieldName, "width")) *out = naNum(rwy->widthM()); else if (!strcmp(fieldName, "width")) *out = naNum(rwy->widthM());
else if (!strcmp(fieldName, "threshold")) *out = naNum(rwy->displacedThresholdM()); else if (!strcmp(fieldName, "threshold")) *out = naNum(rwy->displacedThresholdM());
else if (!strcmp(fieldName, "stopway")) *out = naNum(rwy->stopwayM()); else if (!strcmp(fieldName, "stopway")) *out = naNum(rwy->stopwayM());
else if (!strcmp(fieldName, "surface")) *out = naNum(rwy->surface());
else if (!strcmp(fieldName, "ils_frequency_mhz")) { else if (!strcmp(fieldName, "ils_frequency_mhz")) {
*out = rwy->ILS() ? naNum(rwy->ILS()->get_freq() / 100.0) : naNil(); *out = rwy->ILS() ? naNum(rwy->ILS()->get_freq() / 100.0) : naNil();
} else if (!strcmp(fieldName, "ils")) { } else if (!strcmp(fieldName, "ils")) {
@ -715,6 +744,23 @@ static const char* runwayGhostGetMember(naContext c, void* g, naRef field, naRef
return ""; return "";
} }
static const char* taxiwayGhostGetMember(naContext c, void* g, naRef field, naRef* out)
{
const char* fieldName = naStr_data(field);
FGTaxiway* taxi = (FGTaxiway*) g;
if (!strcmp(fieldName, "id")) *out = stringToNasal(c, taxi->ident());
else if (!strcmp(fieldName, "lat")) *out = naNum(taxi->latitude());
else if (!strcmp(fieldName, "lon")) *out = naNum(taxi->longitude());
else if (!strcmp(fieldName, "heading")) *out = naNum(taxi->headingDeg());
else if (!strcmp(fieldName, "length")) *out = naNum(taxi->lengthM());
else if (!strcmp(fieldName, "width")) *out = naNum(taxi->widthM());
else if (!strcmp(fieldName, "surface")) *out = naNum(taxi->surface());
else return 0;
return "";
}
static const char* navaidGhostGetMember(naContext c, void* g, naRef field, naRef* out) static const char* navaidGhostGetMember(naContext c, void* g, naRef field, naRef* out)
{ {
const char* fieldName = naStr_data(field); const char* fieldName = naStr_data(field);
@ -825,6 +871,11 @@ static int geodFromArgs(naRef* args, int offset, int argc, SGGeod& result)
return 1; return 1;
} }
if (gt == &TaxiwayGhostType) {
result = taxiwayGhost(args[offset])->geod();
return 1;
}
if (gt == &FixGhostType) { if (gt == &FixGhostType) {
result = fixGhost(args[offset])->geod(); result = fixGhost(args[offset])->geod();
return 1; return 1;
@ -1135,6 +1186,26 @@ static naRef f_airport_runway(naContext c, naRef me, int argc, naRef* args)
return ghostForRunway(c, apt->getRunwayByIdent(ident)); return ghostForRunway(c, apt->getRunwayByIdent(ident));
} }
static naRef f_airport_taxiway(naContext c, naRef me, int argc, naRef* args)
{
FGAirport* apt = airportGhost(me);
if (!apt) {
naRuntimeError(c, "airport.taxiway called on non-airport object");
}
if ((argc < 1) || !naIsString(args[0])) {
naRuntimeError(c, "airport.taxiway expects a taxiway ident argument");
}
std::string ident(naStr_data(args[0]));
boost::to_upper(ident);
if (!apt->hasTaxiwayWithIdent(ident)) {
return naNil();
}
return ghostForTaxiway(c, apt->getTaxiwayByIdent(ident));
}
static naRef f_airport_sids(naContext c, naRef me, int argc, naRef* args) static naRef f_airport_sids(naContext c, naRef me, int argc, naRef* args)
{ {
FGAirport* apt = airportGhost(me); FGAirport* apt = airportGhost(me);
@ -2277,6 +2348,7 @@ naRef initNasalPositioned(naRef globals, naContext c, naRef gcSave)
hashset(c, gcSave, "airportProto", airportPrototype); hashset(c, gcSave, "airportProto", airportPrototype);
hashset(c, airportPrototype, "runway", naNewFunc(c, naNewCCode(c, f_airport_runway))); hashset(c, airportPrototype, "runway", naNewFunc(c, naNewCCode(c, f_airport_runway)));
hashset(c, airportPrototype, "taxiway", naNewFunc(c, naNewCCode(c, f_airport_taxiway)));
hashset(c, airportPrototype, "tower", naNewFunc(c, naNewCCode(c, f_airport_tower))); hashset(c, airportPrototype, "tower", naNewFunc(c, naNewCCode(c, f_airport_tower)));
hashset(c, airportPrototype, "comms", naNewFunc(c, naNewCCode(c, f_airport_comms))); hashset(c, airportPrototype, "comms", naNewFunc(c, naNewCCode(c, f_airport_comms)));
hashset(c, airportPrototype, "sids", naNewFunc(c, naNewCCode(c, f_airport_sids))); hashset(c, airportPrototype, "sids", naNewFunc(c, naNewCCode(c, f_airport_sids)));