mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 11:45:53 +01:00
Fix the POI search algorithm
(At least so, that it does not trigger the rtree assert. The whole RectC logic has to be fixed to properly handle poles/dateline "overflows")
This commit is contained in:
parent
9e03d85b7a
commit
547d7a5f23
@ -1,3 +1,4 @@
|
|||||||
|
#include <cmath>
|
||||||
#include "wgs84.h"
|
#include "wgs84.h"
|
||||||
#include "rectc.h"
|
#include "rectc.h"
|
||||||
|
|
||||||
@ -6,6 +7,16 @@
|
|||||||
#define MIN_LON deg2rad(-180.0)
|
#define MIN_LON deg2rad(-180.0)
|
||||||
#define MAX_LON deg2rad(180.0)
|
#define MAX_LON deg2rad(180.0)
|
||||||
|
|
||||||
|
static inline double WLON(double lon)
|
||||||
|
{
|
||||||
|
return remainder(lon, 360.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double LLAT(double lat)
|
||||||
|
{
|
||||||
|
return (lat < 0.0) ? qMax(lat, -90.0) : qMin(lat, 90.0);
|
||||||
|
}
|
||||||
|
|
||||||
RectC::RectC(const Coordinates ¢er, double radius)
|
RectC::RectC(const Coordinates ¢er, double radius)
|
||||||
{
|
{
|
||||||
double radDist = radius / WGS84_RADIUS;
|
double radDist = radius / WGS84_RADIUS;
|
||||||
@ -151,6 +162,12 @@ RectC RectC::united(const Coordinates &c) const
|
|||||||
return RectC(Coordinates(l, t), Coordinates(r, b));
|
return RectC(Coordinates(l, t), Coordinates(r, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RectC RectC::adjusted(double lon1, double lat1, double lon2, double lat2) const
|
||||||
|
{
|
||||||
|
return RectC(Coordinates(WLON(_tl.lon() + lon1), LLAT(_tl.lat() + lat1)),
|
||||||
|
Coordinates(WLON(_br.lon() + lon2), LLAT(_br.lat() + lat2)));
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
QDebug operator<<(QDebug dbg, const RectC &rect)
|
QDebug operator<<(QDebug dbg, const RectC &rect)
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
RectC &operator&=(const RectC &r) {*this = *this & r; return *this;}
|
RectC &operator&=(const RectC &r) {*this = *this & r; return *this;}
|
||||||
|
|
||||||
RectC united(const Coordinates &c) const;
|
RectC united(const Coordinates &c) const;
|
||||||
|
RectC adjusted(double lon1, double lat1, double lon2, double lat2) const;
|
||||||
|
|
||||||
bool intersects(const RectC &r) const
|
bool intersects(const RectC &r) const
|
||||||
{return (right() >= r.left() && bottom() <= r.top() && left() <= r.right()
|
{return (right() >= r.left() && bottom() <= r.top() && left() <= r.right()
|
||||||
|
@ -80,13 +80,26 @@ void POI::search(const RectC &rect, QSet<int> &set) const
|
|||||||
{
|
{
|
||||||
qreal min[2], max[2];
|
qreal min[2], max[2];
|
||||||
|
|
||||||
|
if (rect.left() > rect.right()) {
|
||||||
|
min[0] = rect.topLeft().lon();
|
||||||
|
min[1] = rect.bottomRight().lat();
|
||||||
|
max[0] = 180.0;
|
||||||
|
max[1] = rect.topLeft().lat();
|
||||||
|
_tree.Search(min, max, cb, &set);
|
||||||
|
|
||||||
|
min[0] = -180.0;
|
||||||
|
min[1] = rect.bottomRight().lat();
|
||||||
|
max[0] = rect.bottomRight().lon();
|
||||||
|
max[1] = rect.topLeft().lat();
|
||||||
|
_tree.Search(min, max, cb, &set);
|
||||||
|
} else {
|
||||||
min[0] = rect.topLeft().lon();
|
min[0] = rect.topLeft().lon();
|
||||||
min[1] = rect.bottomRight().lat();
|
min[1] = rect.bottomRight().lat();
|
||||||
max[0] = rect.bottomRight().lon();
|
max[0] = rect.bottomRight().lon();
|
||||||
max[1] = rect.topLeft().lat();
|
max[1] = rect.topLeft().lat();
|
||||||
|
|
||||||
_tree.Search(min, max, cb, &set);
|
_tree.Search(min, max, cb, &set);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QList<Waypoint> POI::points(const Path &path) const
|
QList<Waypoint> POI::points(const Path &path) const
|
||||||
{
|
{
|
||||||
@ -130,16 +143,10 @@ QList<Waypoint> POI::points(const Waypoint &point) const
|
|||||||
{
|
{
|
||||||
QList<Waypoint> ret;
|
QList<Waypoint> ret;
|
||||||
QSet<int> set;
|
QSet<int> set;
|
||||||
qreal min[2], max[2];
|
|
||||||
QSet<int>::const_iterator it;
|
QSet<int>::const_iterator it;
|
||||||
|
|
||||||
RectC br(point.coordinates(), _radius);
|
RectC br(point.coordinates(), _radius);
|
||||||
min[0] = br.topLeft().lon();
|
search(br, set);
|
||||||
min[1] = br.bottomRight().lat();
|
|
||||||
max[0] = br.bottomRight().lon();
|
|
||||||
max[1] = br.topLeft().lat();
|
|
||||||
|
|
||||||
_tree.Search(min, max, cb, &set);
|
|
||||||
|
|
||||||
for (it = set.constBegin(); it != set.constEnd(); ++it)
|
for (it = set.constBegin(); it != set.constEnd(); ++it)
|
||||||
ret.append(_data.at(*it));
|
ret.append(_data.at(*it));
|
||||||
@ -150,18 +157,12 @@ QList<Waypoint> POI::points(const Waypoint &point) const
|
|||||||
QList<Waypoint> POI::points(const RectC &rect) const
|
QList<Waypoint> POI::points(const RectC &rect) const
|
||||||
{
|
{
|
||||||
QList<Waypoint> ret;
|
QList<Waypoint> ret;
|
||||||
qreal min[2], max[2];
|
|
||||||
QSet<int> set;
|
QSet<int> set;
|
||||||
QSet<int>::const_iterator it;
|
QSet<int>::const_iterator it;
|
||||||
|
|
||||||
double offset = rad2deg(_radius / WGS84_RADIUS);
|
double offset = rad2deg(_radius / WGS84_RADIUS);
|
||||||
|
RectC br(rect.adjusted(-offset, offset, offset, -offset));
|
||||||
min[0] = rect.topLeft().lon() - offset;
|
search(br, set);
|
||||||
min[1] = rect.bottomRight().lat() - offset;
|
|
||||||
max[0] = rect.bottomRight().lon() + offset;
|
|
||||||
max[1] = rect.topLeft().lat() + offset;
|
|
||||||
|
|
||||||
_tree.Search(min, max, cb, &set);
|
|
||||||
|
|
||||||
for (it = set.constBegin(); it != set.constEnd(); ++it)
|
for (it = set.constBegin(); it != set.constEnd(); ++it)
|
||||||
ret.append(_data.at(*it));
|
ret.append(_data.at(*it));
|
||||||
|
Loading…
Reference in New Issue
Block a user