diff --git a/src/Autopilot/route_mgr.cxx b/src/Autopilot/route_mgr.cxx index e657f2d63..b52fa4fe8 100644 --- a/src/Autopilot/route_mgr.cxx +++ b/src/Autopilot/route_mgr.cxx @@ -281,24 +281,24 @@ bool FGRouteMgr::build() { } -int FGRouteMgr::new_waypoint( const string& target, int n ) { - SGWayPoint *wp = 0; - int type = make_waypoint( &wp, target ); - - if (wp) { - add_waypoint( *wp, n ); - delete wp; - - if ( !near_ground() ) - fgSetString( "/autopilot/locks/heading", "true-heading-hold" ); +void FGRouteMgr::new_waypoint( const string& target, int n ) { + SGWayPoint* wp = make_waypoint( target ); + if (!wp) { + return; + } + + add_waypoint( *wp, n ); + delete wp; + + if ( !near_ground() ) { + fgSetString( "/autopilot/locks/heading", "true-heading-hold" ); } - return type; } -int FGRouteMgr::make_waypoint( SGWayPoint **wp, const string& tgt ) { +SGWayPoint* FGRouteMgr::make_waypoint(const string& tgt ) { string target = tgt; - + // make upper case for (unsigned int i = 0; i < target.size(); i++) if (target[i] >= 'a' && target[i] <= 'z') @@ -321,57 +321,28 @@ int FGRouteMgr::make_waypoint( SGWayPoint **wp, const string& tgt ) { double lat = atof( target.c_str() + pos + 1); SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint lon = " << lon << ", lat = " << lat ); - *wp = new SGWayPoint( lon, lat, alt, SGWayPoint::WGS84, target ); - return 1; - } + return new SGWayPoint( lon, lat, alt, SGWayPoint::WGS84, target ); + } - // check for airport id - const FGAirport *apt = fgFindAirportID( target ); - if (apt) { - SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (airport) = " << target ); - *wp = new SGWayPoint( apt->getLongitude(), apt->getLatitude(), alt, SGWayPoint::WGS84, target ); - return 2; - } - - double lat, lon; - // The base lon/lat are determined by the last WP, - // or the current pos if the WP list is empty. - const int wps = this->size(); - - if (wps > 0) { - SGWayPoint wp = get_waypoint(wps-1); - lat = wp.get_target_lat(); - lon = wp.get_target_lon(); + SGGeod basePosition; + if (route->size() > 0) { + SGWayPoint wp = get_waypoint(route->size()-1); + basePosition = SGGeod::fromDeg(wp.get_target_lon(), wp.get_target_lat()); } else { - lat = fgGetNode("/position/latitude-deg")->getDoubleValue(); - lon = fgGetNode("/position/longitude-deg")->getDoubleValue(); + // route is empty, use current position + basePosition = SGGeod::fromDeg( + fgGetNode("/position/longitude-deg")->getDoubleValue(), + fgGetNode("/position/latitude-deg")->getDoubleValue()); } - // check for fix id - FGFix* f; - double heading; - double dist; - if ( globals->get_fixlist()->query_and_offset( target, lon, lat, 0, f, &heading, &dist ) ) { - SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (fix) = " << target ); - *wp = new SGWayPoint( f->get_lon(), f->get_lat(), alt, SGWayPoint::WGS84, target ); - return 3; + FGPositionedRef p = FGPositioned::findClosestWithIdent(target, basePosition); + if (!p) { + SG_LOG( SG_GENERAL, SG_INFO, "Unable to find FGPositioned with ident:" << target); + return NULL; } - - // Try finding a nav matching the ID - lat *= SGD_DEGREES_TO_RADIANS; - lon *= SGD_DEGREES_TO_RADIANS; - - SG_LOG( SG_GENERAL, SG_INFO, "Looking for nav " << target << " at " << lon << " " << lat); - - if (FGNavRecord* nav = globals->get_navlist()->findByIdent(target.c_str(), lon, lat)) { - SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (nav) = " << target ); - *wp = new SGWayPoint( nav->get_lon(), nav->get_lat(), alt, SGWayPoint::WGS84, target ); - return 4; - } - - // unknown target - return 0; + + return new SGWayPoint(p->longitude(), p->latitude(), p->elevation(), SGWayPoint::WGS84, target); } diff --git a/src/Autopilot/route_mgr.hxx b/src/Autopilot/route_mgr.hxx index 67a27d7c8..f409a8c4e 100644 --- a/src/Autopilot/route_mgr.hxx +++ b/src/Autopilot/route_mgr.hxx @@ -93,7 +93,7 @@ private: SGPropertyNode_ptr mirror; bool altitude_set; - int make_waypoint( SGWayPoint **wp, const string& target ); + SGWayPoint* make_waypoint(const string& target); void update_mirror(); bool near_ground(); @@ -110,7 +110,7 @@ public: bool build (); - int new_waypoint( const string& tgt_alt, int n = -1 ); + void new_waypoint( const string& tgt_alt, int n = -1 ); void add_waypoint( const SGWayPoint& wp, int n = -1 ); SGWayPoint pop_waypoint( int i = 0 ); diff --git a/src/Navaids/positioned.cxx b/src/Navaids/positioned.cxx index e2a5b8d1d..a89d28f29 100644 --- a/src/Navaids/positioned.cxx +++ b/src/Navaids/positioned.cxx @@ -182,38 +182,31 @@ spatialFindTyped(const SGGeod& aPos, double aRange, FGPositioned::Type aLower, F } /** - * Cartesian range predicate. Note that for really long ranges, might need to - * to use geodetic / geocentric distance instead */ class RangePredictate { public: - RangePredictate(const Point3D& aOrigin, double aRange) : + RangePredictate(const SGGeod& aOrigin, double aRange) : mOrigin(aOrigin), - mRangeSquared(aRange * aRange) + mRange(aRange) { ; } bool operator()(const FGPositionedRef& aPos) { - Point3D p(Point3D::fromSGGeod(aPos->geod())); - bool ok = (mOrigin.distance3Dsquared(p) > mRangeSquared); - if (ok) { - double x = sqrt(mOrigin.distance3Dsquared(p) - mRangeSquared); - x *= SG_METER_TO_NM; - //std::cout << "pos:" << aPos->ident() << " failed range check by " << x << std::endl; - } - return ok; + double d, az1, az2; + SGGeodesy::inverse(aPos->geod(), mOrigin, az1, az2, d); + return (d > mRange); } private: - Point3D mOrigin; - double mRangeSquared; + SGGeod mOrigin; + double mRange; }; static void filterListByRange(const SGGeod& aPos, double aRange, FGPositioned::List& aResult) { - RangePredictate pred(Point3D::fromSGGeod(aPos), aRange * SG_NM_TO_METER); + RangePredictate pred(aPos, aRange * SG_NM_TO_METER); FGPositioned::List::iterator newEnd; newEnd = std::remove_if(aResult.begin(), aResult.end(), pred); aResult.erase(newEnd, aResult.end()); @@ -223,17 +216,19 @@ class DistanceOrdering { public: DistanceOrdering(const SGGeod& aPos) : - mPos(Point3D::fromSGGeod(aPos)) + mPos(aPos) { } bool operator()(const FGPositionedRef& a, const FGPositionedRef& b) const { - return mPos.distance3Dsquared(Point3D::fromSGGeod(a->geod())) < - mPos.distance3Dsquared(Point3D::fromSGGeod(b->geod())); + double dA, dB, az1, az2; + SGGeodesy::inverse(mPos, a->geod(), az1, az2, dA); + SGGeodesy::inverse(mPos, b->geod(), az1, az2, dB); + return dA < dB; } private: - Point3D mPos; + SGGeod mPos; }; static void @@ -247,7 +242,9 @@ namedFindClosestTyped(const std::string& aIdent, const SGGeod& aOrigin, FGPositioned::Type aLower, FGPositioned::Type aUpper) { NamedIndexRange range = global_namedIndex.equal_range(aIdent); - if (range.first == range.second) return NULL; + if (range.first == range.second) { + return NULL; + } // common case, only one result. looks a bit ugly because these are // sequential iterators, not random-access ones @@ -265,21 +262,21 @@ namedFindClosestTyped(const std::string& aIdent, const SGGeod& aOrigin, // multiple matches, we need to actually check the distance to each one double minDist = HUGE_VAL; FGPositionedRef result; - Point3D origin(Point3D::fromSGGeod(aOrigin)); - - for (; range.first != range.second; ++range.first) { + NamedPositionedIndex::const_iterator it = range.first; + + for (; it != range.second; ++it) { // filter by type - FGPositioned::Type ty = range.first->second->type(); + FGPositioned::Type ty = it->second->type(); if ((ty < aLower) || (ty > aUpper)) { continue; } // find distance - Point3D p(Point3D::fromSGGeod(range.first->second->geod())); - double ds = origin.distance3Dsquared(p); - if (ds < minDist) { - minDist = ds; - result = range.first->second; + double d, az1, az2; + SGGeodesy::inverse(aOrigin, it->second->geod(), az2, az2, d); + if (d < minDist) { + minDist = d; + result = it->second; } } @@ -340,26 +337,25 @@ FGPositioned::FGPositioned() : FGPositioned::FGPositioned(Type ty, const std::string& aIdent, double aLat, double aLon, double aElev) : mType(ty), - mIdent(aIdent), - mPosition(SGGeod::fromDegFt(aLon, aLat, aElev)) + mPosition(SGGeod::fromDegFt(aLon, aLat, aElev)), + mIdent(aIdent) { - //addToIndices(this); - //SGReferenced::get(this); // hold an owning ref, for the moment + addToIndices(this); + SGReferenced::get(this); // hold an owning ref, for the moment } FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos) : mType(ty), - mIdent(aIdent), - mPosition(aPos) + mPosition(aPos), + mIdent(aIdent) { - //addToIndices(this); - //SGReferenced::get(this); // hold an owning ref, for the moment + addToIndices(this); + SGReferenced::get(this); // hold an owning ref, for the moment } FGPositioned::~FGPositioned() { - //std::cout << "~FGPositioned:" << mIdent << std::endl; - //removeFromIndices(this); + removeFromIndices(this); } SGBucket