mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 13:41:16 +01:00
178 lines
3.4 KiB
C++
178 lines
3.4 KiB
C++
#include "wgs84.h"
|
|
#include "rectc.h"
|
|
|
|
#define MIN_LAT deg2rad(-90.0)
|
|
#define MAX_LAT deg2rad(90.0)
|
|
#define MIN_LON deg2rad(-180.0)
|
|
#define MAX_LON deg2rad(180.0)
|
|
|
|
RectC::RectC(const Coordinates ¢er, double radius)
|
|
{
|
|
double radDist = radius / WGS84_RADIUS;
|
|
double radLon = deg2rad(center.lon());
|
|
double radlat = deg2rad(center.lat());
|
|
|
|
double minLat = radlat - radDist;
|
|
double maxLat = radlat + radDist;
|
|
|
|
double minLon, maxLon;
|
|
if (minLat > MIN_LAT && maxLat < MAX_LAT) {
|
|
double deltaLon = asin(sin(radDist) / cos(radlat));
|
|
minLon = radLon - deltaLon;
|
|
if (minLon < MIN_LON)
|
|
minLon += 2.0 * M_PI;
|
|
maxLon = radLon + deltaLon;
|
|
if (maxLon > MAX_LON)
|
|
maxLon -= 2.0 * M_PI;
|
|
} else {
|
|
// a pole is within the distance
|
|
minLat = qMax(minLat, MIN_LAT);
|
|
maxLat = qMin(maxLat, MAX_LAT);
|
|
minLon = MIN_LON;
|
|
maxLon = MAX_LON;
|
|
}
|
|
|
|
_tl = Coordinates(rad2deg(minLon), rad2deg(maxLat));
|
|
_br = Coordinates(rad2deg(maxLon), rad2deg(minLat));
|
|
}
|
|
|
|
RectC RectC::operator|(const RectC &r) const
|
|
{
|
|
if (isNull())
|
|
return r;
|
|
if (r.isNull())
|
|
return *this;
|
|
|
|
double l1 = _tl.lon();
|
|
double r1 = _tl.lon();
|
|
if (_br.lon() - _tl.lon() < 0)
|
|
l1 = _br.lon();
|
|
else
|
|
r1 = _br.lon();
|
|
|
|
double l2 = r._tl.lon();
|
|
double r2 = r._tl.lon();
|
|
if (r._br.lon() - r._tl.lon() < 0)
|
|
l2 = r._br.lon();
|
|
else
|
|
r2 = r._br.lon();
|
|
|
|
double t1 = _tl.lat();
|
|
double b1 = _tl.lat();
|
|
if (_br.lat() - _tl.lat() < 0)
|
|
t1 = _br.lat();
|
|
else
|
|
b1 = _br.lat();
|
|
|
|
double t2 = r._tl.lat();
|
|
double b2 = r._tl.lat();
|
|
if (r._br.lat() - r._tl.lat() < 0)
|
|
t2 = r._br.lat();
|
|
else
|
|
b2 = r._br.lat();
|
|
|
|
RectC tmp;
|
|
tmp._tl.setLon(qMin(l1, l2));
|
|
tmp._br.setLon(qMax(r1, r2));
|
|
tmp._tl.setLat(qMin(t1, t2));
|
|
tmp._br.setLat(qMax(b1, b2));
|
|
|
|
return tmp;
|
|
}
|
|
|
|
RectC RectC::operator&(const RectC &r) const
|
|
{
|
|
if (isNull() || r.isNull())
|
|
return RectC();
|
|
|
|
double l1 = _tl.lon();
|
|
double r1 = _tl.lon();
|
|
if (_br.lon() - _tl.lon() < 0)
|
|
l1 = _br.lon();
|
|
else
|
|
r1 = _br.lon();
|
|
|
|
double l2 = r._tl.lon();
|
|
double r2 = r._tl.lon();
|
|
if (r._br.lon() - r._tl.lon() < 0)
|
|
l2 = r._br.lon();
|
|
else
|
|
r2 = r._br.lon();
|
|
|
|
if (l1 > r2 || l2 > r1)
|
|
return RectC();
|
|
|
|
double t1 = _tl.lat();
|
|
double b1 = _tl.lat();
|
|
if (_br.lat() - _tl.lat() < 0)
|
|
t1 = _br.lat();
|
|
else
|
|
b1 = _br.lat();
|
|
|
|
double t2 = r._tl.lat();
|
|
double b2 = r._tl.lat();
|
|
if (r._br.lat() - r._tl.lat() < 0)
|
|
t2 = r._br.lat();
|
|
else
|
|
b2 = r._br.lat();
|
|
|
|
if (t1 > b2 || t2 > b1)
|
|
return RectC();
|
|
|
|
RectC tmp;
|
|
tmp._tl.setLon(qMax(l1, l2));
|
|
tmp._br.setLon(qMin(r1, r2));
|
|
tmp._tl.setLat(qMax(t1, t2));
|
|
tmp._br.setLat(qMin(b1, b2));
|
|
|
|
return tmp;
|
|
}
|
|
|
|
RectC RectC::normalized() const
|
|
{
|
|
RectC r;
|
|
|
|
if (_br.lon() < _tl.lon()) {
|
|
r._tl.setLon(_br.lon());
|
|
r._br.setLon(_tl.lon());
|
|
} else {
|
|
r._tl.setLon(_tl.lon());
|
|
r._br.setLon(_br.lon());
|
|
}
|
|
if (_br.lat() < _tl.lat()) {
|
|
r._tl.setLat(_br.lat());
|
|
r._br.setLat(_tl.lat());
|
|
} else {
|
|
r._tl.setLat(_tl.lat());
|
|
r._br.setLat(_br.lat());
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
void RectC::unite(const Coordinates &c)
|
|
{
|
|
if (isNull()) {
|
|
_tl = c;
|
|
_br = c;
|
|
} else {
|
|
if (c.lon() < _tl.lon())
|
|
_tl.setLon(c.lon());
|
|
if (c.lon() > _br.lon())
|
|
_br.setLon(c.lon());
|
|
if (c.lat() > _br.lat())
|
|
_br.setLat(c.lat());
|
|
if (c.lat() < _tl.lat())
|
|
_tl.setLat(c.lat());
|
|
}
|
|
}
|
|
|
|
#ifndef QT_NO_DEBUG
|
|
QDebug operator<<(QDebug dbg, const RectC &rect)
|
|
{
|
|
dbg.nospace() << "RectC(" << rect.topLeft() << ", " << rect.bottomRight()
|
|
<< ")";
|
|
return dbg.space();
|
|
}
|
|
#endif // QT_NO_DEBUG
|