const string& rwy_no(token[1]);
int surface_code = atoi( token[7].c_str() );
- cache->insertRunway(FGPositioned::RUNWAY, rwy_no, pos,
+ cache->insertRunway(FGPositioned::HELIPAD, rwy_no, pos,
currentAirportID, heading, length,
width, 0.0, 0.0, surface_code);
}
// runwaybase.cxx -- a base class for runways and taxiways
//
-// Written by James Turber, started December 2008.
+// Written by James Turner, started December 2008.
//
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
return result;
}
+FGHelipad::FGHelipad(PositionedID aGuid,
+ PositionedID aAirport, const string& aIdent,
+ const SGGeod& aGeod,
+ const double heading, const double length,
+ const double width,
+ const int surface_code) :
+ FGRunwayBase(aGuid, RUNWAY, aIdent, aGeod,
+ heading, length, width, surface_code),
+ _airport(aAirport)
+{
+}
};
+class FGHelipad : public FGRunwayBase
+{
+ PositionedID _airport;
+public:
+ FGHelipad(PositionedID aGuid,
+ PositionedID aAirport, const std::string& rwy_no,
+ const SGGeod& aGeod,
+ const double heading, const double length,
+ const double width,
+ const int surface_code);
+};
+
+
#endif // _FG_RUNWAYS_HXX
return mRunways.size();
}
+unsigned int FGAirport::numHelipads() const
+{
+ loadHelipads();
+ return mHelipads.size();
+}
+
FGRunway* FGAirport::getRunwayByIndex(unsigned int aIndex) const
{
loadRunways();
return (FGRunway*) flightgear::NavDataCache::instance()->loadById(mRunways[aIndex]);
}
+FGHelipad* FGAirport::getHelipadByIndex(unsigned int aIndex) const
+{
+ loadHelipads();
+
+ assert(aIndex >= 0 && aIndex < mHelipads.size());
+ return (FGHelipad*) flightgear::NavDataCache::instance()->loadById(mHelipads[aIndex]);
+}
+
bool FGAirport::hasRunwayWithIdent(const string& aIdent) const
{
return flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent) != 0;
mRunways = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::RUNWAY);
}
+void FGAirport::loadHelipads() const
+{
+ if (mHelipadsLoaded) {
+ return; // already loaded, great
+ }
+
+ loadSceneryDefinitions();
+
+ mHelipadsLoaded = true;
+ mHelipads = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::HELIPAD);
+}
+
void FGAirport::loadTaxiways() const
{
if (mTaxiwaysLoaded) {
// forward decls
class FGAirportDynamics;
class FGRunway;
+class FGHelipad;
class FGTaxiway;
class FGPavement;
class SGPropertyNode;
FGAirportDynamics *getDynamics();
unsigned int numRunways() const;
+ unsigned int numHelipads() const;
FGRunway* getRunwayByIndex(unsigned int aIndex) const;
+ FGHelipad* getHelipadByIndex(unsigned int aIndex) const;
bool hasRunwayWithIdent(const std::string& aIdent) const;
FGRunway* getRunwayByIdent(const std::string& aIdent) const;
void validateTowerData() const;
/**
- * Helper to parse property data loaded from an ICAO.twr.xml filke
+ * Helper to parse property data loaded from an ICAO.twr.xml file
*/
void readTowerData(SGPropertyNode* aRoot);
FGAirportDynamics *_dynamics;
void loadRunways() const;
+ void loadHelipads() const;
void loadTaxiways() const;
void loadProcedures() const;
mutable bool mTowerDataLoaded;
mutable bool mRunwaysLoaded;
+ mutable bool mHelipadsLoaded;
mutable bool mTaxiwaysLoaded;
mutable bool mProceduresLoaded;
bool mILSDataLoaded;
mutable PositionedIDVec mRunways;
+ mutable PositionedIDVec mHelipads;
mutable PositionedIDVec mTaxiways;
PositionedIDVec mPavements;
}
for (unsigned int r=0; r<apt->numRunways(); ++r) {
- FGRunway* rwy = apt->getRunwayByIndex(r);
- if (!rwy->isReciprocal()) {
- drawRunwayPre(rwy);
- }
+ FGRunway* rwy = apt->getRunwayByIndex(r);
+ if (!rwy->isReciprocal()) {
+ drawRunwayPre(rwy);
+ }
}
- for (unsigned int r=0; r<apt->numRunways(); ++r) {
- FGRunway* rwy = apt->getRunwayByIndex(r);
- if (!rwy->isReciprocal()) {
- drawRunway(rwy);
- }
+ for (unsigned int r=0; r<apt->numRunways(); ++r) {
+ FGRunway* rwy = apt->getRunwayByIndex(r);
+ if (!rwy->isReciprocal()) {
+ drawRunway(rwy);
+ }
- if (rwy->ILS()) {
- drawILS(false, rwy);
- }
- } // of runway iteration
+ if (rwy->ILS()) {
+ drawILS(false, rwy);
+ }
+ }
+
+ for (unsigned int r=0; r<apt->numHelipads(); ++r) {
+ FGHelipad* hp = apt->getHelipadByIndex(r);
+ drawHelipad(hp);
+ } // of runway iteration
}
} // of ai/models iteration
}
+void MapWidget::drawHelipad(FGHelipad* hp)
+{
+ SGVec2d pos = project(hp->geod());
+ glLineWidth(1.0);
+ glColor3f(1.0, 1.0, 1.0);
+ circleAt(pos, 16, 5.0);
+
+ if (validDataForKey(hp)) {
+ setAnchorForKey(hp, pos);
+ return;
+ }
+
+ char buffer[1024];
+ ::snprintf(buffer, 1024, "%s\n%03d\n%.0f'",
+ hp->ident().c_str(),
+ displayHeading(hp->headingDeg()),
+ hp->lengthFt());
+
+ MapData* d = createDataForKey(hp);
+ d->setText(buffer);
+ d->setLabel(hp->ident());
+ d->setPriority(40);
+ d->setOffset(MapData::HALIGN_CENTER | MapData::VALIGN_BOTTOM, 8);
+ d->setAnchor(pos);
+}
+
void MapWidget::drawAIAircraft(const SGPropertyNode* model, const SGGeod& pos, double hdg)
{
// forward decls
class FGRouteMgr;
class FGRunway;
+class FGHelipad;
class FGAirport;
class FGNavRecord;
class FGFix;
int scoreAirportRunways(FGAirport* apt);
void drawRunwayPre(FGRunway* rwy);
void drawRunway(FGRunway* rwy);
+ void drawHelipad(FGHelipad* hp);
void drawILS(bool tuned, FGRunway* rwy);
void drawNavaids();
namespace {
const int MAX_RETRIES = 10;
-const int SCHEMA_VERSION = 6;
+const int SCHEMA_VERSION = 7;
const int CACHE_SIZE_KBYTES= 16000;
// bind a std::string to a sqlite statement. The std::string must live the
if (ty == FGPositioned::TAXIWAY) {
reset(loadRunwayStmt);
return new FGTaxiway(rowId, id, pos, heading, lengthM, widthM, surface);
+ } else if (ty == FGPositioned::HELIPAD) {
+ reset(loadRunwayStmt);
+ return new FGHelipad(rowId, apt, id, pos, heading, lengthM, widthM, surface);
} else {
double displacedThreshold = sqlite3_column_double(loadRunwayStmt, 4);
double stopway = sqlite3_column_double(loadRunwayStmt, 5);
return new AirportTower(rowid, aptId, ident, pos);
case FGPositioned::RUNWAY:
+ case FGPositioned::HELIPAD:
case FGPositioned::TAXIWAY:
return loadRunway(rowid, ty, ident, pos, aptId);
{
// only runways are spatially indexed; don't bother indexing taxiways
// or pavements
- bool spatialIndex = (ty == FGPositioned::RUNWAY);
+ bool spatialIndex = ( ty == FGPositioned::RUNWAY || ty == FGPositioned::HELIPAD);
sqlite3_int64 rowId = d->insertPositioned(ty, cleanRunwayNo(ident), "", pos, apt,
spatialIndex);
HELIPORT,
SEAPORT,
RUNWAY,
+ HELIPAD,
TAXIWAY,
PAVEMENT,
WAYPOINT,