From fd53e89ea58eca753efb74edc6d9bbfe6fec1456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Sat, 15 Apr 2017 08:59:31 +0200 Subject: [PATCH] Improved error handling --- src/offlinemap.cpp | 142 +++++++++++++++++++++++++++------------------ src/offlinemap.h | 4 ++ src/ozf.cpp | 15 ++--- src/ozf.h | 1 - 4 files changed, 92 insertions(+), 70 deletions(-) diff --git a/src/offlinemap.cpp b/src/offlinemap.cpp index 94e28d64..9c11726e 100644 --- a/src/offlinemap.cpp +++ b/src/offlinemap.cpp @@ -305,8 +305,8 @@ bool OfflineMap::getImageInfo(const QString &path) } if (_imgPath.endsWith("ozf2")) { - _ozf.load(_imgPath); - _size = _ozf.size(); + if (_ozf.load(_imgPath)) + _size = _ozf.size(); } else { QImageReader img(_imgPath); _size = img.size(); @@ -540,74 +540,100 @@ void OfflineMap::unload() } } -void OfflineMap::draw(QPainter *painter, const QRectF &rect) +void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect) { - if (_tileSize.isValid()) { - QPoint tl = QPoint((int)floor(rect.left() / (qreal)_tileSize.width()) - * _tileSize.width(), (int)floor(rect.top() / _tileSize.height()) - * _tileSize.height()); + QPoint tl = QPoint((int)floor(rect.left() / (qreal)_tileSize.width()) + * _tileSize.width(), (int)floor(rect.top() / _tileSize.height()) + * _tileSize.height()); - 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(); - QString tileName(_tileName.arg(QString::number(x), - QString::number(y))); - QPixmap pixmap; + 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(); - if (_tar.isOpen()) { - QString key = _tar.fileName() + "/" + tileName; - if (!QPixmapCache::find(key, &pixmap)) { - QByteArray ba = _tar.file(tileName); - pixmap = QPixmap::fromImage(QImage::fromData(ba)); - if (!pixmap.isNull()) - QPixmapCache::insert(key, pixmap); - } - } else - pixmap = QPixmap(tileName); - - 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); + if (!QRectF(QPointF(x, y), _ozf.tileSize()).intersects(bounds())) { + painter->fillRect(QRectF(QPoint(x, y), _tileSize), Qt::white); + continue; } - } - } else if (_ozf.isOpen()) { - QPoint tl = QPoint((int)floor(rect.left() - / (qreal)_ozf.tileSize().width()) * _ozf.tileSize().width(), - (int)floor(rect.top() / _ozf.tileSize().height()) - * _ozf.tileSize().height()); - QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y()); - for (int i = 0; i < ceil(s.width() / _ozf.tileSize().width()); i++) { - for (int j = 0; j < ceil(s.height() / _ozf.tileSize().height()); - j++) { - int x = tl.x() + i * _ozf.tileSize().width(); - int y = tl.y() + j * _ozf.tileSize().height(); + QString tileName(_tileName.arg(QString::number(x), + QString::number(y))); + QPixmap pixmap; - QPixmap pixmap; - QString key = _ozf.fileName() + "/" + QString::number(x) - + "_" + QString::number(y); + if (_tar.isOpen()) { + QString key = _tar.fileName() + "/" + tileName; if (!QPixmapCache::find(key, &pixmap)) { - pixmap = _ozf.tile(x, y); + QByteArray ba = _tar.file(tileName); + pixmap = QPixmap::fromImage(QImage::fromData(ba)); if (!pixmap.isNull()) QPixmapCache::insert(key, pixmap); } + } else + pixmap = QPixmap(tileName); + 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 || _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); } } } + +void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect) +{ + QPoint tl = QPoint((int)floor(rect.left() / _ozf.tileSize().width()) + * _ozf.tileSize().width(), (int)floor(rect.top() + / _ozf.tileSize().height()) * _ozf.tileSize().height()); + + QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y()); + for (int i = 0; i < ceil(s.width() / _ozf.tileSize().width()); i++) { + for (int j = 0; j < ceil(s.height() / _ozf.tileSize().height()); j++) { + int x = tl.x() + i * _ozf.tileSize().width(); + int y = tl.y() + j * _ozf.tileSize().height(); + + if (!QRectF(QPointF(x, y), _ozf.tileSize()).intersects(bounds())) { + painter->fillRect(QRectF(QPoint(x, y), _tileSize), Qt::white); + continue; + } + + QPixmap pixmap; + QString key = _ozf.fileName() + "/" + QString::number(x) + + "_" + QString::number(y); + if (!QPixmapCache::find(key, &pixmap)) { + pixmap = _ozf.tile(x, y); + if (!pixmap.isNull()) + QPixmapCache::insert(key, pixmap); + } + + if (pixmap.isNull()) { + qWarning("%s: error loading tile image", qPrintable(key)); + painter->fillRect(QRectF(QPoint(x, y), _tileSize), Qt::white); + } else + painter->drawPixmap(QPoint(x, y), pixmap); + } + } +} + +void OfflineMap::drawImage(QPainter *painter, const QRectF &rect) +{ + if (!_img || _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); + } +} + +void OfflineMap::draw(QPainter *painter, const QRectF &rect) +{ + if (_ozf.isOpen()) + drawOZF(painter, rect); + else if (_tileSize.isValid()) + drawTiled(painter, rect); + else + drawImage(painter, rect); +} diff --git a/src/offlinemap.h b/src/offlinemap.h index 77201262..460cc47e 100644 --- a/src/offlinemap.h +++ b/src/offlinemap.h @@ -79,6 +79,10 @@ private: bool getTileInfo(const QStringList &tiles, const QString &path = QString()); bool getImageInfo(const QString &path); + void drawTiled(QPainter *painter, const QRectF &rect); + void drawOZF(QPainter *painter, const QRectF &rect); + void drawImage(QPainter *painter, const QRectF &rect); + QString _name; QSize _size; Projection *_projection; diff --git a/src/ozf.cpp b/src/ozf.cpp index 84d37e56..8cf11907 100644 --- a/src/ozf.cpp +++ b/src/ozf.cpp @@ -113,33 +113,26 @@ bool OZF::load(const QString &path) return true; } -QPixmap OZF::blankTile() -{ - QPixmap p(tileSize()); - p.fill(); - return p; -} - QPixmap OZF::tile(int x, int y) { Q_ASSERT(_file.isOpen()); int i = (y/tileSize().height()) * _dim.width() + (x/tileSize().width()); if (i >= _tiles.size() - 1 || i < 0) - return blankTile(); + return QPixmap(); int size = _tiles.at(i+1) - _tiles.at(i); if (!_file.seek(_tiles.at(i))) - return blankTile(); + return QPixmap(); QByteArray ba = _file.read(size); if (ba.size() != size) - return blankTile(); + return QPixmap(); quint32 bes = qToBigEndian(tileSize().width() * tileSize().height()); ba.prepend(QByteArray((char*)&bes, sizeof(bes))); QByteArray uba = qUncompress(ba); if (uba.size() != tileSize().width() * tileSize().height()) - return blankTile(); + return QPixmap(); QImage img((const uchar*)uba.constData(), tileSize().width(), tileSize().height(), QImage::Format_Indexed8); diff --git a/src/ozf.h b/src/ozf.h index 66d81f5d..65a44890 100644 --- a/src/ozf.h +++ b/src/ozf.h @@ -24,7 +24,6 @@ private: template bool readValue(T &val); bool readHeaders(); bool readTileTable(); - QPixmap blankTile(); QSize _size; QSize _dim;