Skip to content

Commit 6398a9a

Browse files
authored
Merge pull request #418 from Wulkop/feature/lod-bodies-skip-white-tiles
Feature/lod bodies skip white tiles
2 parents 9375a37 + 06cf525 commit 6398a9a

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

plugins/csp-lod-bodies/src/TileSourceWebMapService.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,26 @@ bool loadImpl(TileSourceWebMapService* source, BaseTileData* tile, TileId const&
136136
return false;
137137
}
138138

139+
bool isCompletelyWhiteTile = true;
140+
// Iterate through pixel values and stop after one non-white pixel in tile
141+
for (int i = 0; i < width * height; ++i) {
142+
auto pixel = reinterpret_cast<uint8_t*>(data) + i * 4;
143+
if (pixel[0] != 255 || pixel[1] != 255 || pixel[2] != 255 || pixel[3] != 255) {
144+
isCompletelyWhiteTile = false;
145+
break;
146+
}
147+
}
148+
if (isCompletelyWhiteTile) {
149+
logger().debug(
150+
"Failed to parse tile data: File '{}' is completely white and most likely corrupt.",
151+
*cacheFile);
152+
source->markTileDataAsInvalid(*cacheFile);
153+
if (boost::filesystem::remove(*cacheFile) == 0) {
154+
logger().debug("Failed to remove tile data: File '{}'", *cacheFile);
155+
}
156+
return false;
157+
}
158+
139159
// The image data can be read. For some patches (those at the international date boundary)
140160
// two requests are made. For those, only half of the pixels contain valid data (above or below
141161
// the diagonal).
@@ -392,6 +412,20 @@ std::optional<std::string> TileSourceWebMapService::loadData(TileId const& tileI
392412
"Failed to download tile data: Cannot open '{}' for writing!", cacheFile.str()));
393413
}
394414

415+
// Check if we already had an error with this tile cache file in the past
416+
if (mLastTimeTileFailed.find(cacheFilePath) != mLastTimeTileFailed.end()) {
417+
auto cooldownTime = std::chrono::seconds(3);
418+
auto timeNow = std::chrono::system_clock::now();
419+
if (timeNow - mLastTimeTileFailed[cacheFilePath] < cooldownTime) {
420+
logger().warn(
421+
"Failed to download tile data: Waiting for '{}' to cool down", cacheFile.str());
422+
// Sleep for the rest of the cooldown time (plus a little longer 500ms)
423+
std::this_thread::sleep_until(
424+
mLastTimeTileFailed[cacheFilePath] + cooldownTime + std::chrono::milliseconds(500));
425+
}
426+
mLastTimeTileFailed.erase(cacheFilePath);
427+
}
428+
395429
curlpp::Easy request;
396430
request.setOpt(curlpp::options::Url(url.str()));
397431
request.setOpt(curlpp::options::WriteStream(&out));
@@ -495,4 +529,10 @@ bool TileSourceWebMapService::isSame(TileSource const* other) const {
495529

496530
////////////////////////////////////////////////////////////////////////////////////////////////////
497531

532+
void TileSourceWebMapService::markTileDataAsInvalid(boost::filesystem::path const& TileDataPath) {
533+
mLastTimeTileFailed[TileDataPath] = std::chrono::system_clock::now();
534+
}
535+
536+
////////////////////////////////////////////////////////////////////////////////////////////////////
537+
498538
} // namespace csp::lodbodies

plugins/csp-lod-bodies/src/TileSourceWebMapService.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "TileData.hpp"
1313
#include "TileSource.hpp"
1414

15+
#include <chrono>
1516
#include <cstdio>
1617
#include <optional>
1718
#include <string>
@@ -70,6 +71,12 @@ class TileSourceWebMapService : public TileSource {
7071
// writable) a std::runtime_error is thrown.
7172
std::optional<std::string> loadData(TileId const& tileId, int x, int y);
7273

74+
// This will mark a previously downloaded tile file as invalid together with the current
75+
// timestamp. This information is used to avoid quering the same tile immediately after we've
76+
// received invalid data from server Tracking the time of the last error allows us to apply a kind
77+
// of cooldown mechanism
78+
void markTileDataAsInvalid(boost::filesystem::path const& TileDataPath);
79+
7380
private:
7481
static std::mutex mFileSystemMutex;
7582

@@ -79,6 +86,10 @@ class TileSourceWebMapService : public TileSource {
7986
std::string mLayers;
8087
TileDataType mFormat = TileDataType::eColor;
8188
uint32_t mResolution;
89+
90+
// We keep track of the time a tile has had invalid data from the server.
91+
// This timestamp is used for a cooldown mechanism
92+
std::map<boost::filesystem::path, std::chrono::system_clock::time_point> mLastTimeTileFailed;
8293
};
8394
} // namespace csp::lodbodies
8495

0 commit comments

Comments
 (0)