Index: src/Navaids/positioned.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Navaids/positioned.cxx,v
retrieving revision 1.4
diff -u -3 -r1.4 positioned.cxx
--- src/Navaids/positioned.cxx	4 Dec 2008 08:15:36 -0000	1.4
+++ src/Navaids/positioned.cxx	4 Dec 2008 19:53:50 -0000
@@ -98,7 +98,7 @@
 }
 
 static void
-spatialFilterInBucket(const SGBucket& aBucket, const FGPositioned::Filter& aFilter, FGPositioned::List& aResult)
+spatialFilterInBucket(const SGBucket& aBucket, FGPositioned::Filter* aFilter, FGPositioned::List& aResult)
 {
   SpatialPositionedIndex::const_iterator it;
   it = global_spatialIndex.find(aBucket.gen_index());
@@ -109,8 +109,13 @@
   BucketEntry::const_iterator l = it->second.begin();
   BucketEntry::const_iterator u = it->second.end();
 
+  if (!aFilter) { // pass everything
+    aResult.insert(aResult.end(), l, u);
+    return;
+  }
+
   for ( ; l != u; ++l) {
-    if (aFilter(*l)) {
+    if ((*aFilter)(*l)) {
       aResult.push_back(*l);
     }
   }
@@ -118,7 +123,7 @@
 
 static void
 spatialFind(const SGGeod& aPos, double aRange, 
-  const FGPositioned::Filter& aFilter, FGPositioned::List& aResult)
+  FGPositioned::Filter* aFilter, FGPositioned::List& aResult)
 {
   SGBucket buck(aPos);
   double lat = aPos.getLatitudeDeg(),
@@ -135,6 +140,7 @@
   } // of i-iteration  
 }
 
+/*
 class LowerLimitOfType
 {
 public:
@@ -149,6 +155,7 @@
   }
 };
 
+
 static void
 spatialFindTyped(const SGGeod& aPos, double aRange, FGPositioned::Type aLower, FGPositioned::Type aUpper, FGPositioned::List& aResult)
 {
@@ -180,6 +187,7 @@
     } // of j-iteration
   } // of i-iteration  
 }
+*/
 
 /**
  */
@@ -238,8 +246,7 @@
 }
 
 static FGPositionedRef
-namedFindClosestTyped(const std::string& aIdent, const SGGeod& aOrigin, 
-  FGPositioned::Type aLower, FGPositioned::Type aUpper)
+namedFindClosest(const std::string& aIdent, const SGGeod& aOrigin, FGPositioned::Filter* aFilter)
 {
   NamedIndexRange range = global_namedIndex.equal_range(aIdent);
   if (range.first == range.second) {
@@ -251,8 +258,7 @@
   NamedPositionedIndex::const_iterator check = range.first;
   if (++check == range.second) {
     // excellent, only one match in the range - all we care about is the type
-    FGPositioned::Type ty = range.first->second->type();
-    if ((ty < aLower) || (ty > aUpper)) {
+    if (aFilter && !aFilter->pass(range.first->second)) {
       return NULL; // type check failed
     }
     
@@ -267,7 +273,7 @@
   for (; it != range.second; ++it) {
   // filter by type
     FGPositioned::Type ty = it->second->type();
-    if ((ty < aLower) || (ty > aUpper)) {
+    if (aFilter && !aFilter->pass(range.first->second)) {
       continue;
     }
     
@@ -284,7 +290,7 @@
 }
 
 static FGPositioned::List
-spatialGetClosest(const SGGeod& aPos, unsigned int aN, double aCutoffNm, const FGPositioned::Filter& aFilter)
+spatialGetClosest(const SGGeod& aPos, unsigned int aN, double aCutoffNm, FGPositioned::Filter* aFilter)
 {
   FGPositioned::List result;
   int radius = 1; // start at 1, radius 0 is handled explicitly
@@ -381,28 +387,13 @@
 // search / query functions
 
 FGPositionedRef
-FGPositioned::findClosestWithIdent(const std::string& aIdent, double aLat, double aLon)
+FGPositioned::findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter)
 {
-  return findClosestWithIdent(aIdent, SGGeod::fromDeg(aLon, aLat));
-}
-
-FGPositionedRef
-FGPositioned::findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos)
-{
-  return namedFindClosestTyped(aIdent, aPos, INVALID, LAST_TYPE);
+  return namedFindClosest(aIdent, aPos, aFilter);
 }
 
 FGPositioned::List
-FGPositioned::findWithinRangeByType(const SGGeod& aPos, double aRangeNm, Type aTy)
-{
-  List result;
-  spatialFindTyped(aPos, aRangeNm, aTy, aTy, result);
-  filterListByRange(aPos, aRangeNm, result);
-  return result;
-}
-
-FGPositioned::List
-FGPositioned::findWithinRange(const SGGeod& aPos, double aRangeNm, const Filter& aFilter)
+FGPositioned::findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilter)
 {
   List result;
   spatialFind(aPos, aRangeNm, aFilter, result);
@@ -411,20 +402,48 @@
 }
 
 FGPositioned::List
-FGPositioned::findAllWithIdent(const std::string& aIdent)
+FGPositioned::findAllWithIdentSortedByRange(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter)
 {
   List result;
   NamedIndexRange range = global_namedIndex.equal_range(aIdent);
   for (; range.first != range.second; ++range.first) {
+    if (aFilter && !aFilter->pass(range.first->second)) {
+      continue;
+    }
+    
     result.push_back(range.first->second);
   }
   
+  sortByDistance(aPos, result);
   return result;
 }
 
 FGPositioned::List
-FGPositioned::findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, const Filter& aFilter)
+FGPositioned::findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* 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 && !aFilter->pass(candidate)) {
+      continue;
+    }
+  
+    if (!aCur) {
+      return candidate;
+    }
+  }
+  
+  return NULL; // fell out, no match in range
+}
+
Index: src/Navaids/positioned.hxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Navaids/positioned.hxx,v
retrieving revision 1.2
diff -u -3 -r1.2 positioned.hxx
--- src/Navaids/positioned.hxx	4 Dec 2008 08:15:38 -0000	1.2
+++ src/Navaids/positioned.hxx	4 Dec 2008 19:53:50 -0000
@@ -87,27 +87,54 @@
   
   /**
    * Predicate class to support custom filtering of FGPositioned queries
+   * Default implementation of this passes any FGPositioned instance.
    */
   class Filter
   {
   public:
     virtual ~Filter() { ; }
     
-    virtual bool pass(FGPositioned* aPos) const = 0;
+    /**
+     * Over-rideable filter method. Default implementation returns true.
+     */
+    virtual bool pass(FGPositioned* aPos) const
+    { return true; }
     
     bool operator()(FGPositioned* aPos) const
     { return pass(aPos); }
   };
   
-  static List findWithinRange(const SGGeod& aPos, double aRangeNm, const Filter& aFilter);
-      
-  static List findWithinRangeByType(const SGGeod& aPos, double aRangeNm, Type aTy);
-
-  static FGPositionedRef findClosestWithIdent(const std::string& aIdent, double aLat, double aLon);
+  class TypeFilter : public Filter
+  {
+  public:
+    TypeFilter(Type aTy) : mType(aTy) { ; }
+    virtual bool pass(FGPositioned* aPos) const
+    { return (mType == aPos->type()); }
+  private:
+    const Type mType;
+  };
   
-  static FGPositionedRef findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos);
+  static List findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilter = NULL);
+        
+  static FGPositionedRef findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter = NULL);
   
-  static List findAllWithIdent(const std::string& aIdent);
+  /**
+   * Find the next item with the specified partial ID, after the 'current' item
+   * Note this function is not hyper-efficient, particular where the partial id
+   * spans a large number of candidates.
+   *
+   * @param aCur - Current item, or NULL to retrieve the first item with partial id
+   * @param aId - the (partial) id to lookup
+   */
+  static FGPositionedRef findNextWithPartialId(FGPositionedRef aCur, const std::string& aId, Filter* aFilter = NULL);
+  
+  /**
+   * Find all items with the specified ident, and return then sorted by
+   * distance from a position
+   *
+   * @param aFilter - optional filter on items
+   */
+  static List findAllWithIdentSortedByRange(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter = NULL);
   
   /**
    * Find the closest N items to a position, which pass the specified filter
@@ -119,7 +146,7 @@
    * @param aN - number of matches to find
    * @param aCutoffNm - maximum distance to search within, in nautical miles
    */
-  static List findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, const Filter& aFilter);
+  static List findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* aFilter = NULL);
   
   /**
    * Debug helper, map a type to a human-readable string
