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:
parent
e844383988
commit
1e8cdd5829
5 changed files with 28 additions and 6 deletions
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue