Further extensions to FGPositioned to support ongoing GPS work.
This commit is contained in:
parent
04b30f322d
commit
5755b7ae0e
2 changed files with 100 additions and 32 deletions
|
@ -474,6 +474,10 @@ FGPositioned::cart() const
|
||||||
|
|
||||||
FGPositioned::Type FGPositioned::typeFromName(const std::string& aName)
|
FGPositioned::Type FGPositioned::typeFromName(const std::string& aName)
|
||||||
{
|
{
|
||||||
|
if (aName.empty() || (aName == "")) {
|
||||||
|
return INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* _name;
|
const char* _name;
|
||||||
Type _ty;
|
Type _ty;
|
||||||
|
@ -489,7 +493,8 @@ FGPositioned::Type FGPositioned::typeFromName(const std::string& aName)
|
||||||
{"dme", DME},
|
{"dme", DME},
|
||||||
// aliases
|
// aliases
|
||||||
{"waypoint", WAYPOINT},
|
{"waypoint", WAYPOINT},
|
||||||
|
{"apt", AIRPORT},
|
||||||
|
|
||||||
{NULL, INVALID}
|
{NULL, INVALID}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -585,36 +590,6 @@ FGPositioned::findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm
|
||||||
return spatialGetClosest(aPos, aN, aCutoffNm, aFilter);
|
return spatialGetClosest(aPos, aN, aCutoffNm, aFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
FGPositionedRef
|
|
||||||
FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter)
|
|
||||||
{
|
|
||||||
NamedIndexRange range = global_namedIndex.equal_range(aId);
|
|
||||||
for (; range.first != range.second; ++range.first) {
|
|
||||||
FGPositionedRef candidate = range.first->second;
|
|
||||||
if (aCur == candidate) {
|
|
||||||
aCur = NULL; // found our start point, next match will pass
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aFilter) {
|
|
||||||
if (aFilter->hasTypeRange() && !aFilter->passType(candidate->type())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!aFilter->pass(candidate)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aCur) {
|
|
||||||
return candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL; // fell out, no match in range
|
|
||||||
}*/
|
|
||||||
|
|
||||||
FGPositionedRef
|
FGPositionedRef
|
||||||
FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter)
|
FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter)
|
||||||
{
|
{
|
||||||
|
@ -656,4 +631,86 @@ FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId
|
||||||
return NULL; // Reached the end of the valid sequence with no match.
|
return NULL; // Reached the end of the valid sequence with no match.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGPositionedRef
|
||||||
|
FGPositioned::findWithPartialId(const std::string& aId, Filter* aFilter, int aOffset)
|
||||||
|
{
|
||||||
|
// see comment in findNextWithPartialId concerning upperBoundId
|
||||||
|
std::string upperBoundId = aId;
|
||||||
|
upperBoundId[upperBoundId.size()-1]++;
|
||||||
|
NamedPositionedIndex::const_iterator upperBound = global_namedIndex.lower_bound(upperBoundId);
|
||||||
|
|
||||||
|
NamedIndexRange range = global_namedIndex.equal_range(aId);
|
||||||
|
|
||||||
|
while (range.first != upperBound) {
|
||||||
|
for (; range.first != range.second; ++range.first) {
|
||||||
|
FGPositionedRef candidate = range.first->second;
|
||||||
|
if (aFilter) {
|
||||||
|
if (aFilter->hasTypeRange() && !aFilter->passType(candidate->type())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aFilter->pass(candidate)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aOffset == 0) {
|
||||||
|
return candidate;
|
||||||
|
} else {
|
||||||
|
--aOffset; // seen one more valid result, decrement the count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unable to match the filter with this range - try the next range.
|
||||||
|
range = global_namedIndex.equal_range(range.second->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL; // Reached the end of the valid sequence with no match.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper filter which proxies to an inner filter, but also ensures the
|
||||||
|
* ident starts with supplied partial ident.
|
||||||
|
*/
|
||||||
|
class PartialIdentFilter : public FGPositioned::Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PartialIdentFilter(const std::string& ident, FGPositioned::Filter* filter) :
|
||||||
|
_ident(ident),
|
||||||
|
_inner(filter)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
virtual bool pass(FGPositioned* aPos) const
|
||||||
|
{
|
||||||
|
if (!_inner->pass(aPos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (::strncmp(aPos->ident().c_str(), _ident.c_str(), _ident.size()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual FGPositioned::Type minType() const
|
||||||
|
{ return _inner->minType(); }
|
||||||
|
|
||||||
|
virtual FGPositioned::Type maxType() const
|
||||||
|
{ return _inner->maxType(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _ident;
|
||||||
|
FGPositioned::Filter* _inner;
|
||||||
|
};
|
||||||
|
|
||||||
|
FGPositionedRef
|
||||||
|
FGPositioned::findClosestWithPartialId(const SGGeod& aPos, const std::string& aId, Filter* aFilter, int aOffset)
|
||||||
|
{
|
||||||
|
PartialIdentFilter pf(aId, aFilter);
|
||||||
|
List matches = spatialGetClosest(aPos, aOffset + 1, 1000.0, &pf);
|
||||||
|
|
||||||
|
if ((int) matches.size() <= aOffset) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_INFO, "FGPositioned::findClosestWithPartialId, couldn't match enough with prefix:" << aId);
|
||||||
|
return NULL; // couldn't find a match within the cutoff distance
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches[aOffset];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,11 @@ public:
|
||||||
*/
|
*/
|
||||||
static FGPositionedRef findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter = NULL);
|
static FGPositionedRef findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As above, but searches using an offset index
|
||||||
|
*/
|
||||||
|
static FGPositionedRef findWithPartialId(const std::string& aId, Filter* aFilter, int aOffset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all items with the specified ident, and return then sorted by
|
* Find all items with the specified ident, and return then sorted by
|
||||||
* distance from a position
|
* distance from a position
|
||||||
|
@ -182,12 +187,18 @@ public:
|
||||||
* Very large cutoff values will make this slow.
|
* Very large cutoff values will make this slow.
|
||||||
*
|
*
|
||||||
* @result The matches (possibly less than N, depending on the filter and cutoff),
|
* @result The matches (possibly less than N, depending on the filter and cutoff),
|
||||||
* sorted by distance from the search pos
|
* sorted by distance from the search pos
|
||||||
* @param aN - number of matches to find
|
* @param aN - number of matches to find
|
||||||
* @param aCutoffNm - maximum distance to search within, in nautical miles
|
* @param aCutoffNm - maximum distance to search within, in nautical miles
|
||||||
*/
|
*/
|
||||||
static List findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* aFilter = NULL);
|
static List findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* aFilter = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the closest match based on partial id (with an offset to allow selecting the n-th closest).
|
||||||
|
* Cutoff distance is limited internally, to avoid making this very slow.
|
||||||
|
*/
|
||||||
|
static FGPositionedRef findClosestWithPartialId(const SGGeod& aPos, const std::string& aId, Filter* aFilter, int aOffset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map a candidate type string to a real type. Returns INVALID if the string
|
* Map a candidate type string to a real type. Returns INVALID if the string
|
||||||
* does not correspond to a defined type.
|
* does not correspond to a defined type.
|
||||||
|
|
Loading…
Add table
Reference in a new issue