From c3f345c7f9139f17ea6945ac372d61a302351142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Thu, 31 Dec 2020 14:03:30 +0100 Subject: [PATCH] Added support for ZIPed DEM files --- src/data/dem.cpp | 52 ++++++++++++++++++++++++++++++++++++++---------- src/data/dem.h | 3 ++- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/data/dem.cpp b/src/data/dem.cpp index 004156f1..f2ce7f28 100644 --- a/src/data/dem.cpp +++ b/src/data/dem.cpp @@ -1,7 +1,21 @@ +/* + WARNING: This code uses internal Qt API - the QZipReader class for reading + ZIP files - and things may break if Qt changes the API. For Qt5 this is not + a problem as we can "see the future" now and there are no changes in all + the supported Qt5 versions up to the last one (5.15). In Qt6 the class + might change or even disappear in the future, but this is very unlikely + as there were no changes for several years and The Qt Company's policy + is: "do not invest any resources into any desktop related stuff unless + absolutely necessary". There is an issue (QTBUG-3897) since the year 2009 to + include the ZIP reader into the public API, which aptly illustrates the + effort The Qt Company is willing to make about anything desktop related... +*/ + #include #include #include #include +#include #include "common/coordinates.h" #include "dem.h" @@ -55,15 +69,19 @@ static qreal height(const Coordinates &c, const QByteArray *data) QString DEM::_dir; QCache DEM::_data; -QString DEM::fileName(const Key &key) +QString DEM::baseName(const Key &key) { const char ns = (key.lat() >= 0) ? 'N' : 'S'; const char ew = (key.lon() >= 0) ? 'E' : 'W'; - QString basename = QString("%1%2%3%4.hgt").arg(ns) + return QString("%1%2%3%4.hgt").arg(ns) .arg(qAbs(key.lat()), 2, 10, QChar('0')).arg(ew) .arg(qAbs(key.lon()), 3, 10, QChar('0')); - return QDir(_dir).absoluteFilePath(basename); +} + +QString DEM::fileName(const QString &baseName) +{ + return QDir(_dir).absoluteFilePath(baseName); } void DEM::setDir(const QString &path) @@ -80,17 +98,29 @@ qreal DEM::elevation(const Coordinates &c) QByteArray *ba = _data[k]; if (!ba) { - QFile file(fileName(k)); - if (!file.open(QIODevice::ReadOnly)) { - qWarning("%s: %s", qPrintable(file.fileName()), - qPrintable(file.errorString())); - _data.insert(k, new QByteArray()); - return NAN; - } else { - ba = new QByteArray(file.readAll()); + QString bn(baseName(k)); + QString fn(fileName(bn)); + QString zn(fn + ".zip"); + + if (QFileInfo::exists(zn)) { + QZipReader zip(zn, QIODevice::ReadOnly); + ba = new QByteArray(zip.fileData(bn)); qreal ele = height(c, ba); _data.insert(k, ba); return ele; + } else { + QFile file(fn); + if (!file.open(QIODevice::ReadOnly)) { + qWarning("%s: %s", qPrintable(file.fileName()), + qPrintable(file.errorString())); + _data.insert(k, new QByteArray()); + return NAN; + } else { + ba = new QByteArray(file.readAll()); + qreal ele = height(c, ba); + _data.insert(k, ba); + return ele; + } } } else return height(c, ba); diff --git a/src/data/dem.h b/src/data/dem.h index 2e4aa0e7..46e25b4e 100644 --- a/src/data/dem.h +++ b/src/data/dem.h @@ -27,7 +27,8 @@ private: int _lon, _lat; }; - static QString fileName(const Key &key); + static QString baseName(const Key &key); + static QString fileName(const QString &baseName); static QString _dir; static QCache _data;