1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Remaining qreal/double separation

+ some minor TrekBuddy atlas issues fixes
This commit is contained in:
Martin Tůma 2018-05-02 21:25:14 +02:00
parent 1aedc1de93
commit cf81e42f52
8 changed files with 117 additions and 54 deletions

View File

@ -125,7 +125,8 @@ HEADERS += src/config.h \
src/data/fitparser.h \ src/data/fitparser.h \
src/data/igcparser.h \ src/data/igcparser.h \
src/data/nmeaparser.h \ src/data/nmeaparser.h \
src/data/oziparsers.h src/data/oziparsers.h \
src/map/rectd.h
SOURCES += src/main.cpp \ SOURCES += src/main.cpp \
src/common/coordinates.cpp \ src/common/coordinates.cpp \
src/common/rectc.cpp \ src/common/rectc.cpp \

View File

@ -36,13 +36,13 @@ void Atlas::computeZooms()
{ {
qSort(_maps.begin(), _maps.end(), resCmp); qSort(_maps.begin(), _maps.end(), resCmp);
_zooms.append(QPair<int, int>(0, _maps.count() - 1)); _zooms.append(Zoom(0, _maps.count() - 1));
for (int i = 1; i < _maps.count(); i++) { for (int i = 1; i < _maps.count(); i++) {
qreal last = _maps.at(i-1)->resolution(_maps.at(i)->bounds()); qreal last = _maps.at(i-1)->resolution(_maps.at(i)->bounds());
qreal cur = _maps.at(i)->resolution(_maps.at(i)->bounds()); qreal cur = _maps.at(i)->resolution(_maps.at(i)->bounds());
if (cur < last * ZOOM_THRESHOLD) { if (cur < last * ZOOM_THRESHOLD) {
_zooms.last().second = i-1; _zooms.last().last = i-1;
_zooms.append(QPair<int, int>(i, _maps.count() - 1)); _zooms.append(Zoom(i, _maps.count() - 1));
} }
} }
} }
@ -56,7 +56,7 @@ void Atlas::computeBounds()
for (int z = 0; z < _zooms.count(); z++) { for (int z = 0; z < _zooms.count(); z++) {
QList<OfflineMap*> m; QList<OfflineMap*> m;
for (int i = _zooms.at(z).first; i <= _zooms.at(z).second; i++) for (int i = _zooms.at(z).first; i <= _zooms.at(z).last; i++)
m.append(_maps.at(i)); m.append(_maps.at(i));
qSort(m.begin(), m.end(), xCmp); qSort(m.begin(), m.end(), xCmp);
@ -75,9 +75,8 @@ void Atlas::computeBounds()
} }
for (int i = 0; i < _maps.count(); i++) for (int i = 0; i < _maps.count(); i++)
_bounds.append(QPair<QRectF, QRectF>(QRectF(TL(_maps.at(i)).toPointF(), _bounds.append(Bounds(RectD(TL(_maps.at(i)), BR(_maps.at(i))),
BR(_maps.at(i)).toPointF()), QRectF(offsets.at(i), QRectF(offsets.at(i), _maps.at(i)->bounds().size())));
_maps.at(i)->bounds().size())));
} }
Atlas::Atlas(const QString &fileName, QObject *parent) Atlas::Atlas(const QString &fileName, QObject *parent)
@ -152,11 +151,11 @@ QRectF Atlas::bounds() const
{ {
QSizeF s(0, 0); QSizeF s(0, 0);
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).second; i++) { for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
if (_bounds.at(i).second.right() > s.width()) if (_bounds.at(i).xy.right() > s.width())
s.setWidth(_bounds.at(i).second.right()); s.setWidth(_bounds.at(i).xy.right());
if (_bounds.at(i).second.bottom() > s.height()) if (_bounds.at(i).xy.bottom() > s.height())
s.setHeight(_bounds.at(i).second.bottom()); s.setHeight(_bounds.at(i).xy.bottom());
} }
return QRectF(QPointF(0, 0), s); return QRectF(QPointF(0, 0), s);
@ -166,9 +165,8 @@ qreal Atlas::resolution(const QRectF &rect) const
{ {
int idx = _zooms.at(_zoom).first; int idx = _zooms.at(_zoom).first;
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).second; i++) { for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
if (_bounds.at(i).second.contains(_maps.at(i)->xy2pp(rect.center()) if (_bounds.at(i).xy.contains(rect.center())) {
.toPointF())) {
idx = i; idx = i;
break; break;
} }
@ -188,9 +186,8 @@ int Atlas::zoomFit(const QSize &size, const RectC &br)
} }
for (int z = 0; z < _zooms.count(); z++) { for (int z = 0; z < _zooms.count(); z++) {
for (int i = _zooms.at(z).first; i <= _zooms.at(z).second; i++) { for (int i = _zooms.at(z).first; i <= _zooms.at(z).last; i++) {
if (!_bounds.at(i).first.contains(_maps.at(i)->ll2pp(br.center()) if (!_bounds.at(i).pp.contains(_maps.at(i)->ll2pp(br.center())))
.toPointF()))
continue; continue;
QRect sbr = QRectF(_maps.at(i)->ll2xy(br.topLeft()), QRect sbr = QRectF(_maps.at(i)->ll2xy(br.topLeft()),
@ -232,15 +229,15 @@ int Atlas::zoomOut()
QPointF Atlas::ll2xy(const Coordinates &c) QPointF Atlas::ll2xy(const Coordinates &c)
{ {
QPointF pp; PointD pp;
if (_mapIndex >= 0) if (_mapIndex >= 0)
pp = _maps.at(_mapIndex)->ll2pp(c).toPointF(); pp = _maps.at(_mapIndex)->ll2pp(c);
if (_mapIndex < 0 || !_bounds.at(_mapIndex).first.contains(pp)) { if (_mapIndex < 0 || !_bounds.at(_mapIndex).pp.contains(pp)) {
_mapIndex = _zooms.at(_zoom).first; _mapIndex = _zooms.at(_zoom).first;
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).second; i++) { for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
pp = _maps.at(i)->ll2pp(c).toPointF(); pp = _maps.at(i)->ll2pp(c);
if (_bounds.at(i).first.contains(pp)) { if (_bounds.at(i).pp.contains(pp)) {
_mapIndex = i; _mapIndex = i;
break; break;
} }
@ -248,21 +245,21 @@ QPointF Atlas::ll2xy(const Coordinates &c)
} }
QPointF p = _maps.at(_mapIndex)->pp2xy(pp); QPointF p = _maps.at(_mapIndex)->pp2xy(pp);
return p + _bounds.at(_mapIndex).second.topLeft(); return p + _bounds.at(_mapIndex).xy.topLeft();
} }
Coordinates Atlas::xy2ll(const QPointF &p) Coordinates Atlas::xy2ll(const QPointF &p)
{ {
int idx = _zooms.at(_zoom).first; int idx = _zooms.at(_zoom).first;
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).second; i++) { for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
if (_bounds.at(i).second.contains(_maps.at(i)->xy2pp(p).toPointF())) { if (_bounds.at(i).xy.contains(p)) {
idx = i; idx = i;
break; break;
} }
} }
QPointF p2 = p - _bounds.at(idx).second.topLeft(); QPointF p2 = p - _bounds.at(idx).xy.topLeft();
return _maps.at(idx)->xy2ll(p2); return _maps.at(idx)->xy2ll(p2);
} }
@ -271,8 +268,8 @@ void Atlas::draw(QPainter *painter, const QRectF &rect, bool block)
Q_UNUSED(block); Q_UNUSED(block);
// All in one map // All in one map
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).second; i++) { for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
if (_bounds.at(i).second.contains(rect)) { if (_bounds.at(i).xy.contains(rect)) {
draw(painter, rect, i); draw(painter, rect, i);
return; return;
} }
@ -280,8 +277,8 @@ void Atlas::draw(QPainter *painter, const QRectF &rect, bool block)
// Multiple maps // Multiple maps
painter->fillRect(rect, _backgroundColor); painter->fillRect(rect, _backgroundColor);
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).second; i++) { for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
QRectF ir = rect.intersected(_bounds.at(i).second); QRectF ir = rect.intersected(_bounds.at(i).xy);
if (!ir.isNull()) if (!ir.isNull())
draw(painter, ir, i); draw(painter, ir, i);
} }
@ -290,7 +287,7 @@ void Atlas::draw(QPainter *painter, const QRectF &rect, bool block)
void Atlas::draw(QPainter *painter, const QRectF &rect, int mapIndex) void Atlas::draw(QPainter *painter, const QRectF &rect, int mapIndex)
{ {
OfflineMap *map = _maps.at(mapIndex); OfflineMap *map = _maps.at(mapIndex);
const QPointF offset = _bounds.at(mapIndex).second.topLeft(); const QPointF offset = _bounds.at(mapIndex).xy.topLeft();
QRectF pr = QRectF(rect.topLeft() - offset, rect.size()); QRectF pr = QRectF(rect.topLeft() - offset, rect.size());
map->load(); map->load();

View File

@ -2,6 +2,7 @@
#define ATLAS_H #define ATLAS_H
#include "map.h" #include "map.h"
#include "rectd.h"
class OfflineMap; class OfflineMap;
@ -36,6 +37,22 @@ public:
static bool isAtlas(const QString &path); static bool isAtlas(const QString &path);
private: private:
struct Zoom {
int first;
int last;
Zoom() : first(-1), last(-1) {}
Zoom(int first, int last) : first(first), last(last) {}
};
struct Bounds {
RectD pp;
QRectF xy;
Bounds() {}
Bounds(const RectD &pp, const QRectF &xy) : pp(pp), xy(xy) {}
};
void draw(QPainter *painter, const QRectF &rect, int mapIndex); void draw(QPainter *painter, const QRectF &rect, int mapIndex);
void computeZooms(); void computeZooms();
void computeBounds(); void computeBounds();
@ -43,8 +60,8 @@ private:
QString _name; QString _name;
QList<OfflineMap*> _maps; QList<OfflineMap*> _maps;
QVector<QPair<int, int> > _zooms; QVector<Zoom> _zooms;
QVector<QPair<QRectF, QRectF> > _bounds; QVector<Bounds> _bounds;
int _zoom; int _zoom;
int _mapIndex; int _mapIndex;

View File

@ -19,7 +19,7 @@ public:
bool isNull() const {return std::isnan(_x) && std::isnan(_y);} bool isNull() const {return std::isnan(_x) && std::isnan(_y);}
QPointF toPointF() const {return QPointF(_x, _y);} QPointF toPointF() const {return QPointF((qreal)_x, (qreal)_y);}
private: private:
double _x, _y; double _x, _y;

43
src/map/rectd.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef RECTD_H
#define RECTD_H
#include "pointd.h"
class RectD
{
public:
RectD() {}
RectD(const PointD &topLeft, const PointD &bottomRight)
: _tl(topLeft), _br(bottomRight) {}
PointD topLeft() const {return _tl;}
PointD bottomRight() const {return _br;}
double left() const {return _tl.x();}
double right() const {return _br.x();}
double top() const {return _tl.y();}
double bottom() const {return _br.y();}
double width() const {return (right() - left());}
double height() const {return (top() - bottom());}
bool contains(const PointD &p) const
{return (p.x() >= left() && p.x() <= right() && p.y() <= top()
&& p.y() >= bottom());}
bool isNull() const {return _tl.isNull() && _br.isNull();}
private:
PointD _tl, _br;
};
#ifndef QT_NO_DEBUG
inline QDebug operator<<(QDebug dbg, const RectD &rect)
{
dbg.nospace() << "RectD(" << rect.topLeft() << ", " << rect.bottomRight()
<< ")";
return dbg.space();
}
#endif // QT_NO_DEBUG
#endif // RECTD_H

View File

@ -4,22 +4,23 @@
#include <QPixmap> #include <QPixmap>
#include <QPoint> #include <QPoint>
#include <QDebug> #include <QDebug>
#include "rectd.h"
class Tile class Tile
{ {
public: public:
Tile(const QPoint &xy, const QVariant &zoom, const QRectF &bbox = QRectF()) Tile(const QPoint &xy, const QVariant &zoom, const RectD &bbox = RectD())
{_xy = xy; _zoom = zoom; _bbox = bbox;} {_xy = xy; _zoom = zoom; _bbox = bbox;}
const QVariant &zoom() const {return _zoom;} const QVariant &zoom() const {return _zoom;}
const QPoint &xy() const {return _xy;} const QPoint &xy() const {return _xy;}
const QRectF &bbox() const {return _bbox;} const RectD &bbox() const {return _bbox;}
QPixmap& pixmap() {return _pixmap;} QPixmap& pixmap() {return _pixmap;}
private: private:
QVariant _zoom; QVariant _zoom;
QPoint _xy; QPoint _xy;
QRectF _bbox; RectD _bbox;
QPixmap _pixmap; QPixmap _pixmap;
}; };

View File

@ -64,14 +64,12 @@ void WMSMap::updateTransform()
double pixelSpan = sd2res(_zooms.at(_zoom)); double pixelSpan = sd2res(_zooms.at(_zoom));
if (_projection.isGeographic()) if (_projection.isGeographic())
pixelSpan /= deg2rad(WGS84_RADIUS); pixelSpan /= deg2rad(WGS84_RADIUS);
double sx = (_br.x() - _tl.x()) / pixelSpan; double sx = _bbox.width() / pixelSpan;
double sy = (_tl.y() - _br.y()) / pixelSpan; double sy = _bbox.height() / pixelSpan;
ReferencePoint tl(PointD(0, 0), _tl); ReferencePoint tl(PointD(0, 0), _bbox.topLeft());
ReferencePoint br(PointD(sx, sy), _br); ReferencePoint br(PointD(sx, sy), _bbox.bottomRight());
_transform = Transform(tl, br); _transform = Transform(tl, br);
_bounds = QRectF(QPointF(0, 0), QSizeF(sx, sy));
} }
bool WMSMap::loadWMS() bool WMSMap::loadWMS()
@ -85,8 +83,8 @@ bool WMSMap::loadWMS()
} }
_projection = wms.projection(); _projection = wms.projection();
_tl = _projection.ll2xy(wms.boundingBox().topLeft()); _bbox = RectD(_projection.ll2xy(wms.boundingBox().topLeft()),
_br = _projection.ll2xy(wms.boundingBox().bottomRight()); _projection.ll2xy(wms.boundingBox().bottomRight()));
_tileLoader->setUrl(tileUrl(wms.version())); _tileLoader->setUrl(tileUrl(wms.version()));
if (wms.version() >= "1.3.0") { if (wms.version() >= "1.3.0") {
@ -128,6 +126,12 @@ void WMSMap::clearCache()
qWarning("%s: %s\n", qPrintable(_name), qPrintable(_errorString)); qWarning("%s: %s\n", qPrintable(_name), qPrintable(_errorString));
} }
QRectF WMSMap::bounds() const
{
return QRectF(_transform.proj2img(_bbox.topLeft()),
_transform.proj2img(_bbox.bottomRight()));
}
qreal WMSMap::resolution(const QRectF &rect) const qreal WMSMap::resolution(const QRectF &rect) const
{ {
Coordinates tl = xy2ll((rect.topLeft())); Coordinates tl = xy2ll((rect.topLeft()));
@ -207,9 +211,9 @@ void WMSMap::draw(QPainter *painter, const QRectF &rect, bool block)
j * TILE_SIZE))); j * TILE_SIZE)));
PointD tbr(_transform.img2proj(QPointF(i * TILE_SIZE + TILE_SIZE PointD tbr(_transform.img2proj(QPointF(i * TILE_SIZE + TILE_SIZE
- 1, j * TILE_SIZE + TILE_SIZE - 1))); - 1, j * TILE_SIZE + TILE_SIZE - 1)));
QRectF bbox = (_cs.axisOrder() == CoordinateSystem::YX) RectD bbox = (_cs.axisOrder() == CoordinateSystem::YX)
? QRectF(QPointF(tbr.y(), tbr.x()), QPointF(ttl.y(), ttl.x())) ? RectD(PointD(tbr.y(), tbr.x()), PointD(ttl.y(), ttl.x()))
: QRectF(ttl.toPointF(), tbr.toPointF()); : RectD(ttl, tbr);
tiles.append(Tile(QPoint(i, j), _zoom, bbox)); tiles.append(Tile(QPoint(i, j), _zoom, bbox));
} }

View File

@ -5,6 +5,7 @@
#include "projection.h" #include "projection.h"
#include "map.h" #include "map.h"
#include "wms.h" #include "wms.h"
#include "rectd.h"
class TileLoader; class TileLoader;
@ -17,7 +18,7 @@ public:
const QString &name() const {return _name;} const QString &name() const {return _name;}
QRectF bounds() const {return _bounds;} QRectF bounds() const;
qreal resolution(const QRectF &rect) const; qreal resolution(const QRectF &rect) const;
int zoom() const {return _zoom;} int zoom() const {return _zoom;}
@ -57,8 +58,7 @@ private:
Transform _transform; Transform _transform;
CoordinateSystem _cs; CoordinateSystem _cs;
QVector<double> _zooms; QVector<double> _zooms;
PointD _tl, _br; RectD _bbox;
QRectF _bounds;
int _zoom; int _zoom;
bool _valid; bool _valid;