diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp index 127de08f..77b12b30 100644 --- a/src/GUI/gui.cpp +++ b/src/GUI/gui.cpp @@ -2019,10 +2019,7 @@ void GUI::demLoaded() } _demRects.clear(); - - DEM::lock(); DEM::clearCache(); - DEM::unlock(); reloadFiles(); reloadMap(); @@ -3070,9 +3067,7 @@ void GUI::loadOptions() Downloader::setTimeout(_options.connectionTimeout); QPixmapCache::setCacheLimit(_options.pixmapCache * 1024); - DEM::lock(); DEM::setCacheSize(_options.demCache * 1024); - DEM::unlock(); HillShading::setAlpha(_options.hillshadingAlpha); HillShading::setBlur(_options.hillshadingBlur); @@ -3211,11 +3206,8 @@ void GUI::updateOptions(const Options &options) if (options.pixmapCache != _options.pixmapCache) QPixmapCache::setCacheLimit(options.pixmapCache * 1024); - if (options.demCache != _options.demCache) { - DEM::lock(); + if (options.demCache != _options.demCache) DEM::setCacheSize(options.demCache * 1024); - DEM::unlock(); - } SET_HS_OPTION(hillshadingAlpha, setAlpha); SET_HS_OPTION(hillshadingBlur, setBlur); diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp index be4b28e9..743367ec 100644 --- a/src/map/IMG/rastertile.cpp +++ b/src/map/IMG/rastertile.cpp @@ -461,18 +461,16 @@ void RasterTile::fetchData(QList &polygons, MatrixD RasterTile::elevation(int extend) const { - MatrixD m(_rect.height() + 2 * extend, _rect.width() + 2 * extend); - QVector ll; - int left = _rect.left() - extend; int right = _rect.right() + extend; int top = _rect.top() - extend; int bottom = _rect.bottom() + extend; - ll.reserve(m.w() * m.h()); - for (int y = top; y <= bottom; y++) - for (int x = left; x <= right; x++) - ll.append(xy2ll(QPointF(x, y))); + Matrix ll(_rect.height() + 2 * extend, + _rect.width() + 2 * extend); + for (int y = top, i = 0; y <= bottom; y++) + for (int x = left; x <= right; x++, i++) + ll.at(i) = xy2ll(QPointF(x, y)); if (_data->hasDEM()) { RectC rect; @@ -487,16 +485,14 @@ MatrixD RasterTile::elevation(int extend) const -rect.height() / factor), _zoom, &tiles); DEMTree tree(tiles); + MatrixD m(ll.h(), ll.w()); + for (int i = 0; i < ll.size(); i++) m.at(i) = tree.elevation(ll.at(i)); - } else { - DEM::lock(); - for (int i = 0; i < ll.size(); i++) - m.at(i) = DEM::elevation(ll.at(i)); - DEM::unlock(); - } - return m; + return m; + } else + return DEM::elevation(ll); } void RasterTile::drawHillShading(QPainter *painter) const diff --git a/src/map/dem.cpp b/src/map/dem.cpp index 3c5abf56..3bbbbe8a 100644 --- a/src/map/dem.cpp +++ b/src/map/dem.cpp @@ -75,7 +75,9 @@ DEM::TileCache DEM::_data; void DEM::setCacheSize(int size) { + _lock.lock(); _data.setMaxCost(size); + _lock.unlock(); } void DEM::setDir(const QString &path) @@ -85,7 +87,9 @@ void DEM::setDir(const QString &path) void DEM::clearCache() { + _lock.lock(); _data.clear(); + _lock.unlock(); } double DEM::height(const Coordinates &c, const Entry *e) @@ -132,6 +136,27 @@ double DEM::elevation(const Coordinates &c) return NAN; Tile tile(floor(c.lon()), floor(c.lat())); + + _lock.lock(); + + Entry *e = _data.object(tile); + double ele; + + if (!e) { + e = loadTile(tile); + ele = height(c, e); + _data.insert(tile, e, e->data().size() / 1024); + } else + ele = height(c, e); + + _lock.unlock(); + + return ele; +} + +double DEM::elevationLockFree(const Coordinates &c) +{ + Tile tile(floor(c.lon()), floor(c.lat())); Entry *e = _data.object(tile); double ele; @@ -145,6 +170,21 @@ double DEM::elevation(const Coordinates &c) return ele; } +MatrixD DEM::elevation(const Matrix &m) +{ + if (_dir.isEmpty()) + return MatrixD(m.h(), m.w(), NAN); + + MatrixD ret(m.h(), m.w()); + + _lock.lock(); + for (int i = 0; i < m.size(); i++) + ret.at(i) = elevationLockFree(m.at(i)); + _lock.unlock(); + + return ret; +} + QList DEM::tiles() { static const QRegularExpression re( diff --git a/src/map/dem.h b/src/map/dem.h index d6426fa4..0848a274 100644 --- a/src/map/dem.h +++ b/src/map/dem.h @@ -7,6 +7,7 @@ #include #include "common/hash.h" #include "data/area.h" +#include "matrix.h" class Coordinates; @@ -38,8 +39,7 @@ public: static void clearCache(); static double elevation(const Coordinates &c); - static void lock() {_lock.lock();} - static void unlock() {_lock.unlock();} + static MatrixD elevation(const Matrix &m); static QList tiles(); @@ -61,6 +61,7 @@ private: static double height(const Coordinates &c, const Entry *e); static Entry *loadTile(const Tile &tile); + static double elevationLockFree(const Coordinates &c); static QString _dir; static TileCache _data; diff --git a/src/map/map.cpp b/src/map/map.cpp index 1a3fcd2d..16b11761 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1,6 +1,5 @@ #include #include -#include "dem.h" #include "map.h" @@ -80,14 +79,3 @@ qreal Map::resolution(const QRectF &rect) return ds/ps; } - -double Map::elevation(const Coordinates &c) -{ - double ele; - - DEM::lock(); - ele = DEM::elevation(c); - DEM::unlock(); - - return ele; -} diff --git a/src/map/map.h b/src/map/map.h index 0b8e5963..bab5b7f3 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -7,6 +7,7 @@ #include #include "common/rectc.h" #include "common/util.h" +#include "dem.h" class QPainter; @@ -58,7 +59,7 @@ public: virtual void draw(QPainter *painter, const QRectF &rect, Flags flags) = 0; - virtual double elevation(const Coordinates &c); + virtual double elevation(const Coordinates &c) {return DEM::elevation(c);} virtual void clearCache() {} diff --git a/src/map/mapsforge/rastertile.cpp b/src/map/mapsforge/rastertile.cpp index 12c1484e..8e5b695e 100644 --- a/src/map/mapsforge/rastertile.cpp +++ b/src/map/mapsforge/rastertile.cpp @@ -470,26 +470,18 @@ void RasterTile::fetchData(QList &paths, MatrixD RasterTile::elevation(int extend) const { - MatrixD m(_rect.height() + 2 * extend, _rect.width() + 2 * extend); - int left = _rect.left() - extend; int right = _rect.right() + extend; int top = _rect.top() - extend; int bottom = _rect.bottom() + extend; - QVector ll; - ll.reserve(m.w() * m.h()); - for (int y = top; y <= bottom; y++) { - for (int x = left; x <= right; x++) - ll.append(xy2ll(QPointF(x, y))); - } + Matrix ll(_rect.height() + 2 * extend, + _rect.width() + 2 * extend); + for (int y = top, i = 0; y <= bottom; y++) + for (int x = left; x <= right; x++, i++) + ll.at(i) = xy2ll(QPointF(x, y)); - DEM::lock(); - for (int i = 0; i < ll.size(); i++) - m.at(i) = DEM::elevation(ll.at(i)); - DEM::unlock(); - - return m; + return DEM::elevation(ll); } void RasterTile::render()