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.