1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-06-27 03:29:16 +02:00

Move the DEM sources to the common folder now that we use them in map/data

This commit is contained in:
2024-02-22 21:34:34 +01:00
parent 108e68c7c9
commit f7a81cafd5
11 changed files with 20 additions and 20 deletions

View File

@ -1,186 +0,0 @@
/*
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 <QtEndian>
#include <QtMath>
#include <QDir>
#include <QFile>
#include <QRegularExpression>
#include <QLocale>
#include <private/qzipreader_p.h>
#include "common/rectc.h"
#include "dem.h"
#define SRTM3_SAMPLES 1201
#define SRTM1_SAMPLES 3601
#define SRTM05_SAMPLES 7201
#define SRTM_SIZE(samples) \
((samples) * (samples) * 2)
static double interpolate(double dx, double dy, double p0, double p1, double p2,
double p3)
{
return p0 * (1.0 - dx) * (1.0 - dy) + p1 * dx * (1.0 - dy)
+ p2 * dy * (1.0 - dx) + p3 * dx * dy;
}
static double value(int col, int row, int samples, const QByteArray *data)
{
int pos = ((samples - 1 - row) * samples + col) * 2;
qint16 val = qFromBigEndian(*((const qint16*)(data->constData() + pos)));
return (val == -32768) ? NAN : val;
}
static double height(const Coordinates &c, const QByteArray *data)
{
int samples;
if (data->size() == SRTM_SIZE(SRTM3_SAMPLES))
samples = SRTM3_SAMPLES;
else if (data->size() == SRTM_SIZE(SRTM1_SAMPLES))
samples = SRTM1_SAMPLES;
else if (data->size() == SRTM_SIZE(SRTM05_SAMPLES))
samples = SRTM05_SAMPLES;
else
return NAN;
double lat = (c.lat() - floor(c.lat())) * (samples - 1);
double lon = (c.lon() - floor(c.lon())) * (samples - 1);
int row = (int)lat;
int col = (int)lon;
double p0 = value(col, row, samples, data);
double p1 = value(col + 1, row, samples, data);
double p2 = value(col, row + 1, samples, data);
double p3 = value(col + 1, row + 1, samples, data);
return interpolate(lon - col, lat - row, p0, p1, p2, p3);
}
QMutex DEM::_lock;
QString DEM::Tile::latStr() const
{
const char ns = (_lat >= 0) ? 'N' : 'S';
return QString("%1%2").arg(ns).arg(qAbs(_lat), 2, 10, QChar('0'));
}
QString DEM::Tile::lonStr() const
{
const char ew = (_lon >= 0) ? 'E' : 'W';
return QString("%1%2").arg(ew).arg(qAbs(_lon), 3, 10, QChar('0'));
}
QString DEM::Tile::baseName() const
{
return QString("%1%2.hgt").arg(latStr(), lonStr());
}
QString DEM::_dir;
DEM::TileCache DEM::_data;
void DEM::setCacheSize(int size)
{
_data.setMaxCost(size * 1024);
}
void DEM::setDir(const QString &path)
{
_dir = path;
}
void DEM::clearCache()
{
_data.clear();
}
QByteArray *DEM::loadTile(const Tile &tile)
{
QString bn(tile.baseName());
QString fn(QDir(_dir).absoluteFilePath(bn));
QString zn(fn + ".zip");
if (QFileInfo::exists(zn)) {
QZipReader zip(zn, QIODevice::ReadOnly);
return new QByteArray(zip.fileData(bn));
} else {
QFile file(fn);
if (!file.open(QIODevice::ReadOnly)) {
qWarning("%s: %s", qPrintable(file.fileName()),
qPrintable(file.errorString()));
return new QByteArray();
} else
return new QByteArray(file.readAll());
}
}
double DEM::elevation(const Coordinates &c)
{
if (_dir.isEmpty())
return NAN;
Tile tile(qFloor(c.lon()), qFloor(c.lat()));
QByteArray *ba = _data.object(tile);
double ele;
if (!ba) {
ba = loadTile(tile);
ele = height(c, ba);
_data.insert(tile, ba, ba->size());
} else
ele = height(c, ba);
return ele;
}
QList<Area> DEM::tiles()
{
static const QRegularExpression re("([NS])([0-9]{2})([EW])([0-9]{3})");
QDir dir(_dir);
QFileInfoList files(dir.entryInfoList(QDir::Files | QDir::Readable));
QLocale l(QLocale::system());
QList<Area> list;
for (int i = 0; i < files.size(); i++) {
QString basename(files.at(i).baseName());
QRegularExpressionMatch match(re.match(basename));
if (!match.hasMatch())
continue;
int lat = match.captured(2).toInt();
int lon = match.captured(4).toInt();
if (match.captured(1) == "S")
lat = -lat;
if (match.captured(3) == "W")
lon = -lon;
Area area(RectC(Coordinates(lon, lat + 1), Coordinates(lon + 1, lat)));
area.setName(basename);
area.setDescription(files.at(i).suffix().toUpper() + ", "
+ l.formattedDataSize(files.at(i).size()));
list.append(area);
}
return list;
}
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const DEM::Tile &tile)
{
dbg.nospace() << "Tile(" << tile.baseName() << ")";
return dbg.space();
}
#endif // QT_NO_DEBUG

View File

@ -1,65 +0,0 @@
#ifndef DEM_H
#define DEM_H
#include <QString>
#include <QCache>
#include <QByteArray>
#include <QMutex>
#include "common/hash.h"
#include "area.h"
class Coordinates;
class DEM
{
public:
class Tile {
public:
Tile(int lon, int lat) : _lon(lon), _lat(lat) {}
int lon() const {return _lon;}
int lat() const {return _lat;}
QString lonStr() const;
QString latStr() const;
QString baseName() const;
bool operator==(const Tile &other) const
{
return (_lon == other._lon && _lat == other._lat);
}
private:
int _lon, _lat;
};
static void setCacheSize(int size);
static void setDir(const QString &path);
static void clearCache();
static double elevation(const Coordinates &c);
static void lock() {_lock.lock();}
static void unlock() {_lock.unlock();}
static QList<Area> tiles();
private:
typedef QCache<DEM::Tile, QByteArray> TileCache;
static QByteArray *loadTile(const Tile &tile);
static QString _dir;
static TileCache _data;
static QMutex _lock;
};
inline HASH_T qHash(const DEM::Tile &tile)
{
return (qHash(tile.lon()) ^ qHash(tile.lat()));
}
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const DEM::Tile &tile);
#endif // QT_NO_DEBUG
#endif // DEM_H

View File

@ -4,7 +4,7 @@
#include <QObject>
#include <QDir>
#include "common/downloader.h"
#include "dem.h"
#include "common/dem.h"
class RectC;

View File

@ -1,4 +1,4 @@
#include "dem.h"
#include "common/dem.h"
#include "route.h"
bool Route::_useDEM = false;

View File

@ -1,4 +1,4 @@
#include "dem.h"
#include "common/dem.h"
#include "track.h"

View File

@ -1,6 +1,6 @@
#include <QDir>
#include <QFileInfo>
#include "dem.h"
#include "common/dem.h"
#include "waypoint.h"
bool Waypoint::_useDEM = false;