7#include "ScanlineTextureMapperContext.h" 
    9#include "GeoSceneAbstractTileProjection.h" 
   10#include "MarbleDebug.h" 
   11#include "StackedTile.h" 
   12#include "StackedTileLoader.h" 
   19ScanlineTextureMapperContext::ScanlineTextureMapperContext(
StackedTileLoader *
const tileLoader, 
int tileLevel)
 
   20    : m_tileLoader(tileLoader)
 
   21    , m_textureProjection(tileLoader->tileProjection()->
type())
 
   23    m_tileSize(tileLoader->tileSize())
 
   25    m_tileLevel(tileLevel)
 
   26    , m_globalWidth(m_tileSize.width() * m_tileLoader->tileColumnCount(m_tileLevel))
 
   27    , m_globalHeight(m_tileSize.height() * m_tileLoader->tileRowCount(m_tileLevel))
 
   28    , m_normGlobalWidth(m_globalWidth / (2 * M_PI))
 
   29    , m_normGlobalHeight(m_globalHeight / M_PI)
 
   33    , m_toTileCoordinatesLon(0.5 * m_globalWidth - m_tilePosX)
 
   34    , m_toTileCoordinatesLat(0.5 * m_globalHeight - m_tilePosY)
 
   42void ScanlineTextureMapperContext::pixelValueF(
const qreal lon, 
const qreal lat, QRgb *
const scanLine)
 
   51    m_prevPixelX = rad2PixelX(lon);
 
   52    m_prevPixelY = rad2PixelY(lat);
 
   54    qreal posX = m_toTileCoordinatesLon + m_prevPixelX;
 
   55    qreal posY = m_toTileCoordinatesLat + m_prevPixelY;
 
   61    if (posX >= (qreal)(m_tileSize.width()) || posX < 0.0 || posY >= (qreal)(m_tileSize.height()) || posY < 0.0) {
 
   65        *scanLine = m_tile->pixelF(posX, posY);
 
   74void ScanlineTextureMapperContext::pixelValue(
const qreal lon, 
const qreal lat, QRgb *
const scanLine)
 
   83    m_prevPixelX = rad2PixelX(lon);
 
   84    m_prevPixelY = rad2PixelY(lat);
 
   85    int iPosX = (int)(m_toTileCoordinatesLon + m_prevPixelX);
 
   86    int iPosY = (int)(m_toTileCoordinatesLat + m_prevPixelY);
 
   92    if (iPosX >= m_tileSize.width() || iPosX < 0 || iPosY >= m_tileSize.height() || iPosY < 0) {
 
   93        nextTile(iPosX, iPosY);
 
   97        *scanLine = m_tile->pixel(iPosX, iPosY);
 
  116void ScanlineTextureMapperContext::pixelValueApproxF(
const qreal lon, 
const qreal lat, QRgb *scanLine, 
const int n)
 
  120    qreal stepLat = lat - m_prevLat;
 
  121    qreal stepLon = lon - m_prevLon;
 
  126    const qreal nInverse = 1.0 / (qreal)(n);
 
  128    if (fabs(stepLon) < M_PI) {
 
  129        const qreal itStepLon = (rad2PixelX(lon) - m_prevPixelX) * nInverse;
 
  130        const qreal itStepLat = (rad2PixelY(lat) - m_prevPixelY) * nInverse;
 
  136        qreal itLon = m_prevPixelX + m_toTileCoordinatesLon;
 
  137        qreal itLat = m_prevPixelY + m_toTileCoordinatesLat;
 
  139        const int tileWidth = m_tileSize.width();
 
  140        const int tileHeight = m_tileSize.height();
 
  146        QRgb oldRgb = qRgb(0, 0, 0);
 
  151        const bool alwaysCheckTileRange = isOutOfTileRangeF(itLon, itLat, itStepLon, itStepLat, n);
 
  153        for (
int j = 1; j < n; ++j) {
 
  154            qreal posX = itLon + itStepLon * j;
 
  155            qreal posY = itLat + itStepLat * j;
 
  156            if (alwaysCheckTileRange)
 
  157                if (posX >= tileWidth || posX < 0.0 || posY >= tileHeight || posY < 0.0) {
 
  158                    nextTile(posX, posY);
 
  159                    itLon = m_prevPixelX + m_toTileCoordinatesLon;
 
  160                    itLat = m_prevPixelY + m_toTileCoordinatesLat;
 
  161                    posX = qBound<qreal>(0.0, (itLon + itStepLon * j), tileWidth - 1.0);
 
  162                    posY = qBound<qreal>(0.0, (itLat + itStepLat * j), tileHeight - 1.0);
 
  166            *scanLine = m_tile->pixelF(posX, posY);
 
  170            if (*scanLine != oldRgb) {
 
  172                    *(scanLine - 1) = m_tile->pixelF(oldPosX, oldPosY, *(scanLine - 1));
 
  175                oldRgb = m_tile->pixelF(posX, posY, *scanLine);
 
  196        stepLon = (TWOPI - fabs(stepLon)) * nInverse;
 
  197        stepLat = stepLat * nInverse;
 
  201        if (m_prevLon < lon) {
 
  202            for (
int j = 1; j < n; ++j) {
 
  203                m_prevLat += stepLat;
 
  204                m_prevLon -= stepLon;
 
  205                if (m_prevLon <= -M_PI)
 
  207                pixelValueF(m_prevLon, m_prevLat, scanLine);
 
  215            qreal curStepLon = lon - n * stepLon;
 
  217            for (
int j = 1; j < n; ++j) {
 
  218                m_prevLat += stepLat;
 
  219                curStepLon += stepLon;
 
  220                qreal evalLon = curStepLon;
 
  221                if (curStepLon <= -M_PI)
 
  223                pixelValueF(evalLon, m_prevLat, scanLine);
 
  230bool ScanlineTextureMapperContext::isOutOfTileRangeF(
const qreal itLon, 
const qreal itLat, 
const qreal itStepLon, 
const qreal itStepLat, 
const int n)
 const 
  232    const qreal minIPosX = itLon + itStepLon;
 
  233    const qreal minIPosY = itLat + itStepLat;
 
  234    const qreal maxIPosX = itLon + itStepLon * (n - 1);
 
  235    const qreal maxIPosY = itLat + itStepLat * (n - 1);
 
  236    return (maxIPosX >= m_tileSize.width() || maxIPosX < 0 || maxIPosY >= m_tileSize.height() || maxIPosY < 0 || minIPosX >= m_tileSize.width() || minIPosX < 0
 
  237            || minIPosY >= m_tileSize.height() || minIPosY < 0);
 
  240void ScanlineTextureMapperContext::pixelValueApprox(
const qreal lon, 
const qreal lat, QRgb *scanLine, 
const int n)
 
  244    qreal stepLat = lat - m_prevLat;
 
  245    qreal stepLon = lon - m_prevLon;
 
  250    const qreal nInverse = 1.0 / (qreal)(n);
 
  252    if (fabs(stepLon) < M_PI) {
 
  253        const int itStepLon = (int)((rad2PixelX(lon) - m_prevPixelX) * nInverse * 128.0);
 
  254        const int itStepLat = (int)((rad2PixelY(lat) - m_prevPixelY) * nInverse * 128.0);
 
  260        int itLon = (int)((m_prevPixelX + m_toTileCoordinatesLon) * 128.0);
 
  261        int itLat = (int)((m_prevPixelY + m_toTileCoordinatesLat) * 128.0);
 
  263        const int tileWidth = m_tileSize.width();
 
  264        const int tileHeight = m_tileSize.height();
 
  266        const bool alwaysCheckTileRange = isOutOfTileRange(itLon, itLat, itStepLon, itStepLat, n);
 
  268        if (!alwaysCheckTileRange) {
 
  271            for (
int j = 1; j < n; ++j) {
 
  274                *scanLine = m_tile->pixel(iPosXf >> 7, iPosYf >> 7);
 
  278            for (
int j = 1; j < n; ++j) {
 
  279                int iPosX = (itLon + itStepLon * j) >> 7;
 
  280                int iPosY = (itLat + itStepLat * j) >> 7;
 
  282                if (iPosX >= tileWidth || iPosX < 0 || iPosY >= tileHeight || iPosY < 0) {
 
  283                    nextTile(iPosX, iPosY);
 
  284                    itLon = (int)((m_prevPixelX + m_toTileCoordinatesLon) * 128.0);
 
  285                    itLat = (int)((m_prevPixelY + m_toTileCoordinatesLat) * 128.0);
 
  286                    iPosX = (itLon + itStepLon * j) >> 7;
 
  287                    iPosY = (itLat + itStepLat * j) >> 7;
 
  293                    if (iPosY >= tileHeight)
 
  294                        iPosY = tileHeight - 1;
 
  299                *scanLine = m_tile->pixel(iPosX, iPosY);
 
  311        stepLon = (TWOPI - fabs(stepLon)) * nInverse;
 
  312        stepLat = stepLat * nInverse;
 
  316        if (m_prevLon < lon) {
 
  317            for (
int j = 1; j < n; ++j) {
 
  318                m_prevLat += stepLat;
 
  319                m_prevLon -= stepLon;
 
  320                if (m_prevLon <= -M_PI)
 
  322                pixelValue(m_prevLon, m_prevLat, scanLine);
 
  330            qreal curStepLon = lon - n * stepLon;
 
  332            for (
int j = 1; j < n; ++j) {
 
  333                m_prevLat += stepLat;
 
  334                curStepLon += stepLon;
 
  335                qreal evalLon = curStepLon;
 
  336                if (curStepLon <= -M_PI)
 
  338                pixelValue(evalLon, m_prevLat, scanLine);
 
  345bool ScanlineTextureMapperContext::isOutOfTileRange(
const int itLon, 
const int itLat, 
const int itStepLon, 
const int itStepLat, 
const int n)
 const 
  347    const int minIPosX = (itLon + itStepLon) >> 7;
 
  348    const int minIPosY = (itLat + itStepLat) >> 7;
 
  349    const int maxIPosX = (itLon + itStepLon * (n - 1)) >> 7;
 
  350    const int maxIPosY = (itLat + itStepLat * (n - 1)) >> 7;
 
  351    return (maxIPosX >= m_tileSize.width() || maxIPosX < 0 || maxIPosY >= m_tileSize.height() || maxIPosY < 0 || minIPosX >= m_tileSize.width() || minIPosX < 0
 
  352            || minIPosY >= m_tileSize.height() || minIPosY < 0);
 
  361    if (!viewport->mapCoversViewport()) {
 
  367    const int width = viewport->width();
 
  370    int nEvalMin = width - 1;
 
  371    for (
int it = 1; it < 48; ++it) {
 
  372        int nEval = (width - 1) / it + (width - 1) % it;
 
  373        if (nEval < nEvalMin) {
 
  391void ScanlineTextureMapperContext::nextTile(
int &posX, 
int &posY)
 
  396    int lon = posX + m_tilePosX;
 
  397    if (lon >= m_globalWidth)
 
  398        lon -= m_globalWidth;
 
  400        lon += m_globalWidth;
 
  402    int lat = posY + m_tilePosY;
 
  403    if (lat >= m_globalHeight)
 
  404        lat -= m_globalHeight;
 
  406        lat += m_globalHeight;
 
  411    const int tileCol = lon / m_tileSize.width();
 
  412    const int tileRow = lat / m_tileSize.height();
 
  414    m_tile = m_tileLoader->loadTile(TileId(0, m_tileLevel, tileCol, tileRow));
 
  421    m_tilePosX = tileCol * m_tileSize.width();
 
  422    m_toTileCoordinatesLon = (qreal)(0.5 * m_globalWidth - m_tilePosX);
 
  423    posX = lon - m_tilePosX;
 
  425    m_tilePosY = tileRow * m_tileSize.height();
 
  426    m_toTileCoordinatesLat = (qreal)(0.5 * m_globalHeight - m_tilePosY);
 
  427    posY = lat - m_tilePosY;
 
  430void ScanlineTextureMapperContext::nextTile(qreal &posX, qreal &posY)
 
  435    int lon = (int)(posX + m_tilePosX);
 
  436    if (lon >= m_globalWidth)
 
  437        lon -= m_globalWidth;
 
  439        lon += m_globalWidth;
 
  441    int lat = (int)(posY + m_tilePosY);
 
  442    if (lat >= m_globalHeight)
 
  443        lat -= m_globalHeight;
 
  445        lat += m_globalHeight;
 
  450    const int tileCol = lon / m_tileSize.width();
 
  451    const int tileRow = lat / m_tileSize.height();
 
  453    m_tile = m_tileLoader->loadTile(TileId(0, m_tileLevel, tileCol, tileRow));
 
  460    m_tilePosX = tileCol * m_tileSize.width();
 
  461    m_toTileCoordinatesLon = (qreal)(0.5 * m_globalWidth - m_tilePosX);
 
  462    posX = lon - m_tilePosX;
 
  464    m_tilePosY = tileRow * m_tileSize.height();
 
  465    m_toTileCoordinatesLat = (qreal)(0.5 * m_globalHeight - m_tilePosY);
 
  466    posY = lat - m_tilePosY;
 
This file contains the headers for ViewParameters.
 
This file contains the headers for ViewportParams.
 
Tile loading from a quad tree.
 
A public class that controls what is visible in the viewport of a Marble map.
 
Type type(const QSqlDatabase &db)
 
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.
 
@ PrintQuality
Print quality.