SGVec3d cartOrigin(SGVec3d::fromGeod(aOrigin));
for (; it != range.second; ++it) {
- FGPositioned::Type ty = range.first->second->type();
+ FGPositioned* r = it->second;
if (aFilter) {
- if (aFilter->hasTypeRange() && !aFilter->passType(ty)) {
+ if (aFilter->hasTypeRange() && !aFilter->passType(r->type())) {
continue;
}
- if (!aFilter->pass(range.first->second)) {
+ if (!aFilter->pass(r)) {
continue;
}
}
// find distance
- double d2 = distSqr(cartOrigin, it->second->cart());
+ double d2 = distSqr(cartOrigin, r->cart());
if (d2 < minDist) {
minDist = d2;
- result = it->second;
+ result = r;
}
}
SGReferenced::get(this); // hold an owning ref, for the moment
if (aIndexed) {
- assert(ty != TAXIWAY);
+ assert(ty != TAXIWAY && ty != PAVEMENT);
addToIndices(this);
}
}
switch (aTy) {
case RUNWAY: return "runway";
case TAXIWAY: return "taxiway";
+ case PAVEMENT: return "pavement";
case PARK_STAND: return "parking stand";
case FIX: return "fix";
case VOR: return "VOR";
return spatialGetClosest(aPos, aN, aCutoffNm, aFilter);
}
+/*
FGPositionedRef
FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter)
{
}
return NULL; // fell out, no match in range
+}*/
+
+FGPositionedRef
+FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter)
+{
+ // It is essential to bound our search, to avoid iterating all the way to the end of the database.
+ // Do this by generating a second ID with the final character incremented by 1.
+ // e.g., if the partial ID is "KI", we wish to search "KIxxx" but not "KJ".
+ 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 (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;
+ }
+ }
+
+ // 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.
}
+