From b91d729097187c40309ad0c84dd0ab19ab552451 Mon Sep 17 00:00:00 2001 From: Andreas Bircher Date: Thu, 16 Nov 2017 11:58:06 -0500 Subject: [PATCH] online version --- src/Terrain.cc | 84 +++++++++++++++++++++++++++------------------- src/Terrain.h | 11 +++++- src/TerrainTile.cc | 4 +-- src/TerrainTile.h | 2 +- 4 files changed, 62 insertions(+), 39 deletions(-) diff --git a/src/Terrain.cc b/src/Terrain.cc index 875a5d6ce..8920a5fe9 100644 --- a/src/Terrain.cc +++ b/src/Terrain.cc @@ -30,39 +30,9 @@ ElevationProvider::ElevationProvider(QObject* parent) } -bool ElevationProvider::queryTerrainData(const QList& coordinates) +bool ElevationProvider::queryTerrainDataPoints(const QList& coordinates) { - if (coordinates.length() == 0) { - return false; - } - - bool fallBackToOnline = false; - QList altitudes; - foreach (QGeoCoordinate coordinate, coordinates) { - QString uniqueTileId = _uniqueTileId(coordinate); - _tilesMutex.lock(); - if (!_tiles.contains(uniqueTileId)) { - _tilesMutex.unlock(); - fallBackToOnline = true; - break; - } else { - if (_tiles[uniqueTileId].isIn(coordinate)) { - altitudes.push_back(_tiles[uniqueTileId].elevation(coordinate)); - } else { - qCDebug(TerrainLog) << "Error: coordinate not in tile region"; - altitudes.push_back(-1.0); - } - } - _tilesMutex.unlock(); - } - - if (!fallBackToOnline) { - qCDebug(TerrainLog) << "All altitudes taken from cached data"; - emit terrainData(true, altitudes); - return true; - } - - if (_state != State::Idle) { + if (_state != State::Idle || coordinates.length() == 0) { return false; } @@ -95,6 +65,47 @@ bool ElevationProvider::queryTerrainData(const QList& coordinate return true; } +bool ElevationProvider::queryTerrainData(const QList& coordinates) +{ + if (_state != State::Idle || coordinates.length() == 0) { + return false; + } + + QList altitudes; + bool needToDownload = false; + foreach (QGeoCoordinate coordinate, coordinates) { + QString uniqueTileId = _uniqueTileId(coordinate); + _tilesMutex.lock(); + if (!_tiles.contains(uniqueTileId)) { + qCDebug(TerrainLog) << "Need to download tile " << uniqueTileId; + _downloadQueue.append(uniqueTileId); + needToDownload = true; + } else { + if (!needToDownload) { + if (_tiles[uniqueTileId].isIn(coordinate)) { + altitudes.push_back(_tiles[uniqueTileId].elevation(coordinate)); + } else { + qCDebug(TerrainLog) << "Error: coordinate not in tile region"; + altitudes.push_back(-1.0); + } + } + } + _tilesMutex.unlock(); + } + + if (!needToDownload) { + qCDebug(TerrainLog) << "All altitudes taken from cached data"; + emit terrainData(true, altitudes); + _coordinates.clear(); + return true; + } + + _coordinates = coordinates; + + _downloadTiles(); + return true; +} + bool ElevationProvider::cacheTerrainTiles(const QGeoCoordinate& southWest, const QGeoCoordinate& northEast) { qCDebug(TerrainLog) << "Cache terrain tiles southWest:northEast" << southWest << northEast; @@ -116,7 +127,7 @@ bool ElevationProvider::cacheTerrainTiles(const QGeoCoordinate& southWest, const _tilesMutex.unlock(); continue; } - _downloadQueue.append(uniqueTileId.replace("_", ",")); + _downloadQueue.append(uniqueTileId); _tilesMutex.unlock(); qCDebug(TerrainLog) << "Adding tile to download queue: " << uniqueTileId; } @@ -139,7 +150,7 @@ bool ElevationProvider::cacheTerrainTiles(const QList& coordinat _tilesMutex.unlock(); continue; } - _downloadQueue.append(uniqueTileId.replace("_", ",")); + _downloadQueue.append(uniqueTileId); _tilesMutex.unlock(); qCDebug(TerrainLog) << "Adding tile to download queue: " << uniqueTileId; } @@ -233,12 +244,13 @@ void ElevationProvider::_downloadTiles(void) QUrlQuery query; _tilesMutex.lock(); qCDebug(TerrainLog) << "Starting download for " << _downloadQueue.first(); - query.addQueryItem(QStringLiteral("points"), _downloadQueue.first()); + query.addQueryItem(QStringLiteral("points"), _downloadQueue.first().replace("_", ",")); _downloadQueue.pop_front(); _tilesMutex.unlock(); QUrl url(QStringLiteral("https://api.airmap.com/elevation/stage/srtm1/ele/carpet")); url.setQuery(query); + qWarning() << "url" << url; QNetworkRequest request(url); QNetworkProxy tProxy; @@ -253,6 +265,8 @@ void ElevationProvider::_downloadTiles(void) connect(networkReply, &QNetworkReply::finished, this, &ElevationProvider::_requestFinishedTile); _state = State::Downloading; + } else if (_state == State::Idle) { + queryTerrainData(_coordinates); } } diff --git a/src/Terrain.h b/src/Terrain.h index 14cb99f46..ede95c7e0 100644 --- a/src/Terrain.h +++ b/src/Terrain.h @@ -38,7 +38,15 @@ public: /** * Async elevation query for a list of lon,lat coordinates. When the query is done, the terrainData() signal - * is emitted. + * is emitted. This call directly looks elevations up online. + * @param coordinates + * @return true on success + */ + bool queryTerrainDataPoints(const QList& coordinates); + + /** + * Async elevation query for a list of lon,lat coordinates. When the query is done, the terrainData() signal + * is emitted. This call caches local elevation tables for faster lookup in the future. * @param coordinates * @return true on success */ @@ -80,6 +88,7 @@ private: State _state = State::Idle; QNetworkAccessManager _networkManager; + QList _coordinates; static QMutex _tilesMutex; static QHash _tiles; diff --git a/src/TerrainTile.cc b/src/TerrainTile.cc index 8baca5f44..fddc0bae3 100644 --- a/src/TerrainTile.cc +++ b/src/TerrainTile.cc @@ -141,8 +141,8 @@ float TerrainTile::elevation(const QGeoCoordinate& coordinate) const if (_isValid) { qCDebug(TerrainTileLog) << "elevation: " << coordinate << " , in sw " << _southWest << " , ne " << _northEast; // Get the index at resolution of 1 arc second - int indexLat = std::round((coordinate.latitude() - _southWest.latitude()) * gridSize / srtm1TileSize); - int indexLon = std::round((coordinate.longitude() - _southWest.longitude()) * gridSize / srtm1TileSize); + int indexLat = round((coordinate.latitude() - _southWest.latitude()) * (gridSize - 1) / srtm1TileSize); + int indexLon = round((coordinate.longitude() - _southWest.longitude()) * (gridSize - 1) / srtm1TileSize); qCDebug(TerrainTileLog) << "indexLat:indexLon" << indexLat << indexLon; // TODO (birchera): Move this down to the next debug output, once this is all properly working. Q_ASSERT(indexLat >= 0); Q_ASSERT(indexLat < gridSize); diff --git a/src/TerrainTile.h b/src/TerrainTile.h index 199578b77..4ac61de1d 100644 --- a/src/TerrainTile.h +++ b/src/TerrainTile.h @@ -5,7 +5,7 @@ #include -#define TERRAIN_TILE_SIZE 90 +#define TERRAIN_TILE_SIZE 91 Q_DECLARE_LOGGING_CATEGORY(TerrainTileLog) -- 2.22.0