23 using namespace Marble;
26 : m_tileLoader( tileLoader ),
27 m_textureProjection( tileLoader->tileProjection() ),
28 m_tileSize( tileLoader->tileSize() ),
29 m_tileLevel( tileLevel ),
30 m_globalWidth( m_tileSize.width() * m_tileLoader->tileColumnCount( m_tileLevel ) ),
31 m_globalHeight( m_tileSize.height() * m_tileLoader->tileRowCount( m_tileLevel ) ),
32 m_normGlobalWidth( m_globalWidth / ( 2 *
M_PI ) ),
33 m_normGlobalHeight( m_globalHeight /
M_PI ),
40 m_toTileCoordinatesLon( 0.5 * m_globalWidth - m_tilePosX ),
41 m_toTileCoordinatesLat( 0.5 * m_globalHeight - m_tilePosY ),
48 QRgb*
const scanLine )
57 qreal posX = m_toTileCoordinatesLon + rad2PixelX( lon );
58 qreal posY = m_toTileCoordinatesLat + rad2PixelY( lat );
64 if ( posX >= (qreal)( m_tileSize.
width() )
66 || posY >= (qreal)( m_tileSize.
height() )
69 nextTile( posX, posY );
72 *scanLine = m_tile->
pixelF( ( (
int)posX + m_vTileStartX ) / ( 1 << m_deltaLevel ),
73 ( (
int)posY + m_vTileStartY ) / ( 1 << m_deltaLevel ) );
84 QRgb*
const scanLine )
93 int iPosX = (int)( m_toTileCoordinatesLon + rad2PixelX( lon ) );
94 int iPosY = (int)( m_toTileCoordinatesLat + rad2PixelY( lat ) );
100 if ( iPosX >= m_tileSize.
width()
102 || iPosY >= m_tileSize.
height()
105 nextTile( iPosX, iPosY );
109 *scanLine = m_tile->
pixel( ( iPosX + m_vTileStartX ) >> m_deltaLevel,
110 ( iPosY + m_vTileStartY ) >> m_deltaLevel );
131 QRgb *scanLine,
const int n )
135 qreal stepLat = lat - m_prevLat;
136 qreal stepLon = lon - m_prevLon;
141 const qreal nInverse = 1.0 / (qreal)(n);
143 if ( fabs(stepLon) <
M_PI ) {
144 const qreal prevPixelX = rad2PixelX( m_prevLon );
145 const qreal prevPixelY = rad2PixelY( m_prevLat );
147 const qreal itStepLon = ( rad2PixelX( lon ) - prevPixelX ) * nInverse;
148 const qreal itStepLat = ( rad2PixelY( lat ) - prevPixelY ) * nInverse;
154 qreal itLon = prevPixelX + m_toTileCoordinatesLon;
155 qreal itLat = prevPixelY + m_toTileCoordinatesLat;
157 const int tileWidth = m_tileSize.
width();
158 const int tileHeight = m_tileSize.
height();
164 QRgb oldRgb = qRgb( 0, 0, 0 );
169 const bool alwaysCheckTileRange =
170 isOutOfTileRangeF( itLon, itLat, itStepLon, itStepLat, n );
172 for (
int j=1; j < n; ++j ) {
173 qreal posX = itLon + itStepLon * j;
174 qreal posY = itLat + itStepLat * j;
175 if ( alwaysCheckTileRange )
176 if ( posX >= tileWidth
178 || posY >= tileHeight
181 nextTile( posX, posY );
182 itLon = prevPixelX + m_toTileCoordinatesLon;
183 itLat = prevPixelY + m_toTileCoordinatesLat;
184 posX = qMax<qreal>( 0.0, qMin<qreal>( tileWidth-1.0, itLon + itStepLon * j ) );
185 posY = qMax<qreal>( 0.0, qMin<qreal>( tileHeight-1.0, itLat + itStepLat * j ) );
189 *scanLine = m_tile->
pixel( ( (
int)posX + m_vTileStartX ) >> m_deltaLevel,
190 ( (
int)posY + m_vTileStartY ) >> m_deltaLevel );
194 if ( *scanLine != oldRgb ) {
195 if ( oldPosX != -1 ) {
196 *(scanLine - 1) = m_tile->
pixelF( ( oldPosX + m_vTileStartX ) / ( 1 << m_deltaLevel ),
197 ( oldPosY + m_vTileStartY ) / ( 1 << m_deltaLevel ),
201 oldRgb = m_tile->
pixelF( ( posX + m_vTileStartX ) / ( 1 << m_deltaLevel ),
202 ( posY + m_vTileStartY ) / ( 1 << m_deltaLevel ),
225 stepLon = (
TWOPI - fabs(stepLon) ) * nInverse;
226 stepLat = stepLat * nInverse;
230 if ( m_prevLon < lon ) {
232 for (
int j = 1; j < n; ++j ) {
233 m_prevLat += stepLat;
234 m_prevLon -= stepLon;
235 if ( m_prevLon <= -
M_PI )
245 qreal curStepLon = lon - n * stepLon;
247 for (
int j = 1; j < n; ++j ) {
248 m_prevLat += stepLat;
249 curStepLon += stepLon;
250 qreal evalLon = curStepLon;
251 if ( curStepLon <= -
M_PI )
261 bool ScanlineTextureMapperContext::isOutOfTileRangeF(
const qreal itLon,
const qreal itLat,
262 const qreal itStepLon,
const qreal itStepLat,
265 const qreal minIPosX = itLon + itStepLon;
266 const qreal minIPosY = itLat + itStepLat;
267 const qreal maxIPosX = itLon + itStepLon * ( n - 1 );
268 const qreal maxIPosY = itLat + itStepLat * ( n - 1 );
269 return ( maxIPosX >= m_tileSize.
width() || maxIPosX < 0
270 || maxIPosY >= m_tileSize.
height() || maxIPosY < 0
271 || minIPosX >= m_tileSize.
width() || minIPosX < 0
272 || minIPosY >= m_tileSize.
height() || minIPosY < 0 );
277 QRgb *scanLine,
const int n )
281 qreal stepLat = lat - m_prevLat;
282 qreal stepLon = lon - m_prevLon;
287 const qreal nInverse = 1.0 / (qreal)(n);
289 if ( fabs(stepLon) <
M_PI ) {
290 const qreal prevPixelX = rad2PixelX( m_prevLon );
291 const qreal prevPixelY = rad2PixelY( m_prevLat );
293 const int itStepLon = (int)( ( rad2PixelX( lon ) - prevPixelX ) * nInverse * 128.0 );
294 const int itStepLat = (int)( ( rad2PixelY( lat ) - prevPixelY ) * nInverse * 128.0 );
300 int itLon = (int)( ( prevPixelX + m_toTileCoordinatesLon ) * 128.0 );
301 int itLat = (int)( ( prevPixelY + m_toTileCoordinatesLat ) * 128.0 );
303 const int tileWidth = m_tileSize.
width();
304 const int tileHeight = m_tileSize.
height();
306 const bool alwaysCheckTileRange =
307 isOutOfTileRange( itLon, itLat, itStepLon, itStepLat, n );
309 if ( !alwaysCheckTileRange ) {
312 for (
int j = 1; j < n; ++j ) {
315 *scanLine = m_tile->
pixel( ( ( iPosXf >> 7 ) + m_vTileStartX ) >> m_deltaLevel,
316 ( ( iPosYf >> 7 ) + m_vTileStartY ) >> m_deltaLevel );
321 for (
int j = 1; j < n; ++j ) {
322 int iPosX = ( itLon + itStepLon * j ) >> 7;
323 int iPosY = ( itLat + itStepLat * j ) >> 7;
325 if ( iPosX >= tileWidth
327 || iPosY >= tileHeight
330 nextTile( iPosX, iPosY );
331 itLon = (int)( ( prevPixelX + m_toTileCoordinatesLon ) * 128.0 );
332 itLat = (int)( ( prevPixelY + m_toTileCoordinatesLat ) * 128.0 );
333 iPosX = ( itLon + itStepLon * j ) >> 7;
334 iPosY = ( itLat + itStepLat * j ) >> 7;
337 *scanLine = m_tile->
pixel( ( iPosX + m_vTileStartX ) >> m_deltaLevel,
338 ( iPosY + m_vTileStartY ) >> m_deltaLevel );
350 stepLon = (
TWOPI - fabs(stepLon) ) * nInverse;
351 stepLat = stepLat * nInverse;
355 if ( m_prevLon < lon ) {
357 for (
int j = 1; j < n; ++j ) {
358 m_prevLat += stepLat;
359 m_prevLon -= stepLon;
360 if ( m_prevLon <= -
M_PI )
370 qreal curStepLon = lon - n * stepLon;
372 for (
int j = 1; j < n; ++j ) {
373 m_prevLat += stepLat;
374 curStepLon += stepLon;
375 qreal evalLon = curStepLon;
376 if ( curStepLon <= -
M_PI )
386 bool ScanlineTextureMapperContext::isOutOfTileRange(
const int itLon,
const int itLat,
387 const int itStepLon,
const int itStepLat,
390 const int minIPosX = ( itLon + itStepLon ) >> 7;
391 const int minIPosY = ( itLat + itStepLat ) >> 7;
392 const int maxIPosX = ( itLon + itStepLon * ( n - 1 ) ) >> 7;
393 const int maxIPosY = ( itLat + itStepLat * ( n - 1 ) ) >> 7;
394 return ( maxIPosX >= m_tileSize.
width() || maxIPosX < 0
395 || maxIPosY >= m_tileSize.
height() || maxIPosY < 0
396 || minIPosX >= m_tileSize.
width() || minIPosX < 0
397 || minIPosY >= m_tileSize.
height() || minIPosY < 0 );
413 const int width = viewport->
width();
416 int nEvalMin = width - 1;
417 for (
int it = 1; it < 48; ++it ) {
418 int nEval = ( width - 1 ) / it + ( width - 1 ) % it;
419 if ( nEval < nEvalMin ) {
434 ? QImage::Format_RGB32
435 : QImage::Format_ARGB32_Premultiplied;
441 void ScanlineTextureMapperContext::nextTile(
int &posX,
int &posY )
446 int lon = posX + m_tilePosX;
447 if ( lon >= m_globalWidth )
448 lon -= m_globalWidth;
450 lon += m_globalWidth;
452 int lat = posY + m_tilePosY;
453 if ( lat >= m_globalHeight )
454 lat -= m_globalHeight;
456 lat += m_globalHeight;
461 const int tileCol = lon / m_tileSize.
width();
462 const int tileRow = lat / m_tileSize.
height();
465 m_tile = m_tileLoader->
loadTile(
TileId( 0, m_tileLevel - m_deltaLevel, tileCol >> m_deltaLevel, tileRow >> m_deltaLevel ) );
472 m_tilePosX = tileCol * m_tileSize.
width();
473 m_vTileStartX = ( tileCol - ( ( tileCol >> m_deltaLevel ) << m_deltaLevel ) ) * m_tileSize.
width();
474 m_toTileCoordinatesLon = (qreal)(0.5 * m_globalWidth - m_tilePosX);
475 posX = lon - m_tilePosX;
477 m_tilePosY = tileRow * m_tileSize.
height();
478 m_vTileStartY = ( tileRow - ( ( tileRow >> m_deltaLevel ) << m_deltaLevel ) ) * m_tileSize.
height();
479 m_toTileCoordinatesLat = (qreal)(0.5 * m_globalHeight - m_tilePosY);
480 posY = lat - m_tilePosY;
483 void ScanlineTextureMapperContext::nextTile( qreal &posX, qreal &posY )
488 int lon = (int)(posX + m_tilePosX);
489 if ( lon >= m_globalWidth )
490 lon -= m_globalWidth;
492 lon += m_globalWidth;
494 int lat = (int)(posY + m_tilePosY);
495 if ( lat >= m_globalHeight )
496 lat -= m_globalHeight;
498 lat += m_globalHeight;
503 const int tileCol = lon / m_tileSize.
width();
504 const int tileRow = lat / m_tileSize.
height();
507 m_tile = m_tileLoader->
loadTile(
TileId( 0, m_tileLevel - m_deltaLevel, tileCol >> m_deltaLevel, tileRow >> m_deltaLevel ) );
514 m_tilePosX = tileCol * m_tileSize.
width();
515 m_vTileStartX = ( tileCol - ( ( tileCol >> m_deltaLevel ) << m_deltaLevel ) ) * m_tileSize.
width();
516 m_toTileCoordinatesLon = (qreal)(0.5 * m_globalWidth - m_tilePosX);
517 posX = lon - m_tilePosX;
519 m_tilePosY = tileRow * m_tileSize.
height();
520 m_vTileStartY = ( tileRow - ( ( tileRow >> m_deltaLevel ) << m_deltaLevel ) ) * m_tileSize.
height();
521 m_toTileCoordinatesLat = (qreal)(0.5 * m_globalHeight - m_tilePosY);
522 posY = lat - m_tilePosY;
void pixelValueApprox(const qreal lon, const qreal lat, QRgb *scanLine, const int n)
void pixelValue(const qreal lon, const qreal lat, QRgb *const scanLine)
uint pixelF(qreal x, qreal y) const
Returns the color value of the result tile at a given floating point position.
MapQuality
This enum is used to choose the map quality shown in the view.
Tile loading from a quad tree.
ScanlineTextureMapperContext(StackedTileLoader *const tileLoader, int tileLevel)
This file contains the headers for ViewParameters.
bool mapCoversViewport() const
static QImage::Format optimalCanvasImageFormat(const ViewportParams *viewport)
void pixelValueApproxF(const qreal lon, const qreal lat, QRgb *scanLine, const int n)
A public class that controls what is visible in the viewport of a Marble map.
This file contains the headers for ViewportParams.
void pixelValueF(const qreal lon, const qreal lat, QRgb *const scanLine)
uint pixel(int x, int y) const
Returns the color value of the result tile at the given integer position.
static int interpolationStep(const ViewportParams *viewport, MapQuality mapQuality)
const StackedTile * loadTile(TileId const &stackedTileId)
Loads a tile and returns it.