Russian Qt Forum
Октябрь 02, 2024, 11:23 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Алгоритм наложения тайлов на сферу (проекция меркатора)  (Прочитано 21819 раз)
spirits25
Гость
« : Март 01, 2013, 11:30 »

Бодрого всем времени суток.

Может у кого есть наброски или работающий код по наложении тайлов карт (google, OpenStreetMap etc.) на сферу?

Столкнулся со следующей проблемой - строю сферу, используя qt3d, при этом хорошо накладываются тайлы в меркаторе, но если перевожу координаты в сферическую проекцию, то необходимо смещать и вертексы, к которым крепится текущая текстура.

Если необходимо, могу скинуть код, но надеюсь, что кто-то этим уже занимался и поможет=)

Спасибо.
« Последнее редактирование: Апрель 16, 2013, 12:59 от spirits25 » Записан
ssoft
Гость
« Ответ #1 : Март 01, 2013, 12:01 »

Все достаточно просто, необходимо
   - каждый тайл представить в виде сетки точек I x J.
   - для каждой точки
     1. выполнить преобразование из проекции Меркатора на геоид WGS84
     2. выполнить преобразование из геоида WGS84 в 3D декартовые координаты
   - наложить текстуру тайла на сетку точек в декартовых координатах.

Формулы для преобразования можно посмотреть, например, на http://gis-lab.info
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Март 01, 2013, 13:05 »

Отвечал на подобный вопрос, тогда помню разобрались. Поищите по форуму "меркатор". Вертексы двигать не надо, просто пересчитать UV
Записан
spirits25
Гость
« Ответ #3 : Март 05, 2013, 13:50 »

Отвечал на подобный вопрос, тогда помню разобрались. Поищите по форуму "меркатор". Вертексы двигать не надо, просто пересчитать UV

http://www.prog.org.ru/index.php?topic=23408.msg166006#msg166006 в этом сообщении как раз перевод из Меркатора в геоид WGS84?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Март 05, 2013, 16:32 »

http://www.prog.org.ru/index.php?topic=23408.msg166006#msg166006 в этом сообщении как раз перевод из Меркатора в геоид WGS84?
Там перевод из UV сферических в UV меркатора
Записан
spirits25
Гость
« Ответ #5 : Март 05, 2013, 17:21 »

http://www.prog.org.ru/index.php?topic=23408.msg166006#msg166006 в этом сообщении как раз перевод из Меркатора в геоид WGS84?
Там перевод из UV сферических в UV меркатора

Точно не наоборот из меркатора в сферические?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Март 05, 2013, 19:14 »

Точно не наоборот из меркатора в сферические?
Точно, Вы же тогда и спрашивали.

Столкнулся со следующей проблемой - строю сферу, используя qt3d, при этом хорошо накладываются тайлы в меркаторе, но если перевожу координаты в сферическую проекцию, то необходимо смещать и вертексы, к которым крепится текущая текстура.
Какую текстуру Вы хотите наложить на модель сферы?  Текстуру меркатора умеете, сферическая текстура ложится по умолчанию. Что же нужно?
Записан
spirits25
Гость
« Ответ #7 : Март 06, 2013, 13:16 »

Какую текстуру Вы хотите наложить на модель сферы?  Текстуру меркатора умеете, сферическая текстура ложится по умолчанию. Что же нужно?

Вся проблема в том, что текстуры в проекции меркатора, а мне нужно наложить их в обычной (текстуры openstreetmap, но и у google maps такие же). Для первых двух зумов всё отлично, но потом идёт смещение, так как тайл проекции меркатора накладывается на отличные координаты от тех, на которые наложился бы тайл в сферической проекции. Вот в этом проблема, как к вертексам сферы наложить новые тайлы (текстуры). Сейчас буду пробовать совет ssoft.
Записан
ssoft
Гость
« Ответ #8 : Март 06, 2013, 14:40 »

Пробуй - у нас все получилось и работает. Подмигивающий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Март 06, 2013, 17:09 »

Вся проблема в том, что текстуры в проекции меркатора, а мне нужно наложить их в обычной (текстуры openstreetmap, но и у google maps такие же). Для первых двух зумов всё отлично, но потом идёт смещение, так как тайл проекции меркатора накладывается на отличные координаты от тех, на которые наложился бы тайл в сферической проекции. Вот в этом проблема, как к вертексам сферы наложить новые тайлы (текстуры). Сейчас буду пробовать совет ssoft.
Неудобно приставать с вопросами, но все же: я так вижу это дело

- текстура (картинка) подготовлена для проекции меркатора - ну значит и UV должны быть рассчитаны для меркатора

- текстура (картинка) сферическая - ну значит и UV должны быть сферические

Тайл (tile) - это кусочек картинки, возможно для его повторения. В каком контексте Вы здесь используете этот термин - не понимаю. Может как-то хотите пересчитать картинку - ну это обычно дело долгое и мутное. В общем, я растерялся и не понимаю о чем речь  Улыбающийся
Записан
spirits25
Гость
« Ответ #10 : Март 13, 2013, 11:00 »

Тайл (tile) - это кусочек картинки, возможно для его повторения. В каком контексте Вы здесь используете этот термин - не понимаю. Может как-то хотите пересчитать картинку - ну это обычно дело долгое и мутное. В общем, я растерялся и не понимаю о чем речь  Улыбающийся


http://tile.openstreetmap.org/2/2/1.png - вот тайл, он в меркаторе.
Записан
spirits25
Гость
« Ответ #11 : Март 13, 2013, 11:03 »

Пробуй - у нас все получилось и работает. Подмигивающий

У вас случайно нельзя именно этот небольшой кусок попросить посмотреть?

Вчера переписал полностью создание сферы и наложение. Для одной картинки круто, даже быстрее, чем в примерах получилось. А вот если несколько тайлов, то всё равно немного не правильно рассчитывается.
Записан
spirits25
Гость
« Ответ #12 : Март 13, 2013, 14:26 »

Вот мой код:

В этом методе я просто вычисляю количество тайлов для текущего зума и накладываю каждый тайл:
Код:
QGLSceneNode *Earth::buildEarthNode(qreal radius, int divisions, int cur_zoom)
{
    qreal separation = qPow(2, cur_zoom);
    QGLBuilder builder;

    for (int lonTileNum = 0; lonTileNum < separation; lonTileNum++)
    {
        for (int latTileNum = 0; latTileNum < separation; latTileNum++)
        {
            addTileNode(&builder, radius, divisions, cur_zoom, lonTileNum, latTileNum);
        }
    }
    return builder.finalizedSceneNode();
}

А вот здесь уже строится и накладывается текстура (каждый тайл из http://tile.openstreetmap.org/z/x/y.png):

Код:
void Earth::addTileNode(QGLBuilder* builder, qreal radius, int divisions, int cur_zoom,
                        qint32 lonTileNum, qint32 latTileNum)
{
    int separation = qPow(2, cur_zoom);

    // degrees for one tile
    qreal NTLat = 2*maxAbsLat / separation;
    qreal NTLon = 2*maxAbsLon / separation;

    // min and max tile degrees
    qreal minLat = latTileNum * NTLat - maxAbsLat;
    qreal maxLat = (latTileNum+1) * NTLat - maxAbsLat;
    qreal minLon = lonTileNum * NTLon - maxAbsLon;
    qreal maxLon = (lonTileNum+1) * NTLon - maxAbsLon;

    // calculate spherical min and max lon and lat
    int signMinLat = (minLat<0)?-1:1;
    int signMaxLat = (maxLat<0)?-1:1;
    qreal minSphereLat = Mercator2SphereAnalyticDegrees(qAbs(minLat))*signMinLat;
    qreal maxSphereLat = Mercator2SphereAnalyticDegrees(qAbs(maxLat))*signMaxLat;

    qreal minSphereLon = minLon;
    qreal maxSphereLon = maxLon;

    // all stacks and slices
    int stacks = 32;
    int slices = 32;
    if (cur_zoom > 6)
    {
        stacks *= qPow(2, cur_zoom - 6);
        slices *= qPow(2, cur_zoom - 6);
    }

    // stacks and slices for one tile
    int stacksForOne = stacks/separation;
    int slicesForOne = slices/separation;

    // degrees for one stack (slice)
    qreal oneStackDegrees = (maxLat - minLat)/(qreal)stacksForOne;
    qreal oneSliceDegrees = (maxLon - minLon)/(qreal)slicesForOne;

    qreal curSphereLat, curSphereLatNext, curSphereLon;

    QVector3D curDecart;
    QVector3D curDecartNext;

    QGLBuilder tempBuilder;
    for (qreal curMerLat = maxLat; curMerLat >= (minLat+0.2); curMerLat-=oneStackDegrees) {
        qreal curMerLatNext = curMerLat - oneStackDegrees;
        QGeometryData prim;

        double yTexCoord;
        double yTexCoordNext;
        double xTexCoord;
        double xTexCoordNext;

        prim.clear();
        for (qreal curMerLon = minLon; curMerLon <= maxLon; curMerLon += oneSliceDegrees)
        {
            int signLat = (curMerLat >= 0)?1:-1;
            int signLatNext = (curMerLatNext >= 0)?1:-1;

            // перевод текущих широт в сферическую проекцию
            curSphereLat = Mercator2SphereAnalytic(qAbs(curMerLat)/90.0)*signLat*90;
            curSphereLatNext = Mercator2SphereAnalytic(qAbs(curMerLatNext)/90.0)*signLatNext*90;

            // широты не изменяются
            curSphereLon = curMerLon;

            // перевод из lat и lon в декартовые (h = 0)
            curDecart = llh2xyz(curSphereLat, curSphereLon);
            curDecartNext = llh2xyz(curSphereLatNext, curSphereLon);

            prim.appendVertex(curDecart);
            prim.appendNormal(curDecart);
            xTexCoord = (curSphereLon - minSphereLon)/(maxSphereLon - minSphereLon);
            yTexCoord = (curSphereLat/90.0 - minSphereLat)/(maxSphereLat - minSphereLat);
            prim.appendTexCoord(QVector2D(xTexCoord, yTexCoord));

            prim.appendVertex(curDecartNext);
            prim.appendNormal(curDecartNext);
            xTexCoordNext = (curSphereLon - minSphereLon)/(maxSphereLon - minSphereLon);
            yTexCoordNext = (curSphereLatNext/90.0 - minSphereLat)/(maxSphereLat - minSphereLat);
            prim.appendTexCoord(QVector2D(xTexCoordNext, yTexCoordNext));
        }

        tempBuilder.addQuadStrip(prim);
    }
.....
//проверяется существование текстуры (тайла), если нужно скачивается и применяется.
.....
}

После этого всё равно накладывается в меркаторе. Подскажите, что не правильно? Или как правильно?=)
Записан
spirits25
Гость
« Ответ #13 : Март 13, 2013, 15:37 »

Кажется понял. При указании текстурной координаты нужно брать меркаторовскую координату, так как текстура в меркаторовской проекции. И накладывать её на вертекс (точку сферы) в декартовой проекции, которая получена из сферической. Но так африка выглядит нормально, а вот европа сужена по вертикали, антарктида всё равно нереально здоровая..
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Март 13, 2013, 16:06 »

Насколько я понял по приведенному коду Вы хотите наложить меркаторскую текстуру (тайл) на часть сферы (как бы суб-модель) которую сами же и строите. При этом UV должны быть от 0 до 1 (в рамках этой части). Верно?
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.147 секунд. Запросов: 23.