• 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
MercatorScanlineTextureMapper.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 2007 Carlos Licea <carlos _licea@hotmail.com>
9 // Copyright 2008 Inge Wallin <inge@lysator.liu.se>
10 // Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
11 //
12 
13 
14 // local
15 #include"MercatorScanlineTextureMapper.h"
16 
17 // posix
18 #include <cmath>
19 
20 // Qt
21 #include <QRunnable>
22 
23 // Marble
24 #include "GeoPainter.h"
25 #include "MarbleDebug.h"
26 #include "ScanlineTextureMapperContext.h"
27 #include "StackedTileLoader.h"
28 #include "TextureColorizer.h"
29 #include "ViewportParams.h"
30 #include "MathHelper.h"
31 
32 using namespace Marble;
33 
34 class MercatorScanlineTextureMapper::RenderJob : public QRunnable
35 {
36 public:
37  RenderJob( StackedTileLoader *tileLoader, int tileLevel, QImage *canvasImage, const ViewportParams *viewport, MapQuality mapQuality, int yTop, int yBottom );
38 
39  virtual void run();
40 
41 private:
42  StackedTileLoader *const m_tileLoader;
43  const int m_tileLevel;
44  QImage *const m_canvasImage;
45  const ViewportParams *const m_viewport;
46  const MapQuality m_mapQuality;
47  const int m_yPaintedTop;
48  const int m_yPaintedBottom;
49 };
50 
51 MercatorScanlineTextureMapper::RenderJob::RenderJob( StackedTileLoader *tileLoader, int tileLevel, QImage *canvasImage, const ViewportParams *viewport, MapQuality mapQuality, int yTop, int yBottom )
52  : m_tileLoader( tileLoader ),
53  m_tileLevel( tileLevel ),
54  m_canvasImage( canvasImage ),
55  m_viewport( viewport ),
56  m_mapQuality( mapQuality ),
57  m_yPaintedTop( yTop ),
58  m_yPaintedBottom( yBottom )
59 {
60 }
61 
62 MercatorScanlineTextureMapper::MercatorScanlineTextureMapper( StackedTileLoader *tileLoader )
63  : TextureMapperInterface(),
64  m_tileLoader( tileLoader ),
65  m_radius( 0 ),
66  m_oldYPaintedTop( 0 )
67 {
68 }
69 
70 void MercatorScanlineTextureMapper::mapTexture( GeoPainter *painter,
71  const ViewportParams *viewport,
72  int tileZoomLevel,
73  const QRect &dirtyRect,
74  TextureColorizer *texColorizer )
75 {
76  if ( m_canvasImage.size() != viewport->size() || m_radius != viewport->radius() ) {
77  const QImage::Format optimalFormat = ScanlineTextureMapperContext::optimalCanvasImageFormat( viewport );
78 
79  if ( m_canvasImage.size() != viewport->size() || m_canvasImage.format() != optimalFormat ) {
80  m_canvasImage = QImage( viewport->size(), optimalFormat );
81  }
82 
83  if ( !viewport->mapCoversViewport() ) {
84  m_canvasImage.fill( 0 );
85  }
86 
87  m_radius = viewport->radius();
88  m_repaintNeeded = true;
89  }
90 
91  if ( m_repaintNeeded ) {
92  mapTexture( viewport, tileZoomLevel, painter->mapQuality() );
93 
94  if ( texColorizer ) {
95  texColorizer->colorize( &m_canvasImage, viewport, painter->mapQuality() );
96  }
97 
98  m_repaintNeeded = false;
99  }
100 
101  painter->drawImage( dirtyRect, m_canvasImage, dirtyRect );
102 }
103 
104 void MercatorScanlineTextureMapper::mapTexture( const ViewportParams *viewport, int tileZoomLevel, MapQuality mapQuality )
105 {
106  // Reset backend
107  m_tileLoader->resetTilehash();
108 
109  // Initialize needed constants:
110 
111  const int imageHeight = m_canvasImage.height();
112  const qint64 radius = viewport->radius();
113  // Calculate how many degrees are being represented per pixel.
114  const float rad2Pixel = (float)( 2 * radius ) / M_PI;
115 
116  //mDebug() << "m_maxGlobalX: " << m_maxGlobalX;
117  //mDebug() << "radius : " << radius << endl;
118 
119  // Calculate translation of center point
120  const qreal centerLat = viewport->centerLatitude();
121 
122  const int yCenterOffset = (int)( asinh( tan( centerLat ) ) * rad2Pixel );
123 
124  // Calculate y-range the represented by the center point, yTop and
125  // what actually can be painted
126  const int yTop = imageHeight / 2 - 2 * radius + yCenterOffset;
127  int yPaintedTop = imageHeight / 2 - 2 * radius + yCenterOffset;
128  int yPaintedBottom = imageHeight / 2 + 2 * radius + yCenterOffset;
129 
130  if (yPaintedTop < 0) yPaintedTop = 0;
131  if (yPaintedTop > imageHeight) yPaintedTop = imageHeight;
132  if (yPaintedBottom < 0) yPaintedBottom = 0;
133  if (yPaintedBottom > imageHeight) yPaintedBottom = imageHeight;
134 
135  const int numThreads = m_threadPool.maxThreadCount();
136  const int yStep = ( yPaintedBottom - yPaintedTop ) / numThreads;
137  for ( int i = 0; i < numThreads; ++i ) {
138  const int yStart = yPaintedTop + i * yStep;
139  const int yEnd = yPaintedTop + (i + 1) * yStep;
140  QRunnable *const job = new RenderJob( m_tileLoader, tileZoomLevel, &m_canvasImage, viewport, mapQuality, yStart, yEnd );
141  m_threadPool.start( job );
142  }
143 
144  // Remove unused lines
145  const int clearStart = ( yPaintedTop - m_oldYPaintedTop <= 0 ) ? yPaintedBottom : 0;
146  const int clearStop = ( yPaintedTop - m_oldYPaintedTop <= 0 ) ? imageHeight : yTop;
147 
148  QRgb * const itClearBegin = (QRgb*)( m_canvasImage.scanLine( clearStart ) );
149  QRgb * const itClearEnd = (QRgb*)( m_canvasImage.scanLine( clearStop ) );
150 
151  for ( QRgb * it = itClearBegin; it < itClearEnd; ++it ) {
152  *(it) = 0;
153  }
154 
155  m_threadPool.waitForDone();
156 
157  m_oldYPaintedTop = yPaintedTop;
158 
159  m_tileLoader->cleanupTilehash();
160 }
161 
162 
163 void MercatorScanlineTextureMapper::RenderJob::run()
164 {
165  // Scanline based algorithm to do texture mapping
166 
167  const int imageHeight = m_canvasImage->height();
168  const int imageWidth = m_canvasImage->width();
169  const qint64 radius = m_viewport->radius();
170  // Calculate how many degrees are being represented per pixel.
171  const float rad2Pixel = (float)( 2 * radius ) / M_PI;
172  const qreal pixel2Rad = 1.0/rad2Pixel;
173 
174  const bool interlaced = ( m_mapQuality == LowQuality );
175  const bool highQuality = ( m_mapQuality == HighQuality
176  || m_mapQuality == PrintQuality );
177  const bool printQuality = ( m_mapQuality == PrintQuality );
178 
179  // Evaluate the degree of interpolation
180  const int n = ScanlineTextureMapperContext::interpolationStep( m_viewport, m_mapQuality );
181 
182  // Calculate translation of center point
183  const qreal centerLon = m_viewport->centerLongitude();
184  const qreal centerLat = m_viewport->centerLatitude();
185 
186  const int yCenterOffset = (int)( asinh( tan( centerLat ) ) * rad2Pixel );
187 
188  qreal leftLon = + centerLon - ( imageWidth / 2 * pixel2Rad );
189  while ( leftLon < -M_PI ) leftLon += 2 * M_PI;
190  while ( leftLon > M_PI ) leftLon -= 2 * M_PI;
191 
192  const int maxInterpolationPointX = n * (int)( imageWidth / n - 1 ) + 1;
193 
194 
195  // initialize needed variables that are modified during texture mapping:
196 
197  ScanlineTextureMapperContext context( m_tileLoader, m_tileLevel );
198 
199 
200  // Scanline based algorithm to do texture mapping
201 
202  for ( int y = m_yPaintedTop; y < m_yPaintedBottom; ++y ) {
203 
204  QRgb * scanLine = (QRgb*)( m_canvasImage->scanLine( y ) );
205 
206  qreal lon = leftLon;
207  const qreal lat = atan( sinh( ( (imageHeight / 2 + yCenterOffset) - y )
208  * pixel2Rad ) );
209 
210  for ( int x = 0; x < imageWidth; ++x ) {
211  // Prepare for interpolation
212  bool interpolate = false;
213  if ( x > 0 && x <= maxInterpolationPointX ) {
214  x += n - 1;
215  lon += (n - 1) * pixel2Rad;
216  interpolate = !printQuality;
217  }
218  else {
219  interpolate = false;
220  }
221 
222  if ( lon < -M_PI ) lon += 2 * M_PI;
223  if ( lon > M_PI ) lon -= 2 * M_PI;
224 
225  if ( interpolate ) {
226  if (highQuality)
227  context.pixelValueApproxF( lon, lat, scanLine, n );
228  else
229  context.pixelValueApprox( lon, lat, scanLine, n );
230 
231  scanLine += ( n - 1 );
232  }
233 
234  if ( x < imageWidth ) {
235  if ( highQuality )
236  context.pixelValueF( lon, lat, scanLine );
237  else
238  context.pixelValue( lon, lat, scanLine );
239  }
240 
241  ++scanLine;
242  lon += pixel2Rad;
243  }
244 
245  // copy scanline to improve performance
246  if ( interlaced && y + 1 < m_yPaintedBottom ) {
247 
248  const int pixelByteSize = m_canvasImage->bytesPerLine() / imageWidth;
249 
250  memcpy( m_canvasImage->scanLine( y + 1 ),
251  m_canvasImage->scanLine( y ),
252  imageWidth * pixelByteSize );
253  ++y;
254  }
255  }
256 }
QImage::scanLine
uchar * scanLine(int i)
interpolate
void interpolate(MarbleWidget *widget, qreal value)
Definition: examples/cpp/animation-video/main.cpp:68
Marble::ViewportParams::size
QSize size() const
Definition: ViewportParams.cpp:260
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::PrintQuality
Print quality.
Definition: MarbleGlobal.h:87
Marble::MapQuality
MapQuality
This enum is used to choose the map quality shown in the view.
Definition: MarbleGlobal.h:82
ScanlineTextureMapperContext.h
MarbleDebug.h
TextureColorizer.h
Marble::StackedTileLoader
Tile loading from a quad tree.
Definition: StackedTileLoader.h:59
QRunnable
Marble::LowQuality
Low resolution (e.g. interlaced)
Definition: MarbleGlobal.h:84
QRect
QThreadPool::maxThreadCount
maxThreadCount
QImage::fill
void fill(uint pixelValue)
Marble::TextureMapperInterface
Definition: TextureMapperInterface.h:27
asinh
double asinh(double xval)
Definition: sgp4ext.cpp:211
MathHelper.h
Marble::ViewportParams::mapCoversViewport
bool mapCoversViewport() const
Definition: ViewportParams.cpp:398
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
Marble::StackedTileLoader::cleanupTilehash
void cleanupTilehash()
Cleans up the internal tile hash.
Definition: StackedTileLoader.cpp:100
QtConcurrent::run
QFuture< T > run(Function function,...)
GeoPainter.h
MercatorScanlineTextureMapper.h
Marble::ViewportParams
A public class that controls what is visible in the viewport of a Marble map.
Definition: ViewportParams.h:44
Marble::MercatorScanlineTextureMapper::MercatorScanlineTextureMapper
MercatorScanlineTextureMapper(StackedTileLoader *tileLoader)
Definition: MercatorScanlineTextureMapper.cpp:62
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
ViewportParams.h
This file contains the headers for ViewportParams.
Marble::MercatorScanlineTextureMapper::mapTexture
virtual void mapTexture(GeoPainter *painter, const ViewportParams *viewport, int tileZoomLevel, const QRect &dirtyRect, TextureColorizer *texColorizer)
Definition: MercatorScanlineTextureMapper.cpp:70
QImage
Marble::ViewportParams::centerLatitude
qreal centerLatitude() const
Definition: ViewportParams.cpp:294
QThreadPool::waitForDone
void waitForDone()
Marble::TextureMapperInterface::m_repaintNeeded
bool m_repaintNeeded
Definition: TextureMapperInterface.h:42
Marble::ViewportParams::radius
int radius() const
Definition: ViewportParams.cpp:195
Marble::HighQuality
High quality (e.g. antialiasing for lines)
Definition: MarbleGlobal.h:86
Marble::ScanlineTextureMapperContext::interpolationStep
static int interpolationStep(const ViewportParams *viewport, MapQuality mapQuality)
Definition: ScanlineTextureMapperContext.cpp:401
QImage::size
QSize size() const
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
Marble::ScanlineTextureMapperContext
Definition: ScanlineTextureMapperContext.h:30
QImage::height
int height() const
Marble::GeoPainter::mapQuality
MapQuality mapQuality() const
Returns the map quality.
Definition: GeoPainter.cpp:191
QThreadPool::start
void start(QRunnable *runnable, int priority)
QImage::format
Format format() const
Marble::StackedTileLoader::resetTilehash
void resetTilehash()
Resets the internal tile hash.
Definition: StackedTileLoader.cpp:90
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:40 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