* @brief Renders a scaled ancestor tile when the target tile is not yet cached. */
| 672 | * @brief Renders a scaled ancestor tile when the target tile is not yet cached. |
| 673 | */ |
| 674 | bool Widgets::GPS::renderFallbackTile( |
| 675 | QPainter* painter, int tx, int ty, int baseZoom, const QRect& targetRect, double scaledTileSize) |
| 676 | { |
| 677 | const int tileSize = 256; |
| 678 | for (int z = baseZoom - 1; z >= MIN_ZOOM; --z) { |
| 679 | const int dz = baseZoom - z; |
| 680 | const int tileScale = 1 << dz; |
| 681 | const int parentTx = tx >> dz; |
| 682 | const int parentTy = ty >> dz; |
| 683 | const int wrappedParentTx = (parentTx % (1 << z) + (1 << z)) % (1 << z); |
| 684 | const QString parentUrl = tileUrl(wrappedParentTx, parentTy, z); |
| 685 | |
| 686 | if (!s_tileCache.contains(parentUrl)) |
| 687 | continue; |
| 688 | |
| 689 | auto* src = s_tileCache.object(parentUrl); |
| 690 | const QRect sourceRect((tx % tileScale) * (tileSize / tileScale), |
| 691 | (ty % tileScale) * (tileSize / tileScale), |
| 692 | tileSize / tileScale, |
| 693 | tileSize / tileScale); |
| 694 | |
| 695 | const auto cropped = src->copy(sourceRect); |
| 696 | const int roundedSize = qRound(scaledTileSize); |
| 697 | |
| 698 | QImage finalTile; |
| 699 | if (qAbs(baseZoom - z) > 5) { |
| 700 | QImage img = cropped.scaled(1, 1, Qt::IgnoreAspectRatio, Qt::FastTransformation); |
| 701 | finalTile = QImage(roundedSize, roundedSize, QImage::Format_ARGB32); |
| 702 | finalTile.fill(img.pixelColor(0, 0)); |
| 703 | } else { |
| 704 | finalTile = |
| 705 | cropped.scaled(roundedSize, roundedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); |
| 706 | } |
| 707 | |
| 708 | painter->drawImage(targetRect, finalTile); |
| 709 | return true; |
| 710 | } |
| 711 | |
| 712 | return false; |
| 713 | } |
| 714 | |
| 715 | /** |
| 716 | * @brief Draws the NASA GIBS weather overlay tile if available in the cache. |