From c11dafb91567fa823c853c3738ac916973238b41 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 22:33:20 +0100 Subject: [PATCH 1/7] Downloading tiles to a separate function --- src/OpenStreetMap-esp32.cpp | 55 ++++++++++++++++++++++--------------- src/OpenStreetMap-esp32.h | 4 ++- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index 4cb6d31..317f418 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -316,23 +316,14 @@ bool OpenStreetMap::readTileDataToBuffer(WiFiClient *stream, MemoryBuffer &buffe return true; } -bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t zoom, String &result) +std::optional> OpenStreetMap::downloadTile(const String &url, String &result, size_t &size) { - const uint32_t worldTileWidth = 1 << zoom; - if (x >= worldTileWidth || y >= worldTileWidth) - { - result = "Out of range tile coordinates"; - return false; - } - - const String url = "https://tile.openstreetmap.org/" + String(zoom) + "/" + String(x) + "/" + String(y) + ".png"; - HTTPClient http; http.setUserAgent("OpenStreetMap-esp32/1.0 (+https://github.com/CelliesProjects/OpenStreetMap-esp32)"); if (!http.begin(url)) { result = "Failed to initialize HTTP client"; - return false; + return std::nullopt; } const int httpCode = http.GET(); @@ -342,12 +333,12 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t if (httpCode == HTTP_CODE_NOT_FOUND) { - result = "HTTP Error 404 - not found tile " + String(x) + "," + String(y) + "," + String(zoom); - return false; + result = "HTTP Error 404 - not found " + url; + return std::nullopt; } result = "HTTP Error: " + String(httpCode); - return false; + return std::nullopt; } const size_t contentSize = http.getSize(); @@ -355,7 +346,7 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t { http.end(); result = "Empty or chunked response"; - return false; + return std::nullopt; } WiFiClient *stream = http.getStreamPtr(); @@ -363,27 +354,47 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t { http.end(); result = "Failed to get HTTP stream"; - return false; + return std::nullopt; } - MemoryBuffer buffer(contentSize); - if (!buffer.isAllocated()) + auto buffer = std::make_unique(contentSize); + if (!buffer->isAllocated()) { http.end(); result = "Failed to allocate buffer"; - return false; + return std::nullopt; } - if (!readTileDataToBuffer(stream, buffer, contentSize, result)) + if (!readTileDataToBuffer(stream, *buffer, contentSize, result)) { http.end(); log_e("%s", result.c_str()); - return false; + return std::nullopt; } http.end(); + size = contentSize; + result = "Downloaded tile " + url; + return buffer; +} + +bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t zoom, String &result) +{ + const uint32_t worldTileWidth = 1 << zoom; + if (x >= worldTileWidth || y >= worldTileWidth) + { + result = "Out of range tile coordinates"; + return false; + } + + const String url = "https://tile.openstreetmap.org/" + String(zoom) + "/" + String(x) + "/" + String(y) + ".png"; + size_t contentSize; + + auto buffer = downloadTile(url, result, contentSize); + if (!buffer) + return false; - const int16_t rc = png.openRAM(buffer.get(), contentSize, PNGDraw); + const int16_t rc = png.openRAM(buffer.value()->get(), contentSize, PNGDraw); if (rc != PNG_SUCCESS) { result = "PNG Decoder Error: " + String(rc); diff --git a/src/OpenStreetMap-esp32.h b/src/OpenStreetMap-esp32.h index 988a15a..00f94aa 100644 --- a/src/OpenStreetMap-esp32.h +++ b/src/OpenStreetMap-esp32.h @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include @@ -72,7 +74,7 @@ class OpenStreetMap bool composeMap(LGFX_Sprite &mapSprite, const tileList &requiredTiles, uint8_t zoom); bool writeHeader(const LGFX_Sprite &map, File &file); bool writeMap(LGFX_Sprite &map, File &file, MemoryBuffer &buffer); - + std::optional> downloadTile(const String &url, String &result, size_t &size); std::vector tilesCache; uint16_t *currentTileBuffer = nullptr; PNG png; From 096e0a6814f30f7f195db108102caf23502c927e Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 23:02:42 +0100 Subject: [PATCH 2/7] Limit the scope of buffer --- src/OpenStreetMap-esp32.cpp | 50 +++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index 317f418..f054070 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -390,34 +390,36 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t const String url = "https://tile.openstreetmap.org/" + String(zoom) + "/" + String(x) + "/" + String(y) + ".png"; size_t contentSize; - auto buffer = downloadTile(url, result, contentSize); - if (!buffer) - return false; - - const int16_t rc = png.openRAM(buffer.value()->get(), contentSize, PNGDraw); - if (rc != PNG_SUCCESS) { - result = "PNG Decoder Error: " + String(rc); - return false; - } + auto buffer = downloadTile(url, result, contentSize); + if (!buffer) + return false; - if (png.getWidth() != OSM_TILESIZE || png.getHeight() != OSM_TILESIZE) - { - result = "Unexpected tile size: w=" + String(png.getWidth()) + " h=" + String(png.getWidth()); - return false; - } + const int16_t rc = png.openRAM(buffer.value()->get(), contentSize, PNGDraw); + if (rc != PNG_SUCCESS) + { + result = "PNG Decoder Error: " + String(rc); + return false; + } - currentInstance = this; - currentTileBuffer = tile.buffer; - const int decodeResult = png.decode(0, PNG_FAST_PALETTE); - currentTileBuffer = nullptr; - currentInstance = nullptr; + if (png.getWidth() != OSM_TILESIZE || png.getHeight() != OSM_TILESIZE) + { + result = "Unexpected tile size: w=" + String(png.getWidth()) + " h=" + String(png.getWidth()); + return false; + } - if (decodeResult != PNG_SUCCESS) - { - result = "Decoding " + url + " failed with code: " + String(decodeResult); - tile.valid = false; - return false; + currentInstance = this; + currentTileBuffer = tile.buffer; + const int decodeResult = png.decode(0, PNG_FAST_PALETTE); + currentTileBuffer = nullptr; + currentInstance = nullptr; + + if (decodeResult != PNG_SUCCESS) + { + result = "Decoding " + url + " failed with code: " + String(decodeResult); + tile.valid = false; + return false; + } } tile.x = x; From fb9df2b801b15612a0fa5c58f1b9458bee0fe632 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 23:06:30 +0100 Subject: [PATCH 3/7] Clean up error reporting --- src/OpenStreetMap-esp32.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index f054070..2ea7c64 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -330,13 +330,6 @@ std::optional> OpenStreetMap::downloadTile(const S if (httpCode != HTTP_CODE_OK) { http.end(); - - if (httpCode == HTTP_CODE_NOT_FOUND) - { - result = "HTTP Error 404 - not found " + url; - return std::nullopt; - } - result = "HTTP Error: " + String(httpCode); return std::nullopt; } From ce945b2ddf9771fee50ad5592d42e50e93624f25 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 23:08:56 +0100 Subject: [PATCH 4/7] Limit scope of contentSize --- src/OpenStreetMap-esp32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index 2ea7c64..5e55f84 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -381,9 +381,9 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t } const String url = "https://tile.openstreetmap.org/" + String(zoom) + "/" + String(x) + "/" + String(y) + ".png"; - size_t contentSize; { + size_t contentSize; auto buffer = downloadTile(url, result, contentSize); if (!buffer) return false; From 87f6bdeeba59142b0fc2124b2551a913b2b6e08e Mon Sep 17 00:00:00 2001 From: Cellie Date: Sun, 23 Mar 2025 00:02:14 +0100 Subject: [PATCH 5/7] Cleanup --- src/OpenStreetMap-esp32.cpp | 1 - src/OpenStreetMap-esp32.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index 5e55f84..ea8f1bb 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -419,7 +419,6 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t tile.y = y; tile.z = zoom; tile.valid = true; - result = "Added: " + url; return true; } diff --git a/src/OpenStreetMap-esp32.h b/src/OpenStreetMap-esp32.h index 00f94aa..094107c 100644 --- a/src/OpenStreetMap-esp32.h +++ b/src/OpenStreetMap-esp32.h @@ -75,6 +75,7 @@ class OpenStreetMap bool writeHeader(const LGFX_Sprite &map, File &file); bool writeMap(LGFX_Sprite &map, File &file, MemoryBuffer &buffer); std::optional> downloadTile(const String &url, String &result, size_t &size); + std::vector tilesCache; uint16_t *currentTileBuffer = nullptr; PNG png; From 6fe2e5dfae108098fcce6b031d1f1013d18185e9 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sun, 23 Mar 2025 00:17:45 +0100 Subject: [PATCH 6/7] Cleanup --- src/OpenStreetMap-esp32.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index ea8f1bb..1a6e502 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -261,22 +261,11 @@ bool OpenStreetMap::fetchMap(LGFX_Sprite &mapSprite, double longitude, double la } } - // normalize the coordinates longitude = fmod(longitude + 180.0, 360.0) - 180.0; latitude = std::clamp(latitude, -90.0, 90.0); tileList requiredTiles; computeRequiredTiles(longitude, latitude, zoom, requiredTiles); - -#define SHOW_REQUIRED_TILES false -#if defined(SHOW_REQUIRED_TILES) && (SHOW_REQUIRED_TILES == true) - log_i("Required Tiles:"); - for (size_t i = 0; i < requiredTiles.size(); ++i) - { - log_i(" Tile [%zu]: X=%d, Y=%d", i, requiredTiles[i].first, requiredTiles[i].second); - } -#endif - if (tilesCache.capacity() < requiredTiles.size()) { log_e("Caching error: Need %i cache slots, but only %i are provided", requiredTiles.size(), tilesCache.capacity()); @@ -361,7 +350,6 @@ std::optional> OpenStreetMap::downloadTile(const S if (!readTileDataToBuffer(stream, *buffer, contentSize, result)) { http.end(); - log_e("%s", result.c_str()); return std::nullopt; } From 61a2cfe901629bad7c5fc00dbf4a82d712b3554e Mon Sep 17 00:00:00 2001 From: Cellie Date: Sun, 23 Mar 2025 00:29:18 +0100 Subject: [PATCH 7/7] Cleanup --- src/OpenStreetMap-esp32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenStreetMap-esp32.h b/src/OpenStreetMap-esp32.h index 094107c..a4c3e86 100644 --- a/src/OpenStreetMap-esp32.h +++ b/src/OpenStreetMap-esp32.h @@ -69,12 +69,12 @@ class OpenStreetMap void updateCache(const tileList &requiredTiles, uint8_t zoom); bool isTileCached(uint32_t x, uint32_t y, uint8_t z); CachedTile *findUnusedTile(const tileList &requiredTiles, uint8_t zoom); + std::optional> downloadTile(const String &url, String &result, size_t &size); bool downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t zoom, String &result); bool readTileDataToBuffer(WiFiClient *stream, MemoryBuffer &buffer, size_t contentSize, String &result); bool composeMap(LGFX_Sprite &mapSprite, const tileList &requiredTiles, uint8_t zoom); bool writeHeader(const LGFX_Sprite &map, File &file); bool writeMap(LGFX_Sprite &map, File &file, MemoryBuffer &buffer); - std::optional> downloadTile(const String &url, String &result, size_t &size); std::vector tilesCache; uint16_t *currentTileBuffer = nullptr;