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:
parent
335584e29c
commit
7d5d756095
11 changed files with 74 additions and 162 deletions
|
@ -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 ) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
int _surface_code;
|
||||
double _heading;
|
||||
double _length;
|
||||
double _width;
|
||||
|
||||
int _surface_code;
|
||||
};
|
||||
|
||||
#endif // _FG_RUNWAYS_HXX
|
||||
|
|
|
@ -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;
|
||||
|
||||
geo_direct_wgs_84(alt, runway->_lat, runway->_lon, runway->_heading, length, &backLat, &backLon, &az);
|
||||
double runwayLon = runway->geod().getLongitudeDeg(),
|
||||
runwayLat = runway->geod().getLatitudeDeg();
|
||||
double heading = runway->headingDeg();
|
||||
|
||||
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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
++it;
|
||||
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;
|
||||
} // 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()
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue