mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-06-27 03:29:16 +02:00
Added support for DEM data (SRTM HGT) elevation sources
This commit is contained in:
58
src/data/dem.cpp
Normal file
58
src/data/dem.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include <QtEndian>
|
||||
#include "common/coordinates.h"
|
||||
#include "dem.h"
|
||||
|
||||
#define SRTM3_SAMPLES 1201
|
||||
#define SRTM1_SAMPLES 3601
|
||||
|
||||
#define SRTM_SIZE(samples) \
|
||||
((samples) * (samples) * 2)
|
||||
|
||||
|
||||
static qreal 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
|
||||
return NAN;
|
||||
|
||||
int lat = int(qRound((c.lat() - int(c.lat())) * (samples - 1)));
|
||||
int lon = int(qRound((c.lon() - int(c.lon())) * (samples - 1)));
|
||||
|
||||
int pos = ((samples - 1 - lat) * samples + lon) * 2;
|
||||
qint16 val = qFromBigEndian(*((const qint16*)(data.constData() + pos)));
|
||||
|
||||
return (val == -32768) ? NAN : val;
|
||||
}
|
||||
|
||||
QString DEM::fileName(const Key &key) const
|
||||
{
|
||||
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)
|
||||
.arg(qAbs(key.lat), 2, 10, QChar('0')).arg(ew)
|
||||
.arg(qAbs(key.lon), 3, 10, QChar('0'));
|
||||
return _dir.absoluteFilePath(basename);
|
||||
}
|
||||
|
||||
qreal DEM::elevation(const Coordinates &c)
|
||||
{
|
||||
Key k((int)c.lon(), (int)c.lat());
|
||||
|
||||
QMap<Key, QByteArray>::const_iterator it(_data.find(k));
|
||||
if (it == _data.constEnd()) {
|
||||
QFile file(fileName(k));
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
return NAN;
|
||||
else {
|
||||
it = _data.insert(k, file.readAll());
|
||||
return height(c, *it);
|
||||
}
|
||||
} else
|
||||
return height(c, *it);
|
||||
}
|
43
src/data/dem.h
Normal file
43
src/data/dem.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef DEM_H
|
||||
#define DEM_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QByteArray>
|
||||
#include <QDir>
|
||||
|
||||
class QDir;
|
||||
class Coordinates;
|
||||
|
||||
class DEM
|
||||
{
|
||||
public:
|
||||
DEM() {}
|
||||
DEM(const QDir &dir) : _dir(dir) {}
|
||||
qreal elevation(const Coordinates &c);
|
||||
|
||||
private:
|
||||
struct Key {
|
||||
int lon;
|
||||
int lat;
|
||||
|
||||
Key(int lon, int lat) : lon(lon), lat(lat) {}
|
||||
|
||||
bool operator<(const Key &other) const
|
||||
{
|
||||
if (lon < other.lon)
|
||||
return true;
|
||||
else if (lon > other.lon)
|
||||
return false;
|
||||
else
|
||||
return (lat < other.lat);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
QString fileName(const Key &key) const;
|
||||
|
||||
QDir _dir;
|
||||
QMap<Key, QByteArray> _data;
|
||||
};
|
||||
|
||||
#endif // DEM_H
|
@ -1,5 +1,7 @@
|
||||
#include "dem.h"
|
||||
#include "track.h"
|
||||
|
||||
|
||||
int Track::_elevationWindow = 3;
|
||||
int Track::_speedWindow = 5;
|
||||
int Track::_heartRateWindow = 3;
|
||||
@ -11,6 +13,9 @@ int Track::_pauseInterval = 10;
|
||||
|
||||
bool Track::_outlierEliminate = true;
|
||||
bool Track::_useReportedSpeed = false;
|
||||
bool Track::_useDEMElevation = false;
|
||||
|
||||
DEM Track::_dem;
|
||||
|
||||
|
||||
static qreal median(QVector<qreal> &v)
|
||||
@ -147,10 +152,19 @@ Graph Track::elevation() const
|
||||
{
|
||||
Graph raw;
|
||||
|
||||
for (int i = 0; i < _data.size(); i++)
|
||||
if (_data.at(i).hasElevation() && !_outliers.contains(i))
|
||||
for (int i = 0; i < _data.size(); i++) {
|
||||
if (_outliers.contains(i))
|
||||
continue;
|
||||
|
||||
if (_data.at(i).hasElevation() && !_useDEMElevation)
|
||||
raw.append(GraphPoint(_distance.at(i), _time.at(i),
|
||||
_data.at(i).elevation()));
|
||||
else {
|
||||
qreal elevation = _dem.elevation(_data.at(i).coordinates());
|
||||
if (!std::isnan(elevation))
|
||||
raw.append(GraphPoint(_distance.at(i), _time.at(i), elevation));
|
||||
}
|
||||
}
|
||||
|
||||
return filter(raw, _elevationWindow);
|
||||
}
|
||||
|
@ -4,8 +4,10 @@
|
||||
#include <QVector>
|
||||
#include <QSet>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include "trackdata.h"
|
||||
#include "graph.h"
|
||||
#include "dem.h"
|
||||
#include "path.h"
|
||||
|
||||
|
||||
@ -44,6 +46,8 @@ public:
|
||||
static void setOutlierElimination(bool eliminate)
|
||||
{_outlierEliminate = eliminate;}
|
||||
static void useReportedSpeed(bool use) {_useReportedSpeed = use;}
|
||||
static void useDEMElevation(bool use) {_useDEMElevation = use;}
|
||||
static void setDEMDir(const QDir &dir) {_dem = DEM(dir);}
|
||||
|
||||
private:
|
||||
bool discardStopPoint(int i) const;
|
||||
@ -68,6 +72,8 @@ private:
|
||||
static qreal _pauseSpeed;
|
||||
static int _pauseInterval;
|
||||
static bool _useReportedSpeed;
|
||||
static bool _useDEMElevation;
|
||||
static DEM _dem;
|
||||
};
|
||||
|
||||
#endif // TRACK_H
|
||||
|
Reference in New Issue
Block a user