File indexing completed on 2025-01-05 03:59:37

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