1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-27 21:24:47 +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/igcparser.h \
src/data/nmeaparser.h \
src/data/oziparsers.h
src/data/oziparsers.h \
src/map/rectd.h
SOURCES += src/main.cpp \
src/common/coordinates.cpp \
src/common/rectc.cpp \

View File

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

View File

@ -2,6 +2,7 @@
#define ATLAS_H
#include "map.h"
#include "rectd.h"
class OfflineMap;
@ -36,6 +37,22 @@ public:
static bool isAtlas(const QString &path);
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 computeZooms();
void computeBounds();
@ -43,8 +60,8 @@ private:
QString _name;
QList<OfflineMap*> _maps;
QVector<QPair<int, int> > _zooms;
QVector<QPair<QRectF, QRectF> > _bounds;
QVector<Zoom> _zooms;
QVector<Bounds> _bounds;
int _zoom;
int _mapIndex;

View File

@ -19,7 +19,7 @@ public:
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:
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 <QPoint>
#include <QDebug>
#include "rectd.h"
class Tile
{
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;}
const QVariant &zoom() const {return _zoom;}
const QPoint &xy() const {return _xy;}
const QRectF &bbox() const {return _bbox;}
const RectD &bbox() const {return _bbox;}
QPixmap& pixmap() {return _pixmap;}
private:
QVariant _zoom;
QPoint _xy;
QRectF _bbox;
RectD _bbox;
QPixmap _pixmap;
};

View File

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

View File

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