From 7d5d75609533c98fa5ea93829cdd3bb06ee6ebe8 Mon Sep 17 00:00:00 2001 From: jmt Date: Wed, 24 Dec 2008 14:48:30 +0000 Subject: [PATCH] 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. --- src/Airports/apt_loader.cxx | 17 +++++---- src/Airports/runways.cxx | 9 ++--- src/Airports/runways.hxx | 20 +++++------ src/Cockpit/hud_rwy.cxx | 21 ++++++----- src/Instrumentation/mk_viii.cxx | 28 ++++----------- src/Navaids/navlist.cxx | 64 --------------------------------- src/Navaids/navlist.hxx | 6 ---- src/Navaids/navrecord.cxx | 11 +++--- src/Navaids/navrecord.hxx | 2 +- src/Navaids/positioned.cxx | 47 ++++++++++++------------ src/Navaids/positioned.hxx | 11 +++--- 11 files changed, 74 insertions(+), 162 deletions(-) diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx index cb64a633e..646aedc5c 100644 --- a/src/Airports/apt_loader.cxx +++ b/src/Airports/apt_loader.cxx @@ -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 ) { diff --git a/src/Airports/runways.cxx b/src/Airports/runways.cxx index cc2c35015..84c064263 100644 --- a/src/Airports/runways.cxx +++ b/src/Airports/runways.cxx @@ -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; diff --git a/src/Airports/runways.hxx b/src/Airports/runways.hxx index 9289e3404..a198f492c 100644 --- a/src/Airports/runways.hxx +++ b/src/Airports/runways.hxx @@ -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 diff --git a/src/Cockpit/hud_rwy.cxx b/src/Cockpit/hud_rwy.cxx index fd216479b..de1b7d2b8 100644 --- a/src/Cockpit/hud_rwy.cxx +++ b/src/Cockpit/hud_rwy.cxx @@ -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; diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx index d4f20e7c5..6990d38a3 100755 --- a/src/Instrumentation/mk_viii.cxx +++ b/src/Instrumentation/mk_viii.cxx @@ -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, diff --git a/src/Navaids/navlist.cxx b/src/Navaids/navlist.cxx index 0b62054fb..eb2ef38ef 100644 --- a/src/Navaids/navlist.cxx +++ b/src/Navaids/navlist.cxx @@ -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 diff --git a/src/Navaids/navlist.hxx b/src/Navaids/navlist.hxx index a1efefcf6..4f2bc5255 100644 --- a/src/Navaids/navlist.hxx +++ b/src/Navaids/navlist.hxx @@ -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, diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx index 2e0cf1633..e85c43c4f 100644 --- a/src/Navaids/navrecord.cxx +++ b/src/Navaids/navrecord.cxx @@ -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"); } } diff --git a/src/Navaids/navrecord.hxx b/src/Navaids/navrecord.hxx index 36cb4f297..55a02af7e 100644 --- a/src/Navaids/navrecord.hxx +++ b/src/Navaids/navrecord.hxx @@ -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 diff --git a/src/Navaids/positioned.cxx b/src/Navaids/positioned.cxx index 07af55b1c..1f3575c9e 100644 --- a/src/Navaids/positioned.cxx +++ b/src/Navaids/positioned.cxx @@ -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() diff --git a/src/Navaids/positioned.hxx b/src/Navaids/positioned.hxx index 4a0bd4c20..ff3666290 100644 --- a/src/Navaids/positioned.hxx +++ b/src/Navaids/positioned.hxx @@ -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