1
0
Fork 0

FGPositioned clean-ups - apply some desirable changes (such as making members

const) which were previously tricky but now easy. Make it possible not to
index certain types (used for taxiways) and exclude anonymous items from
the name index. Related to this, clean up FGRunway further - remove some public
members, and fix a dumb bug of mine, where we create reciprocal entries for
taxiways.

This should make startup (slightly) quicker, and shrinks FGRunway somewhat.
This commit is contained in:
jmt 2008-12-24 14:48:30 +00:00
parent 335584e29c
commit 7d5d756095
11 changed files with 74 additions and 162 deletions

View file

@ -226,16 +226,19 @@ bool fgAirportDBLoad( FGAirportList *airports,
double stopway2 = atof( stop[1].c_str() );
int surface_code = atoi( token[10].c_str() );
FGRunway* rwy = new FGRunway(NULL, rwy_no, lon, lat, heading, length,
SGGeod pos(SGGeod::fromDegFt(lon, lat, 0.0));
FGRunway* rwy = new FGRunway(NULL, rwy_no, pos, heading, length,
width, displ_thresh1, stopway1, surface_code, false);
FGRunway* reciprocal = new FGRunway(NULL, FGRunway::reverseIdent(rwy_no),
lon, lat, heading + 180.0, length, width,
displ_thresh2, stopway2, surface_code, true);
runways.push_back(rwy);
runways.push_back(reciprocal);
if (rwy_no[0] != 'x') {
// runways need a reciprocal, taxiways do not
FGRunway* reciprocal = new FGRunway(NULL, FGRunway::reverseIdent(rwy_no),
pos, heading + 180.0, length, width,
displ_thresh2, stopway2, surface_code, true);
runways.push_back(reciprocal);
}
} else if ( line_id == 18 ) {
// beacon entry (ignore)
} else if ( line_id == 14 ) {

View file

@ -71,21 +71,18 @@ static std::string cleanRunwayNo(const std::string& aRwyNo)
}
FGRunway::FGRunway(FGAirport* aAirport, const string& rwy_no,
const double longitude, const double latitude,
const SGGeod& aGeod,
const double heading, const double length,
const double width,
const double displ_thresh,
const double stopway,
const int surface_code,
bool reciprocal) :
FGPositioned(runwayTypeFromNumber(rwy_no), cleanRunwayNo(rwy_no), latitude, longitude, 0.0),
FGPositioned(runwayTypeFromNumber(rwy_no), cleanRunwayNo(rwy_no), aGeod,
(runwayTypeFromNumber(rwy_no) == FGPositioned::RUNWAY)),
_airport(aAirport),
_reciprocal(reciprocal)
{
_rwy_no = ident();
_lon = longitude;
_lat = latitude;
_heading = heading;
_length = length;
_width = width;

View file

@ -42,7 +42,7 @@ class FGRunway : public FGPositioned
public:
FGRunway(FGAirport* aAirport, const std::string& rwy_no,
const double longitude, const double latitude,
const SGGeod& aGeod,
const double heading, const double length,
const double width,
const double displ_thresh,
@ -132,18 +132,14 @@ public:
int surface() const
{ return _surface_code; }
std::string _rwy_no;
double _displ_thresh;
double _stopway;
double _lon;
double _lat;
double _displ_thresh;
double _stopway;
double _heading;
double _length;
double _width;
double _heading;
double _length;
double _width;
int _surface_code;
int _surface_code;
};
#endif // _FG_RUNWAYS_HXX

View file

@ -190,23 +190,26 @@ void runway_instr::get_rwy_points(sgdVec3 *points3d)
double length = runway->lengthM() * 0.5;
double width = runway->widthM() * 0.5;
double frontLat, frontLon, backLat, backLon,az, tempLat, tempLon;
double runwayLon = runway->geod().getLongitudeDeg(),
runwayLat = runway->geod().getLatitudeDeg();
double heading = runway->headingDeg();
geo_direct_wgs_84(alt, runway->_lat, runway->_lon, runway->_heading, length, &backLat, &backLon, &az);
geo_direct_wgs_84(alt, runwayLat, runwayLon, heading, length, &backLat, &backLon, &az);
sgGeodToCart(backLat * SG_DEGREES_TO_RADIANS, backLon * SG_DEGREES_TO_RADIANS, alt, points3d[4]);
geo_direct_wgs_84(alt, runway->_lat, runway->_lon, runway->_heading + 180, length, &frontLat, &frontLon, &az);
geo_direct_wgs_84(alt, runwayLat, runwayLon, heading + 180, length, &frontLat, &frontLon, &az);
sgGeodToCart(frontLat * SG_DEGREES_TO_RADIANS, frontLon * SG_DEGREES_TO_RADIANS, alt, points3d[5]);
geo_direct_wgs_84(alt, backLat, backLon, runway->_heading + 90, width, &tempLat, &tempLon, &az);
geo_direct_wgs_84(alt, backLat, backLon, heading + 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[0]);
geo_direct_wgs_84(alt, backLat, backLon, runway->_heading - 90, width, &tempLat, &tempLon, &az);
geo_direct_wgs_84(alt, backLat, backLon, heading - 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[1]);
geo_direct_wgs_84(alt, frontLat, frontLon, runway->_heading - 90, width, &tempLat, &tempLon, &az);
geo_direct_wgs_84(alt, frontLat, frontLon, heading - 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[2]);
geo_direct_wgs_84(alt, frontLat, frontLon, runway->_heading + 90, width, &tempLat, &tempLon, &az);
geo_direct_wgs_84(alt, frontLat, frontLon, heading + 90, width, &tempLat, &tempLon, &az);
sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[3]);
}
@ -386,8 +389,8 @@ void runway_instr::drawArrow()
Point3D ac(0.0), rwy(0.0);
ac.setlat(current_aircraft.fdm_state->get_Latitude_deg());
ac.setlon(current_aircraft.fdm_state->get_Longitude_deg());
rwy.setlat(runway->_lat);
rwy.setlon(runway->_lon);
rwy.setlat(runway->latitude());
rwy.setlon(runway->longitude());
float theta = GetHeadingFromTo(ac, rwy);
theta -= fgGetDouble("/orientation/heading-deg");
theta = -theta;

View file

@ -4233,26 +4233,12 @@ MK_VIII::Mode6Handler::test_runway (const FGRunway *_runway)
if (_runway->_length < mk->conf.runway_database)
return false;
// get position of threshold
double latitude, longitude, az;
geo_direct_wgs_84(0,
_runway->_lat,
_runway->_lon,
get_reciprocal_heading(_runway->_heading),
_runway->_length / 2 * SG_FEET_TO_METER,
&latitude,
&longitude,
&az);
SGGeod pos(
SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()));
// get distance to threshold
double distance, az1, az2;
geo_inverse_wgs_84(0,
mk_data(gps_latitude).get(),
mk_data(gps_longitude).get(),
latitude,
longitude,
&az1, &az2, &distance);
SGGeodesy::inverse(pos, _runway->threshold(), az1, az2, distance);
return distance * SG_METER_TO_NM <= 5;
}
@ -4475,9 +4461,9 @@ MK_VIII::TCFHandler::get_azimuth_difference (const FGRunway *_runway)
{
return get_azimuth_difference(mk_data(gps_latitude).get(),
mk_data(gps_longitude).get(),
_runway->_lat,
_runway->_lon,
_runway->_heading);
_runway->latitude(),
_runway->longitude(),
_runway->headingDeg());
}
// Selects the most likely intended destination runway of @airport,

View file

@ -145,7 +145,6 @@ bool FGNavList::add( FGNavRecord *n )
return true;
}
FGNavRecord *FGNavList::findByFreq( double freq, double lon, double lat, double elev )
{
const nav_list_type& stations = navaids[(int)(freq*100.0 + 0.5)];
@ -168,69 +167,6 @@ FGNavRecord *FGNavList::findByIdent( const char* ident,
}
nav_list_type FGNavList::findFirstByIdent( const string& ident, fg_nav_types type, bool exact)
{
nav_list_type n2;
n2.clear();
if ((type != FG_NAV_VOR) && (type != FG_NAV_NDB)) {
return n2;
}
nav_ident_map_iterator it;
if(exact) {
it = ident_navaids.find(ident);
} else {
bool typeMatch = false;
int safety_count = 0;
it = ident_navaids.lower_bound(ident);
while(!typeMatch) {
nav_list_type n0 = it->second;
// local copy, so we should be able to do anything with n0.
// Remove the types that don't match request.
for(nav_list_iterator it0 = n0.begin(); it0 != n0.end();) {
FGNavRecord* nv = *it0;
if(nv->type() == type) {
typeMatch = true;
++it0;
} else {
it0 = n0.erase(it0);
}
}
if(typeMatch) {
return(n0);
}
if(it == ident_navaids.begin()) {
// We didn't find a match before reaching the beginning of the map
n0.clear();
return(n0);
}
safety_count++;
if(safety_count == 1000000) {
SG_LOG(SG_INSTR, SG_ALERT,
"safety_count triggered exit from while loop in findFirstByIdent!");
break;
}
++it;
if(it == ident_navaids.end()) {
n0.clear();
return(n0);
}
}
}
if(it == ident_navaids.end()) {
n2.clear();
return(n2);
} else {
nav_list_type n1 = it->second;
n2.clear();
for(nav_list_iterator it2 = n1.begin(); it2 != n1.end(); ++it2) {
FGNavRecord* nv = *it2;
if(nv->type() == type) n2.push_back(nv);
}
return(n2);
}
}
// Given an Ident and optional freqency, return the first matching

View file

@ -90,12 +90,6 @@ public:
// locate closest item in the DB matching the requested ident
FGNavRecord *findByIdent( const char* ident, const double lon, const double lat );
// Find items of requested type with closest exact or subsequent ident
// (by ASCII code value) to that supplied.
// Supplying true for exact forces only exact matches to be returned (similar to above function)
// Returns an empty list if no match found - calling function should check for this!
nav_list_type findFirstByIdent( const string& ident, FGPositioned::Type type, bool exact = false );
// Given an Ident and optional freqency, return the first matching
// station.
FGNavRecord *findByIdentAndFreq( const char* ident,

View file

@ -37,10 +37,9 @@
#include "Main/fg_props.hxx"
FGNavRecord::FGNavRecord(Type aTy, const std::string& aIdent,
const std::string& aName,
double lat, double lon, double aElevFt,
const std::string& aName, const SGGeod& aPos,
int aFreq, int aRange, double aMultiuse) :
FGPositioned(aTy, aIdent, lat, lon, aElevFt),
FGPositioned(aTy, aIdent, aPos),
freq(aFreq),
range(aRange),
multiuse(aMultiuse),
@ -129,8 +128,8 @@ FGNavRecord* FGNavRecord::createFromStream(std::istream& aStream)
}
FGNavRecord* result = new FGNavRecord(type, ident,
simgear::strutils::strip(name),
lat, lon, elev_ft, freq, range, multiuse);
simgear::strutils::strip(name), SGGeod::fromDegFt(lon, lat, elev_ft),
freq, range, multiuse);
return result;
}
@ -199,7 +198,7 @@ void FGNavRecord::alignLocaliserWithRunway(FGRunway* aRunway, double aThreshold)
set_multiuse( aRunway->headingDeg() );
} else {
SG_LOG(SG_GENERAL, SG_WARN, "localizer:" << ident() << ", aligning with runway "
<< aRunway->_rwy_no << " exceeded heading threshold");
<< aRunway->ident() << " exceeded heading threshold");
}
}

View file

@ -72,7 +72,7 @@ public:
static FGNavRecord* createFromStream(std::istream& aStream);
FGNavRecord(Type type, const std::string& ident, const std::string& name,
double lat, double lon, double aElevFt,
const SGGeod& aPos,
int freq, int range, double multiuse);
inline double get_lon() const { return longitude(); } // degrees

View file

@ -71,8 +71,10 @@ static void
addToIndices(FGPositioned* aPos)
{
assert(aPos);
global_namedIndex.insert(global_namedIndex.begin(),
std::make_pair(aPos->ident(), aPos));
if (!aPos->ident().empty()) {
global_namedIndex.insert(global_namedIndex.begin(),
std::make_pair(aPos->ident(), aPos));
}
SpatialPositionedIndex::iterator it = bucketEntryForPositioned(aPos);
it->second.insert(aPos);
@ -83,14 +85,16 @@ removeFromIndices(FGPositioned* aPos)
{
assert(aPos);
NamedPositionedIndex::iterator it = global_namedIndex.find(aPos->ident());
while (it != global_namedIndex.end() && (it->first == aPos->ident())) {
if (it->second == aPos) {
global_namedIndex.erase(it);
break;
}
if (!aPos->ident().empty()) {
NamedPositionedIndex::iterator it = global_namedIndex.find(aPos->ident());
while (it != global_namedIndex.end() && (it->first == aPos->ident())) {
if (it->second == aPos) {
global_namedIndex.erase(it);
break;
}
++it;
++it;
} // of multimap walk
}
SpatialPositionedIndex::iterator sit = bucketEntryForPositioned(aPos);
@ -271,15 +275,13 @@ namedFindClosest(const std::string& aIdent, const SGGeod& aOrigin, FGPositioned:
NamedPositionedIndex::const_iterator it = range.first;
for (; it != range.second; ++it) {
// filter by type
FGPositioned::Type ty = it->second->type();
if (aFilter && !aFilter->pass(range.first->second)) {
continue;
}
// find distance
double d, az1, az2;
SGGeodesy::inverse(aOrigin, it->second->geod(), az2, az2, d);
SGGeodesy::inverse(aOrigin, it->second->geod(), az1, az2, d);
if (d < minDist) {
minDist = d;
result = it->second;
@ -336,22 +338,17 @@ spatialGetClosest(const SGGeod& aPos, unsigned int aN, double aCutoffNm, FGPosit
///////////////////////////////////////////////////////////////////////////////
FGPositioned::FGPositioned(Type ty, const std::string& aIdent, double aLat, double aLon, double aElev) :
mType(ty),
mPosition(SGGeod::fromDegFt(aLon, aLat, aElev)),
mIdent(aIdent)
{
addToIndices(this);
SGReferenced::get(this); // hold an owning ref, for the moment
}
FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos) :
FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos, bool aIndexed) :
mType(ty),
mPosition(aPos),
mIdent(aIdent)
{
addToIndices(this);
SGReferenced::get(this); // hold an owning ref, for the moment
if (aIndexed) {
assert(ty != TAXIWAY);
addToIndices(this);
}
}
FGPositioned::~FGPositioned()

View file

@ -173,14 +173,15 @@ public:
*/
static const char* nameForType(Type aTy);
protected:
FGPositioned(Type ty, const std::string& aIdent, double aLat, double aLon, double aElev);
FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos);
FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos, bool aIndex = true);
SGGeod mPosition; // can't be const right now
// can't be const right now, navrecord at least needs to fix up the position
// after navaids are parsed
SGGeod mPosition;
Type mType;
std::string mIdent;
const Type mType;
const std::string mIdent;
};
#endif // of FG_POSITIONED_HXX