1998-08-25 17:19:13 +00:00
|
|
|
//
|
1999-02-26 22:08:34 +00:00
|
|
|
// simple.cxx -- a really simplistic class to manage airport ID,
|
2006-07-10 11:36:38 +00:00
|
|
|
// lat, lon of the center of one of it's runways, and
|
2003-08-28 20:53:08 +00:00
|
|
|
// elevation in feet.
|
1998-08-25 17:19:13 +00:00
|
|
|
//
|
|
|
|
// Written by Curtis Olson, started April 1998.
|
2005-02-10 09:01:51 +00:00
|
|
|
// Updated by Durk Talsma, started December, 2004.
|
1998-08-25 17:19:13 +00:00
|
|
|
//
|
2004-11-19 22:10:41 +00:00
|
|
|
// Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt
|
1998-08-25 17:19:13 +00:00
|
|
|
//
|
|
|
|
// 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
|
2006-02-21 01:16:04 +00:00
|
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1998-08-25 17:19:13 +00:00
|
|
|
//
|
|
|
|
// $Id$
|
|
|
|
|
2000-04-27 03:26:36 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2008-12-27 13:20:08 +00:00
|
|
|
#include "simple.hxx"
|
2005-02-25 19:41:53 +00:00
|
|
|
|
2005-02-10 09:01:51 +00:00
|
|
|
#include <simgear/misc/sg_path.hxx>
|
|
|
|
#include <simgear/props/props.hxx>
|
2000-02-16 23:01:03 +00:00
|
|
|
#include <simgear/debug/logstream.hxx>
|
2008-12-27 13:20:08 +00:00
|
|
|
#include <simgear/sg_inlines.h>
|
|
|
|
|
|
|
|
#include <Environment/environment_mgr.hxx>
|
|
|
|
#include <Environment/environment.hxx>
|
2005-02-10 09:01:51 +00:00
|
|
|
#include <Main/fg_props.hxx>
|
|
|
|
#include <Airports/runways.hxx>
|
2008-08-14 18:13:39 +00:00
|
|
|
#include <Airports/dynamics.hxx>
|
2008-12-27 13:20:08 +00:00
|
|
|
#include <Airports/xmlloader.hxx>
|
2002-04-04 06:05:51 +00:00
|
|
|
|
2008-12-26 15:26:42 +00:00
|
|
|
// magic import of a helper which uses FGPositioned internals
|
|
|
|
extern char** searchAirportNamesAndIdents(const std::string& aFilter);
|
2005-02-10 09:01:51 +00:00
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* FGAirport
|
|
|
|
***************************************************************************/
|
|
|
|
|
2007-10-05 12:59:43 +00:00
|
|
|
FGAirport::FGAirport(const string &id, const SGGeod& location, const SGGeod& tower_location,
|
James Turner:
Trivial patch, but an important milestone:
Convert FGAirport to inherit FGPositioned. This concludes the first phase of the FGPositioned changes, and hopefully the most intrusive ones - adding in the base class. There's lots (and lots) of further work to do on the indexing and querying side, as well as cleaning up the accessors, but that will happen in single source files, or a group of related files at a time.
As a trivial note, this patch does fix a bug where the very last airport in apt.dat would get an invalid type. So for all you people who just love to fly to EHYB (Ypenburg, The Hague), things may work a little more sanely.
I'll intentionally let the dust settle after this patch, so any weird behaviour I may potentially have introduced shows up. Just to re-iterate, so far there should be absolutely no user-visible change in the behaviour of anything - navaids, position init, the route manager, AI flight plans, etc. If there is, please let me know and I'll fix it ASAP.
2008-09-13 08:07:22 +00:00
|
|
|
const string &name, bool has_metar, Type aType) :
|
|
|
|
FGPositioned(aType, id, location),
|
2007-10-05 12:59:43 +00:00
|
|
|
_tower_location(tower_location),
|
|
|
|
_name(name),
|
|
|
|
_has_metar(has_metar),
|
|
|
|
_dynamics(0)
|
2005-02-10 09:01:51 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2006-07-10 11:36:38 +00:00
|
|
|
|
2005-12-29 13:58:21 +00:00
|
|
|
FGAirport::~FGAirport()
|
2005-10-18 18:44:37 +00:00
|
|
|
{
|
2007-10-05 12:59:43 +00:00
|
|
|
delete _dynamics;
|
2005-10-18 18:44:37 +00:00
|
|
|
}
|
|
|
|
|
James Turner:
Trivial patch, but an important milestone:
Convert FGAirport to inherit FGPositioned. This concludes the first phase of the FGPositioned changes, and hopefully the most intrusive ones - adding in the base class. There's lots (and lots) of further work to do on the indexing and querying side, as well as cleaning up the accessors, but that will happen in single source files, or a group of related files at a time.
As a trivial note, this patch does fix a bug where the very last airport in apt.dat would get an invalid type. So for all you people who just love to fly to EHYB (Ypenburg, The Hague), things may work a little more sanely.
I'll intentionally let the dust settle after this patch, so any weird behaviour I may potentially have introduced shows up. Just to re-iterate, so far there should be absolutely no user-visible change in the behaviour of anything - navaids, position init, the route manager, AI flight plans, etc. If there is, please let me know and I'll fix it ASAP.
2008-09-13 08:07:22 +00:00
|
|
|
bool FGAirport::isAirport() const
|
|
|
|
{
|
|
|
|
return type() == AIRPORT;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FGAirport::isSeaport() const
|
|
|
|
{
|
|
|
|
return type() == SEAPORT;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FGAirport::isHeliport() const
|
|
|
|
{
|
|
|
|
return type() == HELIPORT;
|
|
|
|
}
|
2005-02-10 09:01:51 +00:00
|
|
|
|
2005-12-29 13:58:21 +00:00
|
|
|
FGAirportDynamics * FGAirport::getDynamics()
|
2005-02-10 09:01:51 +00:00
|
|
|
{
|
2007-10-05 12:59:43 +00:00
|
|
|
if (_dynamics != 0) {
|
|
|
|
return _dynamics;
|
2006-07-10 11:36:38 +00:00
|
|
|
} else {
|
2006-10-12 21:48:18 +00:00
|
|
|
//cerr << "Trying to load dynamics for " << _id << endl;
|
2007-10-05 12:59:43 +00:00
|
|
|
_dynamics = new FGAirportDynamics(this);
|
|
|
|
XMLLoader::load(_dynamics);
|
2007-07-04 17:39:03 +00:00
|
|
|
|
|
|
|
FGRunwayPreference rwyPrefs(this);
|
|
|
|
XMLLoader::load(&rwyPrefs);
|
2007-10-05 12:59:43 +00:00
|
|
|
_dynamics->setRwyUse(rwyPrefs);
|
2007-07-04 17:39:03 +00:00
|
|
|
}
|
2007-10-05 12:59:43 +00:00
|
|
|
return _dynamics;
|
2005-10-18 18:44:37 +00:00
|
|
|
}
|
|
|
|
|
2008-08-14 18:13:39 +00:00
|
|
|
unsigned int FGAirport::numRunways() const
|
|
|
|
{
|
|
|
|
return mRunways.size();
|
|
|
|
}
|
|
|
|
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
FGRunway* FGAirport::getRunwayByIndex(unsigned int aIndex) const
|
2008-08-14 18:13:39 +00:00
|
|
|
{
|
|
|
|
assert(aIndex >= 0 && aIndex < mRunways.size());
|
|
|
|
return mRunways[aIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FGAirport::hasRunwayWithIdent(const string& aIdent) const
|
|
|
|
{
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
return (getIteratorForRunwayIdent(aIdent) != mRunways.end());
|
2008-08-14 18:13:39 +00:00
|
|
|
}
|
|
|
|
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
FGRunway* FGAirport::getRunwayByIdent(const string& aIdent) const
|
2008-08-14 18:13:39 +00:00
|
|
|
{
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
Runway_iterator it = getIteratorForRunwayIdent(aIdent);
|
2008-08-14 18:13:39 +00:00
|
|
|
if (it == mRunways.end()) {
|
James Turner:
Trivial patch, but an important milestone:
Convert FGAirport to inherit FGPositioned. This concludes the first phase of the FGPositioned changes, and hopefully the most intrusive ones - adding in the base class. There's lots (and lots) of further work to do on the indexing and querying side, as well as cleaning up the accessors, but that will happen in single source files, or a group of related files at a time.
As a trivial note, this patch does fix a bug where the very last airport in apt.dat would get an invalid type. So for all you people who just love to fly to EHYB (Ypenburg, The Hague), things may work a little more sanely.
I'll intentionally let the dust settle after this patch, so any weird behaviour I may potentially have introduced shows up. Just to re-iterate, so far there should be absolutely no user-visible change in the behaviour of anything - navaids, position init, the route manager, AI flight plans, etc. If there is, please let me know and I'll fix it ASAP.
2008-09-13 08:07:22 +00:00
|
|
|
SG_LOG(SG_GENERAL, SG_ALERT, "no such runway '" << aIdent << "' at airport " << ident());
|
|
|
|
throw sg_range_exception("unknown runway " + aIdent + " at airport:" + ident(), "FGAirport::getRunwayByIdent");
|
2008-08-14 18:13:39 +00:00
|
|
|
}
|
|
|
|
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
return *it;
|
2008-08-14 18:13:39 +00:00
|
|
|
}
|
2005-10-18 18:44:37 +00:00
|
|
|
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
FGAirport::Runway_iterator
|
|
|
|
FGAirport::getIteratorForRunwayIdent(const string& aIdent) const
|
2008-08-14 18:13:39 +00:00
|
|
|
{
|
|
|
|
string ident(aIdent);
|
|
|
|
if ((aIdent.size() == 1) || !isdigit(aIdent[1])) {
|
|
|
|
ident = "0" + aIdent;
|
|
|
|
}
|
|
|
|
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
Runway_iterator it = mRunways.begin();
|
2008-08-14 18:13:39 +00:00
|
|
|
for (; it != mRunways.end(); ++it) {
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
if ((*it)->ident() == ident) {
|
2008-08-14 18:13:39 +00:00
|
|
|
return it;
|
|
|
|
}
|
|
|
|
}
|
2005-10-18 18:44:37 +00:00
|
|
|
|
2008-08-14 18:13:39 +00:00
|
|
|
return it; // end()
|
|
|
|
}
|
|
|
|
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
FGRunway* FGAirport::findBestRunwayForHeading(double aHeading) const
|
2008-08-14 18:13:39 +00:00
|
|
|
{
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
Runway_iterator it = mRunways.begin();
|
|
|
|
FGRunway* result = NULL;
|
2008-08-14 18:13:39 +00:00
|
|
|
double currentBestQuality = 0.0;
|
|
|
|
|
|
|
|
SGPropertyNode *param = fgGetNode("/sim/airport/runways/search", true);
|
|
|
|
double lengthWeight = param->getDoubleValue("length-weight", 0.01);
|
|
|
|
double widthWeight = param->getDoubleValue("width-weight", 0.01);
|
|
|
|
double surfaceWeight = param->getDoubleValue("surface-weight", 10);
|
|
|
|
double deviationWeight = param->getDoubleValue("deviation-weight", 1);
|
|
|
|
|
|
|
|
for (; it != mRunways.end(); ++it) {
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
double good = (*it)->score(lengthWeight, widthWeight, surfaceWeight);
|
2008-08-14 18:13:39 +00:00
|
|
|
|
2008-12-27 13:20:08 +00:00
|
|
|
double dev = aHeading - (*it)->headingDeg();
|
|
|
|
SG_NORMALIZE_RANGE(dev, -180.0, 180.0);
|
2008-08-14 18:13:39 +00:00
|
|
|
double bad = fabs(deviationWeight * dev) + 1e-20;
|
|
|
|
double quality = good / bad;
|
|
|
|
|
|
|
|
if (quality > currentBestQuality) {
|
|
|
|
currentBestQuality = quality;
|
|
|
|
result = *it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2008-12-23 12:37:59 +00:00
|
|
|
bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const
|
|
|
|
{
|
|
|
|
unsigned int numRunways(mRunways.size());
|
|
|
|
for (unsigned int r=0; r<numRunways; ++r) {
|
|
|
|
FGRunway* rwy = mRunways[r];
|
|
|
|
if (rwy->isReciprocal()) {
|
|
|
|
continue; // we only care about lengths, so don't do work twice
|
|
|
|
}
|
2008-12-24 15:45:35 +00:00
|
|
|
|
|
|
|
if (rwy->isHardSurface() && (rwy->lengthFt() >= aLengthFt)) {
|
2008-12-23 12:37:59 +00:00
|
|
|
return true; // we're done!
|
|
|
|
}
|
|
|
|
} // of runways iteration
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-08-14 18:13:39 +00:00
|
|
|
unsigned int FGAirport::numTaxiways() const
|
|
|
|
{
|
|
|
|
return mTaxiways.size();
|
|
|
|
}
|
|
|
|
|
2008-12-29 22:23:22 +00:00
|
|
|
FGTaxiway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const
|
2008-08-14 18:13:39 +00:00
|
|
|
{
|
|
|
|
assert(aIndex >= 0 && aIndex < mTaxiways.size());
|
|
|
|
return mTaxiways[aIndex];
|
|
|
|
}
|
|
|
|
|
2008-12-29 22:23:22 +00:00
|
|
|
void FGAirport::setRunwaysAndTaxiways(vector<FGRunwayPtr>& rwys,
|
|
|
|
vector<FGTaxiwayPtr>& txwys)
|
2008-08-14 18:13:39 +00:00
|
|
|
{
|
2008-12-29 22:23:22 +00:00
|
|
|
mRunways.swap(rwys);
|
|
|
|
Runway_iterator it = mRunways.begin();
|
|
|
|
for (; it != mRunways.end(); ++it) {
|
|
|
|
(*it)->setAirport(this);
|
2008-08-14 18:13:39 +00:00
|
|
|
}
|
2008-12-29 22:23:22 +00:00
|
|
|
|
|
|
|
mTaxiways.swap(txwys);
|
2008-08-14 18:13:39 +00:00
|
|
|
}
|
|
|
|
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
FGRunway* FGAirport::getActiveRunwayForUsage() const
|
2008-08-14 18:13:39 +00:00
|
|
|
{
|
|
|
|
static FGEnvironmentMgr* envMgr = NULL;
|
|
|
|
if (!envMgr) {
|
|
|
|
envMgr = (FGEnvironmentMgr *) globals->get_subsystem("environment");
|
|
|
|
}
|
|
|
|
|
James Turner:
Trivial patch, but an important milestone:
Convert FGAirport to inherit FGPositioned. This concludes the first phase of the FGPositioned changes, and hopefully the most intrusive ones - adding in the base class. There's lots (and lots) of further work to do on the indexing and querying side, as well as cleaning up the accessors, but that will happen in single source files, or a group of related files at a time.
As a trivial note, this patch does fix a bug where the very last airport in apt.dat would get an invalid type. So for all you people who just love to fly to EHYB (Ypenburg, The Hague), things may work a little more sanely.
I'll intentionally let the dust settle after this patch, so any weird behaviour I may potentially have introduced shows up. Just to re-iterate, so far there should be absolutely no user-visible change in the behaviour of anything - navaids, position init, the route manager, AI flight plans, etc. If there is, please let me know and I'll fix it ASAP.
2008-09-13 08:07:22 +00:00
|
|
|
FGEnvironment stationWeather(envMgr->getEnvironment(mPosition));
|
2008-08-14 18:13:39 +00:00
|
|
|
|
|
|
|
double windSpeed = stationWeather.get_wind_speed_kt();
|
|
|
|
double hdg = stationWeather.get_wind_from_heading_deg();
|
|
|
|
if (windSpeed <= 0.0) {
|
|
|
|
hdg = 270; // This forces West-facing rwys to be used in no-wind situations
|
|
|
|
// which is consistent with Flightgear's initial setup.
|
|
|
|
}
|
|
|
|
|
|
|
|
return findBestRunwayForHeading(hdg);
|
|
|
|
}
|
2005-10-18 18:44:37 +00:00
|
|
|
|
2008-12-23 12:37:59 +00:00
|
|
|
FGAirport* FGAirport::findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter)
|
|
|
|
{
|
|
|
|
AirportFilter aptFilter;
|
|
|
|
if (filter == NULL) {
|
|
|
|
filter = &aptFilter;
|
|
|
|
}
|
|
|
|
|
|
|
|
FGPositionedRef r = FGPositioned::findClosest(aPos, aCuttofNm, filter);
|
|
|
|
if (!r) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return static_cast<FGAirport*>(r.ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
FGAirport::HardSurfaceFilter::HardSurfaceFilter(double minLengthFt) :
|
|
|
|
mMinLengthFt(minLengthFt)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FGAirport::HardSurfaceFilter::pass(FGPositioned* aPos) const
|
|
|
|
{
|
|
|
|
if (aPos->type() != AIRPORT) {
|
|
|
|
return false; // exclude seaports and heliports as well, we need a runways
|
|
|
|
}
|
|
|
|
|
|
|
|
return static_cast<FGAirport*>(aPos)->hasHardRunwayOfLengthFt(mMinLengthFt);
|
|
|
|
}
|
|
|
|
|
2008-12-26 15:26:42 +00:00
|
|
|
FGAirport* FGAirport::findByIdent(const std::string& aIdent)
|
|
|
|
{
|
|
|
|
FGPositionedRef r;
|
|
|
|
AirportFilter filter;
|
|
|
|
r = FGPositioned::findNextWithPartialId(r, aIdent, &filter);
|
|
|
|
if (!r) {
|
|
|
|
return NULL; // we don't warn here, let the caller do that
|
|
|
|
}
|
|
|
|
return static_cast<FGAirport*>(r.ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
FGAirport* FGAirport::getByIdent(const std::string& aIdent)
|
|
|
|
{
|
|
|
|
FGPositionedRef r;
|
|
|
|
AirportFilter filter;
|
|
|
|
r = FGPositioned::findNextWithPartialId(r, aIdent, &filter);
|
|
|
|
if (!r) {
|
|
|
|
throw sg_range_exception("No such airport with ident: " + aIdent);
|
|
|
|
}
|
|
|
|
return static_cast<FGAirport*>(r.ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
char** FGAirport::searchNamesAndIdents(const std::string& aFilter)
|
|
|
|
{
|
|
|
|
// we delegate all the work to a horrible helper in FGPositioned, which can
|
|
|
|
// access the (private) index data.
|
|
|
|
return searchAirportNamesAndIdents(aFilter);
|
|
|
|
}
|
|
|
|
|
2005-12-29 13:58:21 +00:00
|
|
|
// find basic airport location info from airport database
|
2006-07-10 11:36:38 +00:00
|
|
|
const FGAirport *fgFindAirportID( const string& id)
|
|
|
|
{
|
2008-12-26 15:26:42 +00:00
|
|
|
if ( id.empty() ) {
|
2005-12-29 13:58:21 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-12-26 15:26:42 +00:00
|
|
|
|
|
|
|
return FGAirport::findByIdent(id);
|
2005-12-29 13:58:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get airport elevation
|
2006-07-10 11:36:38 +00:00
|
|
|
double fgGetAirportElev( const string& id )
|
|
|
|
{
|
2006-02-18 00:18:20 +00:00
|
|
|
SG_LOG( SG_GENERAL, SG_BULK,
|
2005-12-29 13:58:21 +00:00
|
|
|
"Finding elevation for airport: " << id );
|
|
|
|
|
|
|
|
const FGAirport *a=fgFindAirportID( id);
|
|
|
|
if (a) {
|
|
|
|
return a->getElevation();
|
|
|
|
} else {
|
|
|
|
return -9999.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-10 11:36:38 +00:00
|
|
|
// get airport position
|
|
|
|
Point3D fgGetAirportPos( const string& id )
|
|
|
|
{
|
2006-02-18 00:18:20 +00:00
|
|
|
SG_LOG( SG_ATC, SG_BULK,
|
2005-12-29 13:58:21 +00:00
|
|
|
"Finding position for airport: " << id );
|
|
|
|
|
|
|
|
const FGAirport *a = fgFindAirportID( id);
|
2006-07-10 11:36:38 +00:00
|
|
|
|
2005-12-29 13:58:21 +00:00
|
|
|
if (a) {
|
|
|
|
return Point3D(a->getLongitude(), a->getLatitude(), a->getElevation());
|
|
|
|
} else {
|
|
|
|
return Point3D(0.0, 0.0, -9999.0);
|
|
|
|
}
|
|
|
|
}
|