1
0
Fork 0

Support partial all-within-range spatial queries.

As an opt-in API, allow clients to request partial results, with a time-bounded cutoff. Use this to keep the MapWidget responsive even when many airports are being added to the cache (e.g., zooming out or panning rapidly when zoomed out)
This commit is contained in:
James Turner 2012-12-18 10:23:44 +00:00
parent e844383988
commit 1e8cdd5829
5 changed files with 28 additions and 6 deletions

View file

@ -936,7 +936,8 @@ private:
void MapWidget::drawAirports()
{
MapAirportFilter af(_root);
FGPositioned::List apts = FGPositioned::findWithinRange(_projectionCenter, _drawRangeNm, &af);
bool partial = false;
FGPositioned::List apts = FGPositioned::findWithinRangePartial(_projectionCenter, _drawRangeNm, &af, partial);
for (unsigned int i=0; i<apts.size(); ++i) {
drawAirport((FGAirport*) apts[i].get());
}

View file

@ -37,6 +37,7 @@
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/timing/timestamp.hxx>
namespace flightgear
{
@ -258,7 +259,7 @@ void findNearestN(const SGVec3d& aPos, unsigned int aN, double aCutoffM, FGPosit
}
}
void findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults)
bool findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults, int aCutoffMsec)
{
aResults.clear();
FindNearestPQueue pq;
@ -266,7 +267,10 @@ void findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filte
pq.push(Ordered<Node*>(global_spatialOctree, 0));
double rng = aRangeM;
while (!pq.empty()) {
SGTimeStamp tm;
tm.stamp();
while (!pq.empty() && (tm.elapsedMSec() < aCutoffMsec)) {
Node* nd = pq.top().get();
pq.pop();
@ -279,6 +283,8 @@ void findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filte
for (unsigned int r=0; r<numResults; ++r) {
aResults[r] = results[r].get();
}
return !pq.empty();
}
} // of namespace Octree

View file

@ -216,7 +216,7 @@ namespace Octree
};
void findNearestN(const SGVec3d& aPos, unsigned int aN, double aCutoffM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults);
void findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults);
bool findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults, int aCutoffMsec);
} // of namespace Octree

View file

@ -202,7 +202,20 @@ FGPositioned::findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilt
List result;
Octree::findAllWithinRange(SGVec3d::fromGeod(aPos),
aRangeNm * SG_NM_TO_METER, aFilter, result);
aRangeNm * SG_NM_TO_METER, aFilter, result, 0xffffff);
return result;
}
FGPositioned::List
FGPositioned::findWithinRangePartial(const SGGeod& aPos, double aRangeNm, Filter* aFilter, bool& aPartial)
{
validateSGGeod(aPos);
int limitMsec = 32;
List result;
aPartial = Octree::findAllWithinRange(SGVec3d::fromGeod(aPos),
aRangeNm * SG_NM_TO_METER, aFilter, result,
limitMsec);
return result;
}

View file

@ -167,6 +167,8 @@ public:
static List findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilter = NULL);
static List findWithinRangePartial(const SGGeod& aPos, double aRangeNm, Filter* aFilter, bool& aPartial);
static FGPositionedRef findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter = NULL);
static FGPositionedRef findFirstWithIdent(const std::string& aIdent, Filter* aFilter = NULL);