File indexing completed on 2024-04-21 03:49:59
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 0003 #include "TileCoordsPyramid.h" 0004 0005 #include <QRect> 0006 #include <QVector> 0007 #include <MarbleDebug.h> 0008 0009 #include <algorithm> 0010 0011 namespace Marble 0012 { 0013 0014 class Q_DECL_HIDDEN TileCoordsPyramid::Private 0015 { 0016 public: 0017 Private( int const topLevel, int const bottomLevel ); 0018 0019 int m_topLevel; 0020 int m_bottomLevel; 0021 QRect m_bottomLevelCoords; 0022 QVector<int> m_validLevels; 0023 }; 0024 0025 TileCoordsPyramid::Private::Private( int const topLevel, int const bottomLevel ) 0026 : m_topLevel( topLevel ), 0027 m_bottomLevel( bottomLevel ) 0028 { 0029 Q_ASSERT( m_topLevel <= m_bottomLevel ); 0030 } 0031 0032 0033 TileCoordsPyramid::TileCoordsPyramid( int const topLevel, int const bottomLevel ) 0034 : d( new Private( topLevel, bottomLevel )) 0035 { 0036 } 0037 0038 TileCoordsPyramid::TileCoordsPyramid( TileCoordsPyramid const & other ) 0039 : d( new Private( *other.d )) 0040 { 0041 } 0042 0043 TileCoordsPyramid::TileCoordsPyramid() 0044 :d( new Private( 0, 0 ) ) 0045 { 0046 0047 } 0048 0049 TileCoordsPyramid & TileCoordsPyramid::operator=( TileCoordsPyramid const & rhs ) 0050 { 0051 TileCoordsPyramid temp( rhs ); 0052 swap( temp ); 0053 return *this; 0054 } 0055 0056 TileCoordsPyramid::~TileCoordsPyramid() 0057 { 0058 delete d; 0059 } 0060 0061 int TileCoordsPyramid::topLevel() const 0062 { 0063 return d->m_topLevel; 0064 } 0065 0066 int TileCoordsPyramid::bottomLevel() const 0067 { 0068 return d->m_bottomLevel; 0069 } 0070 0071 void TileCoordsPyramid::setBottomLevelCoords( QRect const & coords ) 0072 { 0073 d->m_bottomLevelCoords = coords; 0074 } 0075 0076 QRect TileCoordsPyramid::coords( int const level ) const 0077 { 0078 Q_ASSERT( d->m_topLevel <= level && level <= d->m_bottomLevel ); 0079 int bottomX1, bottomY1, bottomX2, bottomY2; 0080 d->m_bottomLevelCoords.getCoords( &bottomX1, &bottomY1, &bottomX2, &bottomY2 ); 0081 int const deltaLevel = d->m_bottomLevel - level; 0082 int const x1 = bottomX1 >> deltaLevel; 0083 int const y1 = bottomY1 >> deltaLevel; 0084 int const x2 = bottomX2 >> deltaLevel; 0085 int const y2 = bottomY2 >> deltaLevel; 0086 QRect result; 0087 result.setCoords( x1, y1, x2, y2 ); 0088 return result; 0089 } 0090 0091 void TileCoordsPyramid::setValidTileLevels(const QVector<int> validLevels) 0092 { 0093 d->m_validLevels = validLevels; 0094 } 0095 0096 QVector<int> TileCoordsPyramid::validTileLevels() 0097 { 0098 return d->m_validLevels; 0099 } 0100 0101 qint64 TileCoordsPyramid::tilesCount() const 0102 { 0103 qint64 result = 0; 0104 for ( int level = d->m_topLevel; level <= d->m_bottomLevel; ++level ) { 0105 if (!d->m_validLevels.isEmpty() && !d->m_validLevels.contains(level)) continue; 0106 0107 QRect const levelCoords = coords( level ); 0108 // w*h can exceed 32 bit range, so force 64 bit calculation; see bug 342397 0109 result += qint64( levelCoords.width() ) * levelCoords.height(); 0110 } 0111 return result; 0112 } 0113 0114 void TileCoordsPyramid::swap( TileCoordsPyramid & other ) 0115 { 0116 std::swap( d, other.d ); 0117 } 0118 0119 }