9#include"EquirectScanlineTextureMapper.h"
18#include "GeoPainter.h"
19#include "MarbleDebug.h"
20#include "ScanlineTextureMapperContext.h"
21#include "StackedTileLoader.h"
22#include "TextureColorizer.h"
28class EquirectScanlineTextureMapper::RenderJob :
public QRunnable
37 const int m_tileLevel;
38 QImage *
const m_canvasImage;
41 const int m_yPaintedTop;
42 const int m_yPaintedBottom;
46 : m_tileLoader( tileLoader ),
47 m_tileLevel( tileLevel ),
48 m_canvasImage( canvasImage ),
49 m_viewport( viewport ),
50 m_mapQuality( mapQuality ),
51 m_yPaintedTop( yTop ),
52 m_yPaintedBottom( yBottom )
57EquirectScanlineTextureMapper::EquirectScanlineTextureMapper(
StackedTileLoader *tileLoader )
58 : TextureMapperInterface(),
59 m_tileLoader( tileLoader ),
65void EquirectScanlineTextureMapper::mapTexture(
GeoPainter *painter,
68 const QRect &dirtyRect,
69 TextureColorizer *texColorizer )
71 if ( m_canvasImage.
size() != viewport->size() || m_radius != viewport->radius() ) {
72 const QImage::Format optimalFormat = ScanlineTextureMapperContext::optimalCanvasImageFormat( viewport );
74 if ( m_canvasImage.
size() != viewport->size() || m_canvasImage.
format() != optimalFormat ) {
75 m_canvasImage =
QImage( viewport->size(), optimalFormat );
78 if ( !viewport->mapCoversViewport() ) {
79 m_canvasImage.
fill( 0 );
82 m_radius = viewport->radius();
83 m_repaintNeeded =
true;
86 if ( m_repaintNeeded ) {
87 mapTexture( viewport, tileZoomLevel, painter->
mapQuality() );
90 texColorizer->colorize( &m_canvasImage, viewport, painter->
mapQuality() );
93 m_repaintNeeded =
false;
96 painter->
drawImage( dirtyRect, m_canvasImage, dirtyRect );
99void EquirectScanlineTextureMapper::mapTexture(
const ViewportParams *viewport,
int tileZoomLevel,
MapQuality mapQuality )
106 const int imageHeight = m_canvasImage.
height();
111 qreal realYTop, realYBottom, dummyX;
117 const int yTop = qBound(qreal(0.0), realYTop, qreal(imageHeight));
118 int yPaintedTop = yTop;
119 int yPaintedBottom = qBound(qreal(0.0), realYBottom, qreal(imageHeight));
121 yPaintedTop = qBound(0, yPaintedTop, imageHeight);
122 yPaintedBottom = qBound(0, yPaintedBottom, imageHeight);
125 const int yStep = ( yPaintedBottom - yPaintedTop ) / numThreads;
126 for (
int i = 0; i < numThreads; ++i ) {
127 const int yStart = yPaintedTop + i * yStep;
128 const int yEnd = (i == numThreads - 1) ? yPaintedBottom : yPaintedTop + (i + 1) * yStep;
129 QRunnable *
const job =
new RenderJob( m_tileLoader, tileZoomLevel, &m_canvasImage, viewport, mapQuality, yStart, yEnd );
130 m_threadPool.
start( job );
134 const int clearStart = ( yPaintedTop - m_oldYPaintedTop <= 0 ) ? yPaintedBottom : 0;
135 const int clearStop = ( yPaintedTop - m_oldYPaintedTop <= 0 ) ? imageHeight : yTop;
137 QRgb *
const itClearBegin = (QRgb*)( m_canvasImage.
scanLine( clearStart ) );
138 QRgb *
const itClearEnd = (QRgb*)( m_canvasImage.
scanLine( clearStop ) );
140 for ( QRgb * it = itClearBegin; it < itClearEnd; ++it ) {
146 m_oldYPaintedTop = yPaintedTop;
151void EquirectScanlineTextureMapper::RenderJob::run()
155 const int imageHeight = m_canvasImage->
height();
156 const int imageWidth = m_canvasImage->
width();
157 const qint64 radius = m_viewport->radius();
159 const qreal rad2Pixel = (qreal)( 2 * radius ) / M_PI;
160 const float pixel2Rad = 1.0/rad2Pixel;
162 const bool interlaced = ( m_mapQuality ==
LowQuality );
163 const bool highQuality = ( m_mapQuality ==
HighQuality
165 const bool printQuality = ( m_mapQuality ==
PrintQuality );
168 const int n = ScanlineTextureMapperContext::interpolationStep( m_viewport, m_mapQuality );
171 const qreal centerLon = m_viewport->centerLongitude();
172 const qreal centerLat = m_viewport->centerLatitude();
174 const int yCenterOffset = (int)( centerLat * rad2Pixel );
176 const int yTop = imageHeight / 2 - radius + yCenterOffset;
178 qreal leftLon = + centerLon - ( imageWidth / 2 * pixel2Rad );
179 while ( leftLon < -M_PI ) leftLon += 2 * M_PI;
180 while ( leftLon > M_PI ) leftLon -= 2 * M_PI;
182 const int maxInterpolationPointX = n * (int)( imageWidth / n - 1 ) + 1;
187 ScanlineTextureMapperContext context( m_tileLoader, m_tileLevel );
192 for (
int y = m_yPaintedTop; y < m_yPaintedBottom; ++y ) {
194 QRgb * scanLine = (QRgb*)( m_canvasImage->
scanLine( y ) );
197 const qreal lat = M_PI/2 - (y - yTop )* pixel2Rad;
199 for (
int x = 0; x < imageWidth; ++x ) {
202 bool interpolate =
false;
203 if ( x > 0 && x <= maxInterpolationPointX ) {
205 lon += (n - 1) * pixel2Rad;
206 interpolate = !printQuality;
212 if ( lon < -M_PI ) lon += 2 * M_PI;
213 if ( lon > M_PI ) lon -= 2 * M_PI;
217 context.pixelValueApproxF( lon, lat, scanLine, n );
219 context.pixelValueApprox( lon, lat, scanLine, n );
221 scanLine += ( n - 1 );
224 if ( x < imageWidth ) {
226 context.pixelValueF( lon, lat, scanLine );
228 context.pixelValue( lon, lat, scanLine );
236 if ( interlaced && y + 1 < m_yPaintedBottom ) {
238 const int pixelByteSize = m_canvasImage->
bytesPerLine() / imageWidth;
240 memcpy( m_canvasImage->
scanLine( y + 1 ),
242 imageWidth * pixelByteSize );
This file contains the headers for AbstractProjection.
This file contains the headers for ViewportParams.
qreal minLat() const
Returns the arbitrarily chosen minimum (southern) latitude.
qreal maxLat() const
Returns the arbitrarily chosen maximum (northern) latitude.
A 3d point representation.
A painter that allows to draw geometric primitives on the map.
MapQuality mapQuality() const
Returns the map quality.
void drawImage(const GeoDataCoordinates ¢erPosition, const QImage &image)
Draws an image at the given position. The image is placed with its center located at the given center...
Tile loading from a quad tree.
void cleanupTilehash()
Cleans up the internal tile hash.
void resetTilehash()
Resets the internal tile hash.
A public class that controls what is visible in the viewport of a Marble map.
bool screenCoordinates(const qreal lon, const qreal lat, qreal &x, qreal &y) const
Get the screen coordinates corresponding to geographical coordinates in the map.
Binds a QML item to a specific geodetic location in screen coordinates.
MapQuality
This enum is used to choose the map quality shown in the view.
@ HighQuality
High quality (e.g. antialiasing for lines)
@ PrintQuality
Print quality.
@ LowQuality
Low resolution (e.g. interlaced)
qsizetype bytesPerLine() const const
void fill(Qt::GlobalColor color)
void start(Callable &&callableToRun, int priority)
bool waitForDone(int msecs)