File indexing completed on 2024-04-21 03:49:56

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2007-2010 Torsten Rahn <tackat@kde.org>
0004 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
0005 // SPDX-FileCopyrightText: 2010 Jens-Michael Hoffmann <jensmh@gmx.de>
0006 // SPDX-FileCopyrightText: 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0007 //
0008 
0009 #ifndef MARBLE_STACKEDTILE_H
0010 #define MARBLE_STACKEDTILE_H
0011 
0012 #include <QSharedPointer>
0013 #include <QVector>
0014 #include <QImage>
0015 
0016 #include "Tile.h"
0017 
0018 namespace Marble
0019 {
0020 
0021 class TextureTile;
0022 
0023 /*!
0024     \class StackedTile
0025     \brief A single tile that consists of a stack of Tile layers.
0026 
0027     The StackedTile is a tile container that covers a certain area and is used 
0028     for a particular zoom level. It consists of a <b>stack of several
0029     individual thematic Tiles</b> that cover the very same area and
0030     are used for the very same zoom level: This stack of Tiles is
0031     built up from the ground: The first Tile at the bottom usually
0032     represents the ground surface. Optionally there might be a range of other
0033     Tiles stacked on top which cover e.g. relief, streets and clouds.
0034     
0035     For rendering the whole stack of tiles gets merged and blended into a 
0036     single QImage. This merging/blending operation is usually only performed 
0037     once the stack of tiles changes visually. As a result access to the visual 
0038     composition of all TextureTile layers is very fast since it is reduced to 
0039     a single QImage that also consumes very little memory.
0040 
0041     The whole mechanism is comparable to layers in applications like
0042     Gimp or Photoshop (TM) which can be blended on top of each other via 
0043     so called filters and can be merged into a single layer if required.
0044 
0045     Restrictions: The Tiles that are part of the stack need to be of
0046     the same size and need to cover the same area at the same zoom level using 
0047     the very same projection.
0048 */
0049 
0050 class StackedTile : public Tile
0051 {
0052  public:
0053     explicit StackedTile( TileId const &id, QImage const &resultImage, QVector<QSharedPointer<TextureTile> > const &tiles );
0054     ~StackedTile() override;
0055 
0056     void setUsed( bool used );
0057     bool used() const;
0058 
0059     int depth() const;
0060     int byteCount() const;
0061 
0062 /*!
0063     \brief Returns the stack of Tiles
0064     \return A container of Tile objects.
0065 */
0066     QVector<QSharedPointer<TextureTile> > tiles() const;
0067 
0068 /*!
0069     \brief Returns the QImage that describes the merged stack of Tiles
0070     \return A non-zero pointer to the resulting QImage 
0071 */
0072     QImage const * resultImage() const;
0073 
0074 /*!
0075     \brief Returns the color value of the result tile at the given integer position.
0076     \return The uint that describes the color value of the given pixel 
0077     
0078     Note: for gray scale images the color value of a single pixel is described
0079     via a uchar (1 byte) while for RGB(A) images uint (4 bytes) are used.
0080 */
0081     uint pixel( int x, int y ) const;
0082     
0083 /*!
0084     \brief Returns the color value of the result tile at a given floating point position.
0085     \return The uint that describes the color value of the given pixel 
0086     
0087     Subpixel calculation is done via bilinear interpolation.
0088     
0089     Note: for gray scale images the color value of a single pixel is described
0090     via a uchar (1 byte) while for RGB(A) images uint (4 bytes) are used.
0091 */    
0092     uint pixelF( qreal x, qreal y ) const;
0093     // This method passes the top left pixel (if known already) for better performance
0094     uint pixelF( qreal x, qreal y, const QRgb& pixel ) const;
0095 
0096  private:
0097     Q_DISABLE_COPY( StackedTile )
0098 
0099     const QImage m_resultImage;
0100     const int m_depth;
0101     const bool m_isGrayscale;
0102     const QVector<QSharedPointer<TextureTile> > m_tiles;
0103     const uchar **const jumpTable8;
0104     const uint **const jumpTable32;
0105     const int m_byteCount;
0106     bool m_isUsed;
0107 
0108     static int calcByteCount( const QImage &resultImage, const QVector<QSharedPointer<TextureTile> > &tiles );
0109 };
0110 
0111 }
0112 
0113 #endif