1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +01:00

Added support for tiled offline maps

This commit is contained in:
Martin Tůma 2017-03-20 10:05:07 +01:00
parent 2bf66ea912
commit 92545acba0
2 changed files with 90 additions and 23 deletions

View File

@ -26,9 +26,7 @@ int OziMap::parseMapFile(QIODevice &device, QList<ReferencePoint> &points)
if (ln == 1) {
if (line.trimmed() != "OziExplorer Map Data File Version 2.2")
return ln;
} else if (ln == 2)
_name = line.trimmed();
else if (ln == 3)
} else if (ln == 3)
_imgPath = line.trimmed();
else if (ln >= 10 && ln < 40) {
QList<QByteArray> list = line.split(',');
@ -152,6 +150,39 @@ bool OziMap::computeResolution(QList<ReferencePoint> &points)
return true;
}
bool OziMap::getTileInfo(QDir &set)
{
QFileInfoList tiles = set.entryInfoList(QDir::Files);
if (tiles.isEmpty()) {
qWarning("%s: empty tile set", qPrintable(_name));
return false;
}
for (int i = 0; i < tiles.size(); i++) {
if (tiles.at(i).fileName().contains("_0_0.")) {
_tileName = QString(tiles.at(i).fileName())
.replace("_0_0.", "_%1_%2.");
break;
}
}
if (_tileName.isNull()) {
qWarning("%s: invalid tile names", qPrintable(_name));
return false;
}
_tileName = set.absolutePath() + "/" + _tileName;
QImage tile(_tileName.arg("0", "0"));
if (tile.isNull()) {
qWarning("%s: %s: invalid image", qPrintable(_name),
qPrintable(_tileName.arg("0", "0")));
return false;
}
_tileSize = tile.size();
return true;
}
OziMap::OziMap(const QString &path, QObject *parent) : Map(parent)
{
int errorLine;
@ -186,27 +217,35 @@ OziMap::OziMap(const QString &path, QObject *parent) : Map(parent)
}
computeResolution(points);
QFileInfo ii(_imgPath);
if (ii.isRelative())
_imgPath = fi.absoluteFilePath() + "/" + _imgPath;
ii = QFileInfo(_imgPath);
if (!ii.exists()) {
qWarning("%s: %s: no such image", qPrintable(_name),
qPrintable(ii.absoluteFilePath()));
return;
}
if (_size.isNull()) {
if (!_size.isValid()) {
qWarning("%s: missing or invalid image size (IWH)", qPrintable(_name));
return;
}
QDir set(fi.absoluteFilePath() + "/" + "set");
if (set.exists()) {
if (!getTileInfo(set))
return;
} else {
QFileInfo ii(_imgPath);
if (ii.isRelative())
_imgPath = fi.absoluteFilePath() + "/" + _imgPath;
ii = QFileInfo(_imgPath);
if (!ii.exists()) {
qWarning("%s: %s: no such image", qPrintable(_name),
qPrintable(ii.absoluteFilePath()));
return;
}
}
_img = 0;
_valid = true;
}
void OziMap::load()
{
Q_ASSERT(_img == 0);
if (_tileSize.isValid())
return;
_img = new QImage(_imgPath);
if (_img->isNull())
@ -215,10 +254,8 @@ void OziMap::load()
void OziMap::unload()
{
Q_ASSERT(_img != 0);
delete _img;
_img = 0;
if (_img)
delete _img;
}
QRectF OziMap::bounds() const
@ -253,11 +290,36 @@ qreal OziMap::zoomOut()
void OziMap::draw(QPainter *painter, const QRectF &rect)
{
Q_ASSERT(_img != 0);
if (_tileSize.isValid()) {
QPoint tl = QPoint((int)floor(rect.left() / (qreal)_tileSize.width())
* _tileSize.width(), (int)floor(rect.top() / _tileSize.height())
* _tileSize.height());
QPoint p = rect.topLeft().toPoint();
QImage crop = _img->copy(QRect(p, rect.size().toSize()));
painter->drawImage(rect.topLeft(), crop);
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
for (int i = 0; i < ceil(s.width() / _tileSize.width()); i++) {
for (int j = 0; j < ceil(s.height() / _tileSize.height()); j++) {
int x = tl.x() + i * _tileSize.width();
int y = tl.y() + j * _tileSize.height();
QPixmap pixmap(_tileName.arg(QString::number(x),
QString::number(y)));
if (pixmap.isNull()) {
qWarning("%s: error loading tile image", qPrintable(
_tileName.arg(QString::number(x), QString::number(y))));
painter->fillRect(QRectF(QPoint(x, y), _tileSize),
Qt::white);
} else
painter->drawPixmap(QPoint(x, y), pixmap);
}
}
} else {
if (_img->isNull())
painter->fillRect(rect, Qt::white);
else {
QPoint p = rect.topLeft().toPoint();
QImage crop = _img->copy(QRect(p, rect.size().toSize()));
painter->drawImage(rect.topLeft(), crop);
}
}
}
QPointF OziMap::ll2xy(const Coordinates &c) const

View File

@ -7,6 +7,7 @@
#include "coordinates.h"
class QIODevice;
class QDir;
class OziMap : public Map
{
@ -41,6 +42,7 @@ private:
int parseMapFile(QIODevice &device, QList<ReferencePoint> &points);
bool computeTransformation(const QList<ReferencePoint> &points);
bool computeResolution(QList<ReferencePoint> &points);
bool getTileInfo(QDir &set);
QString _name;
QString _imgPath;
@ -48,8 +50,11 @@ private:
QTransform _transform;
qreal _resolution;
bool _valid;
QImage *_img;
QSize _tileSize;
QString _tileName;
bool _valid;
};
#endif // OZIMAP_H