mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 11:45:53 +01:00
Fixed broken radius-rect computation
Always use the double type for coordinate related data
This commit is contained in:
parent
f8009b0151
commit
3f71775101
@ -1,50 +1,16 @@
|
||||
#include "wgs84.h"
|
||||
#include "coordinates.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)
|
||||
|
||||
qreal Coordinates::distanceTo(const Coordinates &c) const
|
||||
double Coordinates::distanceTo(const Coordinates &c) const
|
||||
{
|
||||
qreal dLat = deg2rad(c.lat() - _lat);
|
||||
qreal dLon = deg2rad(c.lon() - _lon);
|
||||
qreal a = pow(sin(dLat / 2.0), 2.0)
|
||||
double dLat = deg2rad(c.lat() - _lat);
|
||||
double dLon = deg2rad(c.lon() - _lon);
|
||||
double a = pow(sin(dLat / 2.0), 2.0)
|
||||
+ cos(deg2rad(_lat)) * cos(deg2rad(c.lat())) * pow(sin(dLon / 2.0), 2.0);
|
||||
|
||||
return (WGS84_RADIUS * (2.0 * atan2(sqrt(a), sqrt(1.0 - a))));
|
||||
}
|
||||
|
||||
QPair<Coordinates, Coordinates> Coordinates::boundingRect(qreal distance) const
|
||||
{
|
||||
qreal radDist = distance / WGS84_RADIUS;
|
||||
|
||||
qreal minLat = deg2rad(_lat) - radDist;
|
||||
qreal maxLat = deg2rad(_lat) + radDist;
|
||||
|
||||
qreal minLon, maxLon;
|
||||
if (minLat > MIN_LAT && maxLat < MAX_LAT) {
|
||||
qreal deltaLon = asin(sin(radDist) / cos(_lat));
|
||||
minLon = deg2rad(_lon) - deltaLon;
|
||||
if (minLon < MIN_LON)
|
||||
minLon += 2.0 * M_PI;
|
||||
maxLon = deg2rad(_lon) + 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;
|
||||
}
|
||||
|
||||
return QPair<Coordinates, Coordinates>(Coordinates(rad2deg(qMin(minLon,
|
||||
maxLon)), rad2deg(qMin(minLat, maxLat))), Coordinates(rad2deg(qMax(minLon,
|
||||
maxLon)), rad2deg(qMax(minLat, maxLat))));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const Coordinates &c)
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define COORDINATES_H
|
||||
|
||||
#include <cmath>
|
||||
#include <QPair>
|
||||
#include <QDebug>
|
||||
|
||||
#ifndef M_PI
|
||||
@ -15,14 +14,14 @@ class Coordinates
|
||||
{
|
||||
public:
|
||||
Coordinates() {_lon = NAN; _lat = NAN;}
|
||||
Coordinates(qreal lon, qreal lat) {_lon = lon; _lat = lat;}
|
||||
Coordinates(double lon, double lat) {_lon = lon; _lat = lat;}
|
||||
|
||||
qreal &rlon() {return _lon;}
|
||||
qreal &rlat() {return _lat;}
|
||||
void setLon(qreal lon) {_lon = lon;}
|
||||
void setLat(qreal lat) {_lat = lat;}
|
||||
qreal lon() const {return _lon;}
|
||||
qreal lat() const {return _lat;}
|
||||
double &rlon() {return _lon;}
|
||||
double &rlat() {return _lat;}
|
||||
void setLon(double lon) {_lon = lon;}
|
||||
void setLat(double lat) {_lat = lat;}
|
||||
double lon() const {return _lon;}
|
||||
double lat() const {return _lat;}
|
||||
|
||||
bool isNull() const
|
||||
{return std::isnan(_lon) && std::isnan(_lat);}
|
||||
@ -30,11 +29,10 @@ public:
|
||||
{return (_lon >= -180.0 && _lon <= 180.0
|
||||
&& _lat >= -90.0 && _lat <= 90.0);}
|
||||
|
||||
qreal distanceTo(const Coordinates &c) const;
|
||||
QPair<Coordinates, Coordinates> boundingRect(qreal distance) const;
|
||||
double distanceTo(const Coordinates &c) const;
|
||||
|
||||
private:
|
||||
qreal _lat, _lon;
|
||||
double _lat, _lon;
|
||||
};
|
||||
|
||||
inline bool operator==(const Coordinates &c1, const Coordinates &c2)
|
||||
|
@ -1,5 +1,41 @@
|
||||
#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())
|
||||
@ -134,7 +170,8 @@ void RectC::unite(const Coordinates &c)
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const RectC &rect)
|
||||
{
|
||||
dbg.nospace() << "RectC(" << rect.topLeft() << ", " << rect.size() << ")";
|
||||
dbg.nospace() << "RectC(" << rect.topLeft() << ", " << rect.bottomRight()
|
||||
<< ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define RECTC_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSizeF>
|
||||
#include "coordinates.h"
|
||||
|
||||
class RectC
|
||||
@ -11,6 +10,7 @@ public:
|
||||
RectC() {}
|
||||
RectC(const Coordinates &topLeft, const Coordinates &bottomRight)
|
||||
: _tl(topLeft), _br(bottomRight) {}
|
||||
RectC(const Coordinates ¢er, double radius);
|
||||
|
||||
bool isNull() const
|
||||
{return _tl.isNull() && _br.isNull();}
|
||||
@ -19,14 +19,9 @@ public:
|
||||
|
||||
Coordinates topLeft() const {return _tl;}
|
||||
Coordinates bottomRight() const {return _br;}
|
||||
|
||||
Coordinates center() const
|
||||
{return Coordinates((_tl.lon() + _br.lon()) / 2.0,
|
||||
(_tl.lat() + _br.lat()) / 2.0);}
|
||||
qreal width() const {return _br.lon() - _tl.lon();}
|
||||
qreal height() const {return _br.lat() - _tl.lat();}
|
||||
|
||||
QSizeF size() const {return QSizeF(width(), height());}
|
||||
|
||||
RectC operator|(const RectC &r) const;
|
||||
RectC &operator|=(const RectC &r) {*this = *this | r; return *this;}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include "common/rectc.h"
|
||||
#include "data.h"
|
||||
#include "poi.h"
|
||||
|
||||
@ -101,12 +102,11 @@ QList<Waypoint> POI::points(const Path &path) const
|
||||
QSet<int>::const_iterator it;
|
||||
|
||||
for (int i = 0; i < path.count(); i++) {
|
||||
const Coordinates &c = path.at(i).coordinates();
|
||||
QPair<Coordinates, Coordinates> br = c.boundingRect(_radius);
|
||||
min[0] = br.first.lon();
|
||||
min[1] = br.first.lat();
|
||||
max[0] = br.second.lon();
|
||||
max[1] = br.second.lat();
|
||||
RectC br(path.at(i).coordinates(), _radius);
|
||||
min[0] = br.topLeft().lon();
|
||||
min[1] = br.bottomRight().lat();
|
||||
max[0] = br.bottomRight().lon();
|
||||
max[1] = br.topLeft().lat();
|
||||
|
||||
_tree.Search(min, max, cb, &set);
|
||||
}
|
||||
@ -124,13 +124,11 @@ QList<Waypoint> POI::points(const Waypoint &point) const
|
||||
qreal min[2], max[2];
|
||||
QSet<int>::const_iterator it;
|
||||
|
||||
const Coordinates &c = point.coordinates();
|
||||
|
||||
QPair<Coordinates, Coordinates> br = c.boundingRect(_radius);
|
||||
min[0] = br.first.lon();
|
||||
min[1] = br.first.lat();
|
||||
max[0] = br.second.lon();
|
||||
max[1] = br.second.lat();
|
||||
RectC br(point.coordinates(), _radius);
|
||||
min[0] = br.topLeft().lon();
|
||||
min[1] = br.bottomRight().lat();
|
||||
max[0] = br.bottomRight().lon();
|
||||
max[1] = br.topLeft().lat();
|
||||
|
||||
_tree.Search(min, max, cb, &set);
|
||||
|
||||
|
@ -54,13 +54,13 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
int latd = list.at(6).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
qreal latm = list.at(7).trimmed().toFloat(&res);
|
||||
double latm = list.at(7).trimmed().toDouble(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
int lond = list.at(9).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
qreal lonm = list.at(10).trimmed().toFloat(&res);
|
||||
double lonm = list.at(10).trimmed().toDouble(&res);
|
||||
if (!res)
|
||||
ll = false;
|
||||
if (ll && list.at(8).trimmed() == "S") {
|
||||
@ -75,10 +75,10 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
p.zone = list.at(13).trimmed().toInt(&res);
|
||||
if (!res)
|
||||
p.zone = 0;
|
||||
qreal ppx = list.at(14).trimmed().toFloat(&res);
|
||||
double ppx = list.at(14).trimmed().toDouble(&res);
|
||||
if (!res)
|
||||
pp = false;
|
||||
qreal ppy = list.at(15).trimmed().toFloat(&res);
|
||||
double ppy = list.at(15).trimmed().toDouble(&res);
|
||||
if (!res)
|
||||
pp = false;
|
||||
if (list.at(16).trimmed() == "S")
|
||||
|
@ -63,7 +63,7 @@ QString WMS::style(QXmlStreamReader &reader)
|
||||
|
||||
RectC WMS::geographicBoundingBox(QXmlStreamReader &reader)
|
||||
{
|
||||
qreal left = NAN, top = NAN, right = NAN, bottom = NAN;
|
||||
double left = NAN, top = NAN, right = NAN, bottom = NAN;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == "westBoundLongitude")
|
||||
|
@ -10,7 +10,7 @@
|
||||
#define CAPABILITIES_FILE "capabilities.xml"
|
||||
#define TILE_SIZE 256
|
||||
|
||||
qreal WMSMap::sd2res(qreal scaleDenominator) const
|
||||
double WMSMap::sd2res(double scaleDenominator) const
|
||||
{
|
||||
return scaleDenominator * 0.28e-3 * _projection.units().fromMeters(1.0);
|
||||
}
|
||||
@ -48,9 +48,9 @@ void WMSMap::computeZooms(const RangeF &scaleDenominator)
|
||||
_zooms.clear();
|
||||
|
||||
if (scaleDenominator.size() > 0) {
|
||||
qreal ld = log2(scaleDenominator.max()) - log2(scaleDenominator.min());
|
||||
double ld = log2(scaleDenominator.max()) - log2(scaleDenominator.min());
|
||||
int cld = ceil(ld);
|
||||
qreal step = ld / (qreal)cld;
|
||||
double step = ld / (qreal)cld;
|
||||
qreal lmax = log2(scaleDenominator.max());
|
||||
for (int i = 0; i <= cld; i++)
|
||||
_zooms.append(pow(2.0, lmax - i * step));
|
||||
@ -60,10 +60,10 @@ void WMSMap::computeZooms(const RangeF &scaleDenominator)
|
||||
|
||||
void WMSMap::updateTransform()
|
||||
{
|
||||
qreal scaleDenominator = _zooms.at(_zoom);
|
||||
double scaleDenominator = _zooms.at(_zoom);
|
||||
ReferencePoint tl, br;
|
||||
|
||||
qreal pixelSpan = sd2res(scaleDenominator);
|
||||
double pixelSpan = sd2res(scaleDenominator);
|
||||
if (_projection.isGeographic())
|
||||
pixelSpan /= deg2rad(WGS84_RADIUS);
|
||||
|
||||
@ -150,7 +150,7 @@ void WMSMap::emitLoaded()
|
||||
|
||||
QRectF WMSMap::bounds() const
|
||||
{
|
||||
qreal pixelSpan = sd2res(_zooms.at(_zoom));
|
||||
double pixelSpan = sd2res(_zooms.at(_zoom));
|
||||
if (_projection.isGeographic())
|
||||
pixelSpan /= deg2rad(WGS84_RADIUS);
|
||||
QSizeF size(_boundingBox.width() / pixelSpan, -_boundingBox.height()
|
||||
@ -176,7 +176,7 @@ int WMSMap::zoomFit(const QSize &size, const RectC &br)
|
||||
QRectF tbr(_projection.ll2xy(br.topLeft()),
|
||||
_projection.ll2xy(br.bottomRight()));
|
||||
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
|
||||
qreal resolution = qMax(qAbs(sc.x()), qAbs(sc.y()));
|
||||
double resolution = qMax(qAbs(sc.x()), qAbs(sc.y()));
|
||||
if (_projection.isGeographic())
|
||||
resolution *= deg2rad(WGS84_RADIUS);
|
||||
|
||||
|
@ -46,7 +46,7 @@ private slots:
|
||||
|
||||
private:
|
||||
QString tileUrl(const QString &version) const;
|
||||
qreal sd2res(qreal scaleDenominator) const;
|
||||
double sd2res(double scaleDenominator) const;
|
||||
QString tilesDir() const;
|
||||
void computeZooms(const RangeF &scaleDenominator);
|
||||
void updateTransform();
|
||||
@ -62,7 +62,7 @@ private:
|
||||
Projection _projection;
|
||||
Transform _transform;
|
||||
CoordinateSystem _cs;
|
||||
QVector<qreal> _zooms;
|
||||
QVector<double> _zooms;
|
||||
QRectF _boundingBox;
|
||||
int _zoom;
|
||||
bool _block;
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
class Zoom
|
||||
{
|
||||
public:
|
||||
Zoom(const QString &id, qreal scaleDenominator, const QPointF &topLeft,
|
||||
Zoom(const QString &id, double scaleDenominator, const QPointF &topLeft,
|
||||
const QSize &tile, const QSize &matrix, const QRect &limits) :
|
||||
_id(id), _scaleDenominator(scaleDenominator), _topLeft(topLeft),
|
||||
_tile(tile), _matrix(matrix), _limits(limits) {}
|
||||
@ -62,7 +62,7 @@ public:
|
||||
{return _scaleDenominator > other._scaleDenominator;}
|
||||
|
||||
const QString &id() const {return _id;}
|
||||
qreal scaleDenominator() const {return _scaleDenominator;}
|
||||
double scaleDenominator() const {return _scaleDenominator;}
|
||||
const QPointF &topLeft() const {return _topLeft;}
|
||||
const QSize &tile() const {return _tile;}
|
||||
const QSize &matrix() const {return _matrix;}
|
||||
@ -70,7 +70,7 @@ public:
|
||||
|
||||
private:
|
||||
QString _id;
|
||||
qreal _scaleDenominator;
|
||||
double _scaleDenominator;
|
||||
QPointF _topLeft;
|
||||
QSize _tile;
|
||||
QSize _matrix;
|
||||
@ -94,7 +94,7 @@ public:
|
||||
private:
|
||||
struct TileMatrix {
|
||||
QString id;
|
||||
qreal scaleDenominator;
|
||||
double scaleDenominator;
|
||||
QPointF topLeft;
|
||||
QSize tile;
|
||||
QSize matrix;
|
||||
|
@ -62,7 +62,7 @@ QString WMTSMap::tilesDir() const
|
||||
return QString(TILES_DIR + "/" + _name);
|
||||
}
|
||||
|
||||
qreal WMTSMap::sd2res(qreal scaleDenominator) const
|
||||
double WMTSMap::sd2res(double scaleDenominator) const
|
||||
{
|
||||
return scaleDenominator * 0.28e-3 * _projection.units().fromMeters(1.0);
|
||||
}
|
||||
@ -75,7 +75,7 @@ void WMTSMap::updateTransform()
|
||||
QPointF topLeft = (_cs.axisOrder() == CoordinateSystem::YX)
|
||||
? QPointF(z.topLeft().y(), z.topLeft().x()) : z.topLeft();
|
||||
|
||||
qreal pixelSpan = sd2res(z.scaleDenominator());
|
||||
double pixelSpan = sd2res(z.scaleDenominator());
|
||||
if (_projection.isGeographic())
|
||||
pixelSpan /= deg2rad(WGS84_RADIUS);
|
||||
QPointF tileSpan(z.tile().width() * pixelSpan, z.tile().height() * pixelSpan);
|
||||
|
@ -46,7 +46,7 @@ private slots:
|
||||
|
||||
private:
|
||||
bool loadWMTS();
|
||||
qreal sd2res(qreal scaleDenominator) const;
|
||||
double sd2res(double scaleDenominator) const;
|
||||
QString tilesDir() const;
|
||||
void updateTransform();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user