Skip to content

Commit 8f605a3

Browse files
Download tiles in a separate function (#9)
* Downloading tiles to a separate function
1 parent f200cae commit 8f605a3

File tree

2 files changed

+52
-56
lines changed

2 files changed

+52
-56
lines changed

src/OpenStreetMap-esp32.cpp

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -261,22 +261,11 @@ bool OpenStreetMap::fetchMap(LGFX_Sprite &mapSprite, double longitude, double la
261261
}
262262
}
263263

264-
// normalize the coordinates
265264
longitude = fmod(longitude + 180.0, 360.0) - 180.0;
266265
latitude = std::clamp(latitude, -90.0, 90.0);
267266

268267
tileList requiredTiles;
269268
computeRequiredTiles(longitude, latitude, zoom, requiredTiles);
270-
271-
#define SHOW_REQUIRED_TILES false
272-
#if defined(SHOW_REQUIRED_TILES) && (SHOW_REQUIRED_TILES == true)
273-
log_i("Required Tiles:");
274-
for (size_t i = 0; i < requiredTiles.size(); ++i)
275-
{
276-
log_i(" Tile [%zu]: X=%d, Y=%d", i, requiredTiles[i].first, requiredTiles[i].second);
277-
}
278-
#endif
279-
280269
if (tilesCache.capacity() < requiredTiles.size())
281270
{
282271
log_e("Caching error: Need %i cache slots, but only %i are provided", requiredTiles.size(), tilesCache.capacity());
@@ -316,104 +305,108 @@ bool OpenStreetMap::readTileDataToBuffer(WiFiClient *stream, MemoryBuffer &buffe
316305
return true;
317306
}
318307

319-
bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t zoom, String &result)
308+
std::optional<std::unique_ptr<MemoryBuffer>> OpenStreetMap::downloadTile(const String &url, String &result, size_t &size)
320309
{
321-
const uint32_t worldTileWidth = 1 << zoom;
322-
if (x >= worldTileWidth || y >= worldTileWidth)
323-
{
324-
result = "Out of range tile coordinates";
325-
return false;
326-
}
327-
328-
const String url = "https://tile.openstreetmap.org/" + String(zoom) + "/" + String(x) + "/" + String(y) + ".png";
329-
330310
HTTPClient http;
331311
http.setUserAgent("OpenStreetMap-esp32/1.0 (+https://github.com/CelliesProjects/OpenStreetMap-esp32)");
332312
if (!http.begin(url))
333313
{
334314
result = "Failed to initialize HTTP client";
335-
return false;
315+
return std::nullopt;
336316
}
337317

338318
const int httpCode = http.GET();
339319
if (httpCode != HTTP_CODE_OK)
340320
{
341321
http.end();
342-
343-
if (httpCode == HTTP_CODE_NOT_FOUND)
344-
{
345-
result = "HTTP Error 404 - not found tile " + String(x) + "," + String(y) + "," + String(zoom);
346-
return false;
347-
}
348-
349322
result = "HTTP Error: " + String(httpCode);
350-
return false;
323+
return std::nullopt;
351324
}
352325

353326
const size_t contentSize = http.getSize();
354327
if (contentSize < 1)
355328
{
356329
http.end();
357330
result = "Empty or chunked response";
358-
return false;
331+
return std::nullopt;
359332
}
360333

361334
WiFiClient *stream = http.getStreamPtr();
362335
if (!stream)
363336
{
364337
http.end();
365338
result = "Failed to get HTTP stream";
366-
return false;
339+
return std::nullopt;
367340
}
368341

369-
MemoryBuffer buffer(contentSize);
370-
if (!buffer.isAllocated())
342+
auto buffer = std::make_unique<MemoryBuffer>(contentSize);
343+
if (!buffer->isAllocated())
371344
{
372345
http.end();
373346
result = "Failed to allocate buffer";
374-
return false;
347+
return std::nullopt;
375348
}
376349

377-
if (!readTileDataToBuffer(stream, buffer, contentSize, result))
350+
if (!readTileDataToBuffer(stream, *buffer, contentSize, result))
378351
{
379352
http.end();
380-
log_e("%s", result.c_str());
381-
return false;
353+
return std::nullopt;
382354
}
383355

384356
http.end();
357+
size = contentSize;
358+
result = "Downloaded tile " + url;
359+
return buffer;
360+
}
385361

386-
const int16_t rc = png.openRAM(buffer.get(), contentSize, PNGDraw);
387-
if (rc != PNG_SUCCESS)
362+
bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t zoom, String &result)
363+
{
364+
const uint32_t worldTileWidth = 1 << zoom;
365+
if (x >= worldTileWidth || y >= worldTileWidth)
388366
{
389-
result = "PNG Decoder Error: " + String(rc);
367+
result = "Out of range tile coordinates";
390368
return false;
391369
}
392370

393-
if (png.getWidth() != OSM_TILESIZE || png.getHeight() != OSM_TILESIZE)
371+
const String url = "https://tile.openstreetmap.org/" + String(zoom) + "/" + String(x) + "/" + String(y) + ".png";
372+
394373
{
395-
result = "Unexpected tile size: w=" + String(png.getWidth()) + " h=" + String(png.getWidth());
396-
return false;
397-
}
374+
size_t contentSize;
375+
auto buffer = downloadTile(url, result, contentSize);
376+
if (!buffer)
377+
return false;
398378

399-
currentInstance = this;
400-
currentTileBuffer = tile.buffer;
401-
const int decodeResult = png.decode(0, PNG_FAST_PALETTE);
402-
currentTileBuffer = nullptr;
403-
currentInstance = nullptr;
379+
const int16_t rc = png.openRAM(buffer.value()->get(), contentSize, PNGDraw);
380+
if (rc != PNG_SUCCESS)
381+
{
382+
result = "PNG Decoder Error: " + String(rc);
383+
return false;
384+
}
404385

405-
if (decodeResult != PNG_SUCCESS)
406-
{
407-
result = "Decoding " + url + " failed with code: " + String(decodeResult);
408-
tile.valid = false;
409-
return false;
386+
if (png.getWidth() != OSM_TILESIZE || png.getHeight() != OSM_TILESIZE)
387+
{
388+
result = "Unexpected tile size: w=" + String(png.getWidth()) + " h=" + String(png.getWidth());
389+
return false;
390+
}
391+
392+
currentInstance = this;
393+
currentTileBuffer = tile.buffer;
394+
const int decodeResult = png.decode(0, PNG_FAST_PALETTE);
395+
currentTileBuffer = nullptr;
396+
currentInstance = nullptr;
397+
398+
if (decodeResult != PNG_SUCCESS)
399+
{
400+
result = "Decoding " + url + " failed with code: " + String(decodeResult);
401+
tile.valid = false;
402+
return false;
403+
}
410404
}
411405

412406
tile.x = x;
413407
tile.y = y;
414408
tile.z = zoom;
415409
tile.valid = true;
416-
417410
result = "Added: " + url;
418411
return true;
419412
}

src/OpenStreetMap-esp32.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <WiFiClient.h>
3030
#include <SD.h>
3131
#include <vector>
32+
#include <optional>
33+
#include <memory>
3234
#include <LovyanGFX.hpp>
3335
#include <PNGdec.h>
3436

@@ -67,6 +69,7 @@ class OpenStreetMap
6769
void updateCache(const tileList &requiredTiles, uint8_t zoom);
6870
bool isTileCached(uint32_t x, uint32_t y, uint8_t z);
6971
CachedTile *findUnusedTile(const tileList &requiredTiles, uint8_t zoom);
72+
std::optional<std::unique_ptr<MemoryBuffer>> downloadTile(const String &url, String &result, size_t &size);
7073
bool downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t zoom, String &result);
7174
bool readTileDataToBuffer(WiFiClient *stream, MemoryBuffer &buffer, size_t contentSize, String &result);
7275
bool composeMap(LGFX_Sprite &mapSprite, const tileList &requiredTiles, uint8_t zoom);

0 commit comments

Comments
 (0)