@@ -87,26 +87,26 @@ void OpenStreetMap::computeRequiredTiles(double longitude, double latitude, uint
8787    const  int32_t  targetTileY = static_cast <int32_t >(exactTileY);
8888
8989    //  Compute the offset inside the tile for the given coordinates
90-     const  int16_t  targetOffsetX = (exactTileX - targetTileX) * OSM_TILESIZE ;
91-     const  int16_t  targetOffsetY = (exactTileY - targetTileY) * OSM_TILESIZE ;
90+     const  int16_t  targetOffsetX = (exactTileX - targetTileX) * currentProvider-> tileSize ;
91+     const  int16_t  targetOffsetY = (exactTileY - targetTileY) * currentProvider-> tileSize ;
9292
9393    //  Compute the offset for tiles covering the map area to keep the location centered
9494    const  int16_t  tilesOffsetX = mapWidth / 2  - targetOffsetX;
9595    const  int16_t  tilesOffsetY = mapHeight / 2  - targetOffsetY;
9696
9797    //  Compute number of colums required
98-     const  float  colsLeft = 1.0  * tilesOffsetX / OSM_TILESIZE ;
99-     const  float  colsRight = float (mapWidth - (tilesOffsetX + OSM_TILESIZE )) / OSM_TILESIZE ;
98+     const  float  colsLeft = 1.0  * tilesOffsetX / currentProvider-> tileSize ;
99+     const  float  colsRight = float (mapWidth - (tilesOffsetX + currentProvider-> tileSize )) / currentProvider-> tileSize ;
100100    numberOfColums = ceil (colsLeft) + 1  + ceil (colsRight);
101101
102-     startOffsetX = tilesOffsetX - (ceil (colsLeft) * OSM_TILESIZE );
102+     startOffsetX = tilesOffsetX - (ceil (colsLeft) * currentProvider-> tileSize );
103103
104104    //  Compute number of rows required
105-     const  float  rowsTop = 1.0  * tilesOffsetY / OSM_TILESIZE ;
106-     const  float  rowsBottom = float (mapHeight - (tilesOffsetY + OSM_TILESIZE )) / OSM_TILESIZE ;
105+     const  float  rowsTop = 1.0  * tilesOffsetY / currentProvider-> tileSize ;
106+     const  float  rowsBottom = float (mapHeight - (tilesOffsetY + currentProvider-> tileSize )) / currentProvider-> tileSize ;
107107    const  uint32_t  numberOfRows = ceil (rowsTop) + 1  + ceil (rowsBottom);
108108
109-     startOffsetY = tilesOffsetY - (ceil (rowsTop) * OSM_TILESIZE );
109+     startOffsetY = tilesOffsetY - (ceil (rowsTop) * currentProvider-> tileSize );
110110
111111    log_v ("  Need %i * %i tiles. First tile offset is %d,%d" 
112112          numberOfColums, numberOfRows, startOffsetX, startOffsetY);
@@ -171,17 +171,11 @@ bool OpenStreetMap::isTileCachedOrBusy(uint32_t x, uint32_t y, uint8_t z)
171171
172172void  OpenStreetMap::freeTilesCache ()
173173{
174-     for  (auto  &tile : tilesCache)
175-         tile.free ();
176- 
177-     tilesCache.clear ();
174+     std::vector<CachedTile>().swap (tilesCache);
178175}
179176
180177bool  OpenStreetMap::resizeTilesCache (uint16_t  numberOfTiles)
181178{
182-     if  (tilesCache.size () == numberOfTiles)
183-         return  true ;
184- 
185179    if  (!numberOfTiles)
186180    {
187181        log_e (" Invalid cache size: %d" 
@@ -193,7 +187,7 @@ bool OpenStreetMap::resizeTilesCache(uint16_t numberOfTiles)
193187
194188    for  (auto  &tile : tilesCache)
195189    {
196-         if  (!tile.allocate ())
190+         if  (!tile.allocate (currentProvider-> tileSize ))
197191        {
198192            log_e (" Tile cache allocation failed!" 
199193            freeTilesCache ();
@@ -211,7 +205,7 @@ void OpenStreetMap::updateCache(const tileList &requiredTiles, uint8_t zoom)
211205    if  (!jobs.empty ())
212206    {
213207        runJobs (jobs);
214-         log_i (" Updated %i tiles in %lu ms - %i ms/tile" size (), millis () - startMS, (millis () - startMS) / jobs.size ());
208+         log_d (" Updated %i tiles in %lu ms - %i ms/tile" size (), millis () - startMS, (millis () - startMS) / jobs.size ());
215209    }
216210}
217211
@@ -270,8 +264,8 @@ bool OpenStreetMap::composeMap(LGFX_Sprite &mapSprite, const tileList &requiredT
270264            continue ;
271265        }
272266
273-         int  drawX = startOffsetX + (tileIndex % numberOfColums) * OSM_TILESIZE ;
274-         int  drawY = startOffsetY + (tileIndex / numberOfColums) * OSM_TILESIZE ;
267+         int  drawX = startOffsetX + (tileIndex % numberOfColums) * currentProvider-> tileSize ;
268+         int  drawY = startOffsetY + (tileIndex / numberOfColums) * currentProvider-> tileSize ;
275269
276270        auto  it = std::find_if (tilesCache.begin (), tilesCache.end (),
277271                               [&](const  CachedTile &tile)
@@ -280,7 +274,7 @@ bool OpenStreetMap::composeMap(LGFX_Sprite &mapSprite, const tileList &requiredT
280274                               });
281275
282276        if  (it != tilesCache.end ())
283-             mapSprite.pushImage (drawX, drawY, OSM_TILESIZE, OSM_TILESIZE , it->buffer );
277+             mapSprite.pushImage (drawX, drawY, currentProvider-> tileSize , currentProvider-> tileSize , it->buffer );
284278        else 
285279            log_w (" Tile (z=%d, x=%d, y=%d) not found in cache" 
286280
@@ -293,8 +287,8 @@ bool OpenStreetMap::composeMap(LGFX_Sprite &mapSprite, const tileList &requiredT
293287        mapSprite.setTextColor (TFT_WHITE, TFT_BLACK);
294288    else 
295289        mapSprite.setTextColor (TFT_BLACK);
296-     mapSprite.drawRightString ("  Map data from OpenStreetMap.org  " 
297-                               mapSprite.width (), mapSprite.height () - 10 , &DejaVu9 );
290+     mapSprite.drawRightString (currentProvider-> attribution ,
291+                               mapSprite.width (), mapSprite.height () - 10 , &DejaVu9Modded );
298292    mapSprite.setTextColor (TFT_WHITE, TFT_BLACK);
299293
300294    return  true ;
@@ -308,7 +302,7 @@ bool OpenStreetMap::fetchMap(LGFX_Sprite &mapSprite, double longitude, double la
308302        return  false ;
309303    }
310304
311-     if  (! zoom || zoom > OSM_MAX_ZOOM )
305+     if  (zoom < currentProvider-> minZoom   || zoom > currentProvider-> maxZoom )
312306    {
313307        log_e (" Invalid zoom level: %d" 
314308        return  false ;
@@ -320,14 +314,10 @@ bool OpenStreetMap::fetchMap(LGFX_Sprite &mapSprite, double longitude, double la
320314        return  false ;
321315    }
322316
323-     if  (!tilesCache.capacity ())
317+     if  (!tilesCache.capacity () && ! resizeTilesCache ( tilesNeeded (mapWidth, mapHeight)) )
324318    {
325-         log_w (" Cache not initialized, setting up a default cache..." 
326-         if  (!resizeTilesCache (OSM_DEFAULT_CACHE_ITEMS))
327-         {
328-             log_e (" Could not allocate tile cache" 
329-             return  false ;
330-         }
319+         log_e (" Could not allocate tile cache" 
320+         return  false ;
331321    }
332322
333323    longitude = fmod (longitude + 180.0 , 360.0 ) - 180.0 ;
@@ -366,7 +356,7 @@ bool OpenStreetMap::fillBuffer(WiFiClient *stream, MemoryBuffer &buffer, size_t
366356                result = " Timeout: " String (OSM_TILE_TIMEOUT_MS) + "  ms" 
367357                return  false ;
368358            }
369-             vTaskDelay ( pdMS_TO_TICKS ( 1 ) );
359+             taskYIELD ( );
370360            continue ;
371361        }
372362
@@ -382,7 +372,7 @@ bool OpenStreetMap::fillBuffer(WiFiClient *stream, MemoryBuffer &buffer, size_t
382372            lastReadTime = millis ();
383373        }
384374        else 
385-             vTaskDelay ( pdMS_TO_TICKS ( 1 ) );
375+             taskYIELD ( );
386376    }
387377    return  true ;
388378}
@@ -432,22 +422,25 @@ std::optional<std::unique_ptr<MemoryBuffer>> OpenStreetMap::urlToBuffer(const ch
432422
433423void  OpenStreetMap::PNGDraw (PNGDRAW *pDraw)
434424{
435-     uint16_t  *destRow = currentInstance->currentTileBuffer  + (pDraw->y  * OSM_TILESIZE );
425+     uint16_t  *destRow = currentInstance->currentTileBuffer  + (pDraw->y  * currentInstance-> currentProvider -> tileSize );
436426    getPNGCurrentCore ()->getLineAsRGB565 (pDraw, destRow, PNG_RGB565_BIG_ENDIAN, 0xffffffff );
437427}
438428
439429bool  OpenStreetMap::fetchTile (CachedTile &tile, uint32_t  x, uint32_t  y, uint8_t  zoom, String &result)
440430{
441-     char  url[64 ];
442-     snprintf (url, sizeof (url), " https://tile.openstreetmap.org/%u/%u/%u.png" 
443-              static_cast <unsigned  int >(zoom),
444-              static_cast <unsigned  int >(x),
445-              static_cast <unsigned  int >(y));
446- 
447-     const  auto  buffer = urlToBuffer (url, result);
431+     String url = currentProvider->urlTemplate ;
432+     url.replace (" {x}" String (x));
433+     url.replace (" {y}" String (y));
434+     url.replace (" {z}" String (zoom));
435+     if  (currentProvider->requiresApiKey  && strstr (url.c_str (), " {apiKey}" 
436+         url.replace (" {apiKey}" apiKey );
437+ 
438+     const  auto  buffer = urlToBuffer (url.c_str (), result);
448439    if  (!buffer)
449440        return  false ;
450441
442+     url.clear ();
443+ 
451444    PNG *png = getPNGCurrentCore ();
452445    const  int16_t  rc = png->openRAM (buffer.value ()->get (), buffer.value ()->size (), PNGDraw);
453446    if  (rc != PNG_SUCCESS)
@@ -456,7 +449,7 @@ bool OpenStreetMap::fetchTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t
456449        return  false ;
457450    }
458451
459-     if  (png->getWidth () != OSM_TILESIZE  || png->getHeight () != OSM_TILESIZE )
452+     if  (png->getWidth () != currentProvider-> tileSize  || png->getHeight () != currentProvider-> tileSize )
460453    {
461454        result = " Unexpected tile size: w=" String (png->getWidth ()) + "  h=" String (png->getHeight ());
462455        return  false ;
@@ -468,7 +461,7 @@ bool OpenStreetMap::fetchTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t
468461    const  int  decodeResult = png->decode (0 , PNG_FAST_PALETTE);
469462    if  (decodeResult != PNG_SUCCESS)
470463    {
471-         result = " Decoding " String ( url)  + "  failed with code: " String (decodeResult);
464+         result = " Decoding " "  failed with code: " String (decodeResult);
472465        tile.valid  = false ;
473466        return  false ;
474467    }
@@ -550,3 +543,25 @@ bool OpenStreetMap::startTileWorkerTasks()
550543    log_i (" Started %d tile worker task(s)" 
551544    return  true ;
552545}
546+ 
547+ uint16_t  OpenStreetMap::tilesNeeded (uint16_t  mapWidth, uint16_t  mapHeight)
548+ {
549+     const  int  tileSize = currentProvider->tileSize ;
550+     int  tilesX = (mapWidth + tileSize - 1 ) / tileSize + 1 ;
551+     int  tilesY = (mapHeight + tileSize - 1 ) / tileSize + 1 ;
552+     return  tilesX * tilesY;
553+ }
554+ 
555+ bool  OpenStreetMap::setTileProvider (int  index)
556+ {
557+     if  (index < 0  || index >= OSM_TILEPROVIDERS)
558+     {
559+         log_e (" invalid provider index" 
560+         return  false ;
561+     }
562+ 
563+     currentProvider = &tileProviders[index];
564+     freeTilesCache ();
565+     log_i (" provider changed to '%s'" name );
566+     return  true ;
567+ }
0 commit comments