mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Use a QCache rather than a QMap to prevent memory exhaustion
This commit is contained in:
parent
87f0448ac7
commit
98c4fb2037
@ -4,13 +4,13 @@
|
|||||||
#include "common/coordinates.h"
|
#include "common/coordinates.h"
|
||||||
#include "dem.h"
|
#include "dem.h"
|
||||||
|
|
||||||
|
|
||||||
#define SRTM3_SAMPLES 1201
|
#define SRTM3_SAMPLES 1201
|
||||||
#define SRTM1_SAMPLES 3601
|
#define SRTM1_SAMPLES 3601
|
||||||
|
|
||||||
#define SRTM_SIZE(samples) \
|
#define SRTM_SIZE(samples) \
|
||||||
((samples) * (samples) * 2)
|
((samples) * (samples) * 2)
|
||||||
|
|
||||||
|
|
||||||
static qreal interpolate(qreal dx, qreal dy, qreal p0, qreal p1, qreal p2,
|
static qreal interpolate(qreal dx, qreal dy, qreal p0, qreal p1, qreal p2,
|
||||||
qreal p3)
|
qreal p3)
|
||||||
{
|
{
|
||||||
@ -18,21 +18,21 @@ static qreal interpolate(qreal dx, qreal dy, qreal p0, qreal p1, qreal p2,
|
|||||||
+ p3 * dx * dy;
|
+ p3 * dx * dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal value(int col, int row, int samples, const QByteArray data)
|
static qreal value(int col, int row, int samples, const QByteArray *data)
|
||||||
{
|
{
|
||||||
int pos = ((samples - 1 - row) * samples + col) * 2;
|
int pos = ((samples - 1 - row) * samples + col) * 2;
|
||||||
qint16 val = qFromBigEndian(*((const qint16*)(data.constData() + pos)));
|
qint16 val = qFromBigEndian(*((const qint16*)(data->constData() + pos)));
|
||||||
|
|
||||||
return (val == -32768) ? NAN : val;
|
return (val == -32768) ? NAN : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal height(const Coordinates &c, const QByteArray data)
|
static qreal height(const Coordinates &c, const QByteArray *data)
|
||||||
{
|
{
|
||||||
int samples;
|
int samples;
|
||||||
|
|
||||||
if (data.size() == SRTM_SIZE(SRTM3_SAMPLES))
|
if (data->size() == SRTM_SIZE(SRTM3_SAMPLES))
|
||||||
samples = SRTM3_SAMPLES;
|
samples = SRTM3_SAMPLES;
|
||||||
else if (data.size() == SRTM_SIZE(SRTM1_SAMPLES))
|
else if (data->size() == SRTM_SIZE(SRTM1_SAMPLES))
|
||||||
samples = SRTM1_SAMPLES;
|
samples = SRTM1_SAMPLES;
|
||||||
else
|
else
|
||||||
return NAN;
|
return NAN;
|
||||||
@ -52,16 +52,16 @@ static qreal height(const Coordinates &c, const QByteArray data)
|
|||||||
|
|
||||||
|
|
||||||
QString DEM::_dir;
|
QString DEM::_dir;
|
||||||
QMap<DEM::Key, QByteArray> DEM::_data;
|
QCache<DEM::Key, QByteArray> DEM::_data;
|
||||||
|
|
||||||
QString DEM::fileName(const Key &key)
|
QString DEM::fileName(const Key &key)
|
||||||
{
|
{
|
||||||
const char ns = (key.lat >= 0) ? 'N' : 'S';
|
const char ns = (key.lat() >= 0) ? 'N' : 'S';
|
||||||
const char ew = (key.lon >= 0) ? 'E' : 'W';
|
const char ew = (key.lon() >= 0) ? 'E' : 'W';
|
||||||
|
|
||||||
QString basename = QString("%1%2%3%4.hgt").arg(ns)
|
QString basename = QString("%1%2%3%4.hgt").arg(ns)
|
||||||
.arg(qAbs(key.lat), 2, 10, QChar('0')).arg(ew)
|
.arg(qAbs(key.lat()), 2, 10, QChar('0')).arg(ew)
|
||||||
.arg(qAbs(key.lon), 3, 10, QChar('0'));
|
.arg(qAbs(key.lon()), 3, 10, QChar('0'));
|
||||||
return QDir(_dir).absoluteFilePath(basename);
|
return QDir(_dir).absoluteFilePath(basename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,18 +77,19 @@ qreal DEM::elevation(const Coordinates &c)
|
|||||||
|
|
||||||
Key k((int)c.lon(), (int)c.lat());
|
Key k((int)c.lon(), (int)c.lat());
|
||||||
|
|
||||||
QMap<Key, QByteArray>::const_iterator it(_data.find(k));
|
QByteArray *ba = _data[k];
|
||||||
if (it == _data.constEnd()) {
|
if (!ba) {
|
||||||
QFile file(fileName(k));
|
QFile file(fileName(k));
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
qWarning("%s: %s", qPrintable(file.fileName()),
|
qWarning("%s: %s", qPrintable(file.fileName()),
|
||||||
qPrintable(file.errorString()));
|
qPrintable(file.errorString()));
|
||||||
_data.insert(k, QByteArray());
|
_data.insert(k, new QByteArray());
|
||||||
return NAN;
|
return NAN;
|
||||||
} else {
|
} else {
|
||||||
it = _data.insert(k, file.readAll());
|
ba = new QByteArray(file.readAll());
|
||||||
return height(c, *it);
|
_data.insert(k, ba);
|
||||||
|
return height(c, ba);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
return height(c, *it);
|
return height(c, ba);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define DEM_H
|
#define DEM_H
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QMap>
|
#include <QCache>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
@ -10,32 +10,38 @@ class Coordinates;
|
|||||||
|
|
||||||
class DEM
|
class DEM
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
static void setDir(const QString &path);
|
|
||||||
static qreal elevation(const Coordinates &c);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Key {
|
class Key {
|
||||||
int lon;
|
public:
|
||||||
int lat;
|
Key(int lon, int lat) : _lon(lon), _lat(lat) {}
|
||||||
|
|
||||||
Key(int lon, int lat) : lon(lon), lat(lat) {}
|
int lon() const {return _lon;}
|
||||||
|
int lat() const {return _lat;}
|
||||||
|
|
||||||
bool operator<(const Key &other) const
|
bool operator==(const Key &other) const
|
||||||
{
|
{
|
||||||
if (lon < other.lon)
|
return (_lon == other._lon && _lat == other._lat);
|
||||||
return true;
|
|
||||||
else if (lon > other.lon)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return (lat < other.lat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _lon, _lat;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QString fileName(const Key &key);
|
static QString fileName(const Key &key);
|
||||||
|
|
||||||
static QString _dir;
|
static QString _dir;
|
||||||
static QMap<Key, QByteArray> _data;
|
static QCache<Key, QByteArray> _data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void setDir(const QString &path);
|
||||||
|
static qreal elevation(const Coordinates &c);
|
||||||
|
|
||||||
|
friend uint qHash(const Key &key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline uint qHash(const DEM::Key &key)
|
||||||
|
{
|
||||||
|
return (key.lon() ^ key.lat());
|
||||||
|
}
|
||||||
|
|
||||||
#endif // DEM_H
|
#endif // DEM_H
|
||||||
|
Loading…
Reference in New Issue
Block a user