• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • marble
TileScalingTextureMapper.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
9 //
10 
11 
12 // local
13 #include "TileScalingTextureMapper.h"
14 
15 // posix
16 #include <cmath>
17 
18 // Qt
19 #include <qmath.h>
20 #include <QImage>
21 
22 // Marble
23 #include "GeoPainter.h"
24 #include "ScanlineTextureMapperContext.h"
25 #include "StackedTileLoader.h"
26 #include "TextureColorizer.h"
27 #include "TileLoaderHelper.h"
28 #include "StackedTile.h"
29 #include "MathHelper.h"
30 #include "ViewportParams.h"
31 
32 using namespace Marble;
33 
34 TileScalingTextureMapper::TileScalingTextureMapper( StackedTileLoader *tileLoader, QObject *parent )
35  : QObject( parent ),
36  TextureMapperInterface(),
37  m_tileLoader( tileLoader ),
38  m_cache( 100 ),
39  m_radius( 0 )
40 {
41  connect( tileLoader, SIGNAL(tileLoaded(TileId)),
42  this, SLOT(removePixmap(TileId)) );
43  connect( tileLoader, SIGNAL(cleared()),
44  this, SLOT(clearPixmaps()) );
45 }
46 
47 void TileScalingTextureMapper::mapTexture( GeoPainter *painter,
48  const ViewportParams *viewport,
49  int tileZoomLevel,
50  const QRect &dirtyRect,
51  TextureColorizer *texColorizer )
52 {
53  if ( viewport->radius() <= 0 )
54  return;
55 
56  if ( texColorizer || m_radius != viewport->radius() ) {
57  if ( m_canvasImage.size() != viewport->size() || m_radius != viewport->radius() ) {
58  const QImage::Format optimalFormat = ScanlineTextureMapperContext::optimalCanvasImageFormat( viewport );
59 
60  if ( m_canvasImage.size() != viewport->size() || m_canvasImage.format() != optimalFormat ) {
61  m_canvasImage = QImage( viewport->size(), optimalFormat );
62  }
63 
64  if ( !viewport->mapCoversViewport() ) {
65  m_canvasImage.fill( 0 );
66  }
67 
68  m_repaintNeeded = true;
69  }
70 
71  if ( m_repaintNeeded ) {
72  mapTexture( painter, viewport, tileZoomLevel, texColorizer );
73 
74  m_radius = viewport->radius();
75  m_repaintNeeded = false;
76  }
77 
78  painter->drawImage( dirtyRect, m_canvasImage, dirtyRect );
79  } else {
80  mapTexture( painter, viewport, tileZoomLevel, texColorizer );
81 
82  m_radius = viewport->radius();
83  }
84 }
85 
86 void TileScalingTextureMapper::mapTexture( GeoPainter *painter, const ViewportParams *viewport, int tileZoomLevel, TextureColorizer *texColorizer )
87 {
88  const int imageHeight = viewport->height();
89  const int imageWidth = viewport->width();
90  const qint64 radius = viewport->radius();
91 
92  const bool highQuality = ( painter->mapQuality() == HighQuality
93  || painter->mapQuality() == PrintQuality );
94 
95  // Reset backend
96  m_tileLoader->resetTilehash();
97 
98  // Calculate translation of center point
99  const qreal centerLon = viewport->centerLongitude();
100  const qreal centerLat = viewport->centerLatitude();
101 
102  const int numTilesX = m_tileLoader->tileRowCount( tileZoomLevel );
103  const int numTilesY = m_tileLoader->tileColumnCount( tileZoomLevel );
104  Q_ASSERT( numTilesX > 0 );
105  Q_ASSERT( numTilesY > 0 );
106 
107  const qreal xNormalizedCenter = 0.5 + 0.5 * centerLon / M_PI;
108  const int minTileX = qFloor( numTilesX * ( xNormalizedCenter - imageWidth/( 8.0 * radius ) ) );
109  const int maxTileX = numTilesX * ( xNormalizedCenter + imageWidth/( 8.0 * radius ) );
110 
111  const qreal yNormalizedCenter = 0.5 - 0.5 * asinh( tan( centerLat ) ) / M_PI;
112  const int minTileY = qMax( qreal( numTilesY * ( yNormalizedCenter - imageHeight/( 8.0 * radius ) ) ),
113  qreal( 0.0 ) );
114  const int maxTileY = qMin( qreal( numTilesY * ( yNormalizedCenter + imageHeight/( 8.0 * radius ) ) ),
115  qreal( numTilesY - 1.0 ) );
116 
117  if ( m_radius != radius ) {
118  m_cache.clear();
119  }
120 
121  if ( texColorizer || m_radius != radius ) {
122  QPainter imagePainter( &m_canvasImage );
123  imagePainter.setRenderHint( QPainter::SmoothPixmapTransform, highQuality );
124 
125  for ( int tileY = minTileY; tileY <= maxTileY; ++tileY ) {
126  for ( int tileX = minTileX; tileX <= maxTileX; ++tileX ) {
127  const qreal xLeft = ( 4.0 * radius ) * ( ( tileX ) / (qreal)numTilesX - xNormalizedCenter ) + ( imageWidth / 2.0 );
128  const qreal xRight = ( 4.0 * radius ) * ( ( tileX + 1 ) / (qreal)numTilesX - xNormalizedCenter ) + ( imageWidth / 2.0 );
129  const qreal yTop = ( 4.0 * radius ) * ( ( tileY ) / (qreal)numTilesY - yNormalizedCenter ) + ( imageHeight / 2.0 );
130  const qreal yBottom = ( 4.0 * radius ) * ( ( tileY + 1 ) / (qreal)numTilesY - yNormalizedCenter ) + ( imageHeight / 2.0 );
131 
132  const QRectF rect = QRectF( QPointF( xLeft, yTop ), QPointF( xRight, yBottom ) );
133  const TileId stackedId = TileId( 0, tileZoomLevel, ( ( tileX % numTilesX ) + numTilesX ) % numTilesX, tileY );
134 
135  const StackedTile *const tile = m_tileLoader->loadTile( stackedId );
136 
137  const QImage *const toScale = tile->resultImage();
138  const int deltaLevel = stackedId.zoomLevel() - tile->id().zoomLevel();
139  const int restTileX = stackedId.x() % ( 1 << deltaLevel );
140  const int restTileY = stackedId.y() % ( 1 << deltaLevel );
141  const int partWidth = toScale->width() >> deltaLevel;
142  const int partHeight = toScale->height() >> deltaLevel;
143  const int startX = restTileX * partWidth;
144  const int startY = restTileY * partHeight;
145  const QImage part = toScale->copy( startX, startY, partWidth, partHeight ).scaled( toScale->size() );
146 
147  imagePainter.drawImage( rect, part );
148  }
149  }
150 
151  if ( texColorizer ) {
152  texColorizer->colorize( &m_canvasImage, viewport, painter->mapQuality() );
153  }
154  } else {
155  painter->save();
156  painter->setRenderHint( QPainter::SmoothPixmapTransform, highQuality );
157 
158  for ( int tileY = minTileY; tileY <= maxTileY; ++tileY ) {
159  for ( int tileX = minTileX; tileX <= maxTileX; ++tileX ) {
160  const qreal xLeft = ( 4.0 * radius ) * ( ( tileX ) / (qreal)numTilesX - xNormalizedCenter ) + ( imageWidth / 2.0 );
161  const qreal xRight = ( 4.0 * radius ) * ( ( tileX + 1 ) / (qreal)numTilesX - xNormalizedCenter ) + ( imageWidth / 2.0 );
162  const qreal yTop = ( 4.0 * radius ) * ( ( tileY ) / (qreal)numTilesY - yNormalizedCenter ) + ( imageHeight / 2.0 );
163  const qreal yBottom = ( 4.0 * radius ) * ( ( tileY + 1 ) / (qreal)numTilesY - yNormalizedCenter ) + ( imageHeight / 2.0 );
164 
165  const QRectF rect = QRectF( QPointF( xLeft, yTop ), QPointF( xRight, yBottom ) );
166  const TileId stackedId = TileId( 0, tileZoomLevel, ( ( tileX % numTilesX ) + numTilesX ) % numTilesX, tileY );
167  const StackedTile *const tile = m_tileLoader->loadTile( stackedId ); // load tile here for every frame, otherwise cleanupTilehash() clears all visible tiles
168 
169  const QSize size = QSize( qRound( rect.right() - rect.left() ), qRound( rect.bottom() - rect.top() ) );
170  const int cacheHash = 2 * ( size.width() % 2 ) + ( size.height() % 2 );
171  const TileId cacheId = TileId( cacheHash, stackedId.zoomLevel(), stackedId.x(), stackedId.y() );
172 
173  const QPixmap *const im_cached = m_cache[cacheId];
174  const QPixmap *im = im_cached;
175  if ( im == 0 ) {
176  const QImage *const toScale = tile->resultImage();
177  const int deltaLevel = stackedId.zoomLevel() - tile->id().zoomLevel();
178  const int restTileX = stackedId.x() % ( 1 << deltaLevel );
179  const int restTileY = stackedId.y() % ( 1 << deltaLevel );
180  const int partWidth = toScale->width() >> deltaLevel;
181  const int partHeight = toScale->height() >> deltaLevel;
182  const int startX = restTileX * partWidth;
183  const int startY = restTileY * partHeight;
184  const QImage part = toScale->copy( startX, startY, partWidth, partHeight ).scaled( toScale->size() );
185 
186  im = new QPixmap( QPixmap::fromImage( part.scaled( size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ) );
187  }
188  painter->drawPixmap( rect.topLeft(), *im );
189 
190  if (im != im_cached)
191  m_cache.insert( cacheId, im );
192  }
193  }
194 
195  painter->restore();
196  }
197 
198  m_tileLoader->cleanupTilehash();
199 }
200 
201 void TileScalingTextureMapper::removePixmap( const TileId &tileId )
202 {
203  const TileId stackedTileId( 0, tileId.zoomLevel(), tileId.x(), tileId.y() );
204  for ( int i = 0; i < 4; ++i ) {
205  const TileId id = TileId( i, stackedTileId.zoomLevel(), stackedTileId.x(), stackedTileId.y() );
206 
207  m_cache.remove( id );
208  }
209 }
210 
211 void TileScalingTextureMapper::clearPixmaps()
212 {
213  m_cache.clear();
214 }
215 
216 #include "TileScalingTextureMapper.moc"
QSize::width
int width() const
Marble::ViewportParams::size
QSize size() const
Definition: ViewportParams.cpp:260
QPainter::setRenderHint
void setRenderHint(RenderHint hint, bool on)
Marble::TileId::zoomLevel
int zoomLevel() const
Definition: TileId.h:57
Marble::GeoPainter
A painter that allows to draw geometric primitives on the map.
Definition: GeoPainter.h:98
Marble::TextureColorizer::colorize
void colorize(QImage *origimg, const ViewportParams *viewport, MapQuality mapQuality)
Definition: TextureColorizer.cpp:228
Marble::TileId::y
int y() const
Definition: TileId.h:67
QPainter::save
void save()
QPixmap::fromImage
QPixmap fromImage(const QImage &image, QFlags< Qt::ImageConversionFlag > flags)
QRectF::top
qreal top() const
Marble::Tile::id
TileId const & id() const
Returns a unique ID for the tile.
Definition: Tile.h:74
Marble::PrintQuality
Print quality.
Definition: MarbleGlobal.h:87
ScanlineTextureMapperContext.h
QImage::copy
QImage copy(const QRect &rectangle) const
TextureColorizer.h
QRectF::left
qreal left() const
Marble::StackedTileLoader
Tile loading from a quad tree.
Definition: StackedTileLoader.h:59
Marble::ViewportParams::height
int height() const
Definition: ViewportParams.cpp:255
Marble::StackedTile
A single tile that consists of a stack of Tile layers.
Definition: StackedTile.h:56
QPointF
QRectF::bottom
qreal bottom() const
QRect
Marble::ViewportParams::width
int width() const
Definition: ViewportParams.cpp:250
QImage::fill
void fill(uint pixelValue)
Marble::TextureMapperInterface
Definition: TextureMapperInterface.h:27
asinh
double asinh(double xval)
Definition: sgp4ext.cpp:211
QObject
QImage::width
int width() const
MathHelper.h
Marble::ViewportParams::mapCoversViewport
bool mapCoversViewport() const
Definition: ViewportParams.cpp:398
QPainter
Marble::ScanlineTextureMapperContext::optimalCanvasImageFormat
static QImage::Format optimalCanvasImageFormat(const ViewportParams *viewport)
Definition: ScanlineTextureMapperContext.cpp:429
Marble::radius
static qreal radius(qreal zoom)
Definition: thumbnailer.cpp:99
QRectF::topLeft
QPointF topLeft() const
Marble::StackedTileLoader::cleanupTilehash
void cleanupTilehash()
Cleans up the internal tile hash.
Definition: StackedTileLoader.cpp:100
Marble::TileScalingTextureMapper::mapTexture
virtual void mapTexture(GeoPainter *painter, const ViewportParams *viewport, int tileZoomLevel, const QRect &dirtyRect, TextureColorizer *texColorizer)
Definition: TileScalingTextureMapper.cpp:47
TileScalingTextureMapper.h
GeoPainter.h
Marble::StackedTile::resultImage
QImage const * resultImage() const
Returns the QImage that describes the merged stack of Tiles.
Definition: StackedTile.cpp:262
Marble::ViewportParams
A public class that controls what is visible in the viewport of a Marble map.
Definition: ViewportParams.h:44
QPixmap
Marble::TileId::x
int x() const
Definition: TileId.h:62
QRectF::right
qreal right() const
Marble::GeoPainter::drawImage
void drawImage(const GeoDataCoordinates &centerPosition, const QImage &image)
Draws an image at the given position. The image is placed with its center located at the given center...
Definition: GeoPainter.cpp:428
Marble::TextureColorizer
Definition: TextureColorizer.h:33
QSize
ViewportParams.h
This file contains the headers for ViewportParams.
QImage
Marble::StackedTileLoader::tileColumnCount
int tileColumnCount(int level) const
Definition: StackedTileLoader.cpp:70
Marble::StackedTileLoader::tileRowCount
int tileRowCount(int level) const
Definition: StackedTileLoader.cpp:75
Marble::ViewportParams::centerLatitude
qreal centerLatitude() const
Definition: ViewportParams.cpp:294
QPainter::restore
void restore()
Marble::TextureMapperInterface::m_repaintNeeded
bool m_repaintNeeded
Definition: TextureMapperInterface.h:42
Marble::TileId
Definition: TileId.h:27
Marble::ViewportParams::radius
int radius() const
Definition: ViewportParams.cpp:195
Marble::ViewportParams::centerLongitude
qreal centerLongitude() const
Definition: ViewportParams.cpp:289
Marble::HighQuality
High quality (e.g. antialiasing for lines)
Definition: MarbleGlobal.h:86
QRectF
StackedTile.h
QSize::height
int height() const
QImage::size
QSize size() const
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
Marble::TileScalingTextureMapper::TileScalingTextureMapper
TileScalingTextureMapper(StackedTileLoader *tileLoader, QObject *parent=0)
Definition: TileScalingTextureMapper.cpp:34
QImage::height
int height() const
Marble::GeoPainter::mapQuality
MapQuality mapQuality() const
Returns the map quality.
Definition: GeoPainter.cpp:191
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
TileLoaderHelper.h
QImage::format
Format format() const
Marble::GeoPainter::drawPixmap
void drawPixmap(const GeoDataCoordinates &centerPosition, const QPixmap &pixmap)
Draws a pixmap at the given position. The pixmap is placed with its center located at the given cente...
Definition: GeoPainter.cpp:452
QImage::scaled
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
Marble::StackedTileLoader::resetTilehash
void resetTilehash()
Resets the internal tile hash.
Definition: StackedTileLoader.cpp:90
Marble::StackedTileLoader::loadTile
const StackedTile * loadTile(TileId const &stackedTileId)
Loads a tile and returns it.
Definition: StackedTileLoader.cpp:118
StackedTileLoader.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal