]> git.mxchange.org Git - flightgear.git/blobdiff - src/Navaids/positioned.cxx
Merge branch 'master' into next
[flightgear.git] / src / Navaids / positioned.cxx
index d1e34373e0017c1e2d2cd9ab68192f9b264c67af..f43e4b82f2eb9ced5192bf31837cbac1a3633f54 100644 (file)
@@ -62,11 +62,17 @@ public:
   {
     return a->type() < b;
   }
-  
+
   bool operator()(const FGPositioned::Type a, const FGPositioned* b) const
   {
     return a < b->type();
   }
+
+  // The operator below is required by VS2005 in debug mode
+  bool operator()(const FGPositioned* a, const FGPositioned* b) const
+  {
+    return a->type() < b->type();
+  }
 };
 
 
@@ -260,22 +266,22 @@ namedFindClosest(const std::string& aIdent, const SGGeod& aOrigin, FGPositioned:
   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;
     }
   }
   
@@ -441,7 +447,7 @@ FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPo
   SGReferenced::get(this); // hold an owning ref, for the moment
   
   if (aIndexed) {
-    assert(ty != TAXIWAY);
+    assert(ty != TAXIWAY && ty != PAVEMENT);
     addToIndices(this);
   }
 }
@@ -469,6 +475,7 @@ const char* FGPositioned::nameForType(Type aTy)
  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";
@@ -543,6 +550,7 @@ FGPositioned::findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm
   return spatialGetClosest(aPos, aN, aCutoffNm, aFilter);
 }
 
+/*
 FGPositionedRef
 FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter)
 {
@@ -570,5 +578,47 @@ FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId
   }
   
   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.  
 }
+