X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=src%2FNavaids%2Fpositioned.cxx;h=89d41475583e0a8e87a353e53dd592033b8bc836;hb=69baf3a9d6adb645325e7bfc0305b09604379d9f;hp=bced11728b6064a703689c3fb499dbddb75c5e30;hpb=458edb933903836ac10b2acd9ef68e06e2a04470;p=flightgear.git diff --git a/src/Navaids/positioned.cxx b/src/Navaids/positioned.cxx index bced11728..89d414755 100644 --- a/src/Navaids/positioned.cxx +++ b/src/Navaids/positioned.cxx @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -53,6 +54,16 @@ static void validateSGGeod(const SGGeod& geod) } } +static bool validateFilter(FGPositioned::Filter* filter) +{ + if (filter->maxType() < filter->minType()) { + SG_LOG(SG_GENERAL, SG_WARN, "invalid positioned filter specified"); + return false; + } + + return true; +} + /////////////////////////////////////////////////////////////////////////////// @@ -73,10 +84,25 @@ FGPositioned::~FGPositioned() FGPositioned* FGPositioned::createUserWaypoint(const std::string& aIdent, const SGGeod& aPos) { - PositionedID id = NavDataCache::instance()->createUserWaypoint(aIdent, aPos); - return NavDataCache::instance()->loadById(id); + NavDataCache* cache = NavDataCache::instance(); + TypeFilter filter(WAYPOINT); + FGPositionedList existing = cache->findAllWithIdent(aIdent, &filter, true); + if (!existing.empty()) { + SG_LOG(SG_NAVAID, SG_WARN, "attempt to insert duplicate WAYPOINT:" << aIdent); + return existing.front().ptr(); + } + + PositionedID id = cache->createPOI(WAYPOINT, aIdent, aPos); + return cache->loadById(id); +} + +bool FGPositioned::deleteUserWaypoint(const std::string& aIdent) +{ + NavDataCache* cache = NavDataCache::instance(); + return cache->removePOI(WAYPOINT, aIdent); } + const SGVec3d& FGPositioned::cart() const { @@ -111,12 +137,21 @@ FGPositioned::Type FGPositioned::typeFromName(const std::string& aName) {"ground", FREQ_GROUND}, {"approach", FREQ_APP_DEP}, {"departure", FREQ_APP_DEP}, + {"runway", RUNWAY}, + {"helipad", HELIPAD}, + {"country", COUNTRY}, + {"city", CITY}, + {"town", TOWN}, + {"village", VILLAGE}, + // aliases + {"localizer", LOC}, {"gnd", FREQ_GROUND}, {"twr", FREQ_TOWER}, {"waypoint", WAYPOINT}, {"apt", AIRPORT}, {"arpt", AIRPORT}, + {"rwy", RUNWAY}, {"any", INVALID}, {"all", INVALID}, @@ -139,6 +174,7 @@ const char* FGPositioned::nameForType(Type aTy) { switch (aTy) { case RUNWAY: return "runway"; + case HELIPAD: return "helipad"; case TAXIWAY: return "taxiway"; case PAVEMENT: return "pavement"; case PARKING: return "parking stand"; @@ -146,7 +182,7 @@ const char* FGPositioned::nameForType(Type aTy) case VOR: return "VOR"; case NDB: return "NDB"; case ILS: return "ILS"; - case LOC: return "localiser"; + case LOC: return "localizer"; case GS: return "glideslope"; case OM: return "outer-marker"; case MM: return "middle-marker"; @@ -165,6 +201,10 @@ const char* FGPositioned::nameForType(Type aTy) case FREQ_UNICOM: return "unicom"; case FREQ_APP_DEP: return "approach-departure"; case TAXI_NODE: return "taxi-node"; + case COUNTRY: return "country"; + case CITY: return "city"; + case TOWN: return "town"; + case VILLAGE: return "village"; default: return "unknown"; } @@ -187,7 +227,8 @@ FGPositioned::findFirstWithIdent(const std::string& aIdent, Filter* aFilter) return NULL; } - List r = NavDataCache::instance()->findAllWithIdent(aIdent, aFilter, true); + FGPositionedList r = + NavDataCache::instance()->findAllWithIdent(aIdent, aFilter, true); if (r.empty()) { return NULL; } @@ -195,26 +236,55 @@ FGPositioned::findFirstWithIdent(const std::string& aIdent, Filter* aFilter) return r.front(); } -FGPositioned::List +FGPositionedList FGPositioned::findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilter) { validateSGGeod(aPos); - List result; + if (!validateFilter(aFilter)) { + return FGPositionedList(); + } + + FGPositionedList result; Octree::findAllWithinRange(SGVec3d::fromGeod(aPos), - aRangeNm * SG_NM_TO_METER, aFilter, result); + aRangeNm * SG_NM_TO_METER, aFilter, result, 0xffffff); + return result; +} + +FGPositionedList +FGPositioned::findWithinRangePartial(const SGGeod& aPos, double aRangeNm, Filter* aFilter, bool& aPartial) +{ + validateSGGeod(aPos); + + if (!validateFilter(aFilter)) { + return FGPositionedList(); + } + + int limitMsec = 32; + FGPositionedList result; + aPartial = Octree::findAllWithinRange(SGVec3d::fromGeod(aPos), + aRangeNm * SG_NM_TO_METER, aFilter, result, + limitMsec); return result; } -FGPositioned::List +FGPositionedList FGPositioned::findAllWithIdent(const std::string& aIdent, Filter* aFilter, bool aExact) { + if (!validateFilter(aFilter)) { + return FGPositionedList(); + } + return NavDataCache::instance()->findAllWithIdent(aIdent, aFilter, aExact); } -FGPositioned::List +FGPositionedList FGPositioned::findAllWithName(const std::string& aName, Filter* aFilter, bool aExact) { + if (!validateFilter(aFilter)) { + return FGPositionedList(); + } + return NavDataCache::instance()->findAllWithName(aName, aFilter, aExact); } @@ -223,7 +293,11 @@ FGPositioned::findClosest(const SGGeod& aPos, double aCutoffNm, Filter* aFilter) { validateSGGeod(aPos); - List l(findClosestN(aPos, 1, aCutoffNm, aFilter)); + if (!validateFilter(aFilter)) { + return NULL; + } + + FGPositionedList l(findClosestN(aPos, 1, aCutoffNm, aFilter)); if (l.empty()) { return NULL; } @@ -232,25 +306,38 @@ FGPositioned::findClosest(const SGGeod& aPos, double aCutoffNm, Filter* aFilter) return l.front(); } -FGPositioned::List +FGPositionedList FGPositioned::findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* aFilter) { validateSGGeod(aPos); - List result; - Octree::findNearestN(SGVec3d::fromGeod(aPos), aN, aCutoffNm * SG_NM_TO_METER, aFilter, result); + FGPositionedList result; + int limitMsec = 0xffff; + Octree::findNearestN(SGVec3d::fromGeod(aPos), aN, aCutoffNm * SG_NM_TO_METER, aFilter, result, limitMsec); return result; } - + +FGPositionedList +FGPositioned::findClosestNPartial(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* aFilter, bool &aPartial) +{ + validateSGGeod(aPos); + + FGPositionedList result; + int limitMsec = 32; + aPartial = Octree::findNearestN(SGVec3d::fromGeod(aPos), aN, aCutoffNm * SG_NM_TO_METER, aFilter, result, + limitMsec); + return result; +} + void -FGPositioned::sortByRange(List& aResult, const SGGeod& aPos) +FGPositioned::sortByRange(FGPositionedList& aResult, const SGGeod& aPos) { validateSGGeod(aPos); SGVec3d cartPos(SGVec3d::fromGeod(aPos)); // computer ordering values Octree::FindNearestResults r; - List::iterator it = aResult.begin(), lend = aResult.end(); + FGPositionedList::iterator it = aResult.begin(), lend = aResult.end(); for (; it != lend; ++it) { double d2 = distSqr((*it)->cart(), cartPos); r.push_back(Octree::OrderedPositioned(*it, d2)); @@ -272,9 +359,15 @@ void FGPositioned::modifyPosition(const SGGeod& newPos) const_cast(mCart) = SGVec3d::fromGeod(newPos); } +//------------------------------------------------------------------------------ +FGPositionedRef FGPositioned::loadByIdImpl(PositionedID id) +{ + return flightgear::NavDataCache::instance()->loadById(id); +} + FGPositioned::TypeFilter::TypeFilter(Type aTy) : - mMinType(aTy), - mMaxType(aTy) + mMinType(LAST_TYPE), + mMaxType(INVALID) { addType(aTy); } @@ -290,6 +383,23 @@ void FGPositioned::TypeFilter::addType(Type aTy) mMaxType = std::max(mMaxType, aTy); } +FGPositioned::TypeFilter +FGPositioned::TypeFilter::fromString(const std::string& aFilterSpec) +{ + if (aFilterSpec.empty()) { + throw sg_format_exception("empty filter spec:", aFilterSpec); + } + + string_list parts = simgear::strutils::split(aFilterSpec, ","); + TypeFilter f; + + BOOST_FOREACH(std::string token, parts) { + f.addType(typeFromName(token)); + } + + return f; +} + bool FGPositioned::TypeFilter::pass(FGPositioned* aPos) const { @@ -300,7 +410,9 @@ FGPositioned::TypeFilter::pass(FGPositioned* aPos) const std::vector::const_iterator it = types.begin(), end = types.end(); for (; it != end; ++it) { - return aPos->type() == *it; + if (aPos->type() == *it) { + return true; + } } return false;