openstreetmap карты и 3D сфера.

Доброе всем время суток.
Столкнулся с проблемой при использовании карт openstreetmap в своей программе. У меня есть сфера, на которую я накладываю текстуры.
Всё дело в том, что я не могу указать текстурные координаты для квадратной текстуры. Прямоугольная отлично ложится на сферу, а квадратная с искажениями (антарктида раз в 20 по площади больше, чем австралия, африка по ширине больше, чем по высоте).

Может кто-то уже сталкивался с подобным, подскажите как сделать=)

Неплохая статейка http://habrahabr.ru/post/143898/, хоть в ней рассказывается как не просто превратить землю в плоскость. Но думаю должно быть понятно, что в обратную сторону тоже надо с умом сворачивать.

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

Спасибо. Действительно, хорошая статья.

AMDmi3, мысль хорошая, а можете мне дать функцию зависимости для проекции меркатора? я в этом не силён=) или если есть пример?
Спасибо.

могу ещё больше обрадовать. не только вы интересуетесь такими вещами) на гитхабе даже есть исходники веб морды для ОСМ карт

Вы про этот https://github.com/openstreetmap ?
Дело в том, что мне не нужно web или 2D. Мне нужно перенести из проекции меркатора именно на 3D сферу (указывая текстурные координаты).

нет конечно) найду ссылку напишу

сори что прочел не внимательно) мысль ясно. вам нуна на спец форум. где такое обсуждалось и говорилось не раз. возможно кто то и расписал уже
http://gis-lab.info/forum
http://gis-lab.info/

в сторону GDAL утилиты гляньте ещё

Спасибо, посмотрю там. Но и здесь останусь, вдруг кто-то поможет=)


/** Mercator projection */
inline double mercator(double x) {
    return 0.5*log((1.0+sin(x))/(1.0-sin(x)));
}

/** Mercator un-projection */
inline double unmercator(double x) {
    return 2.0*atan(tanh(0.5*x));
}

Для шейдеров, насколько я знаю, намного быстрее будет сделать 1D текстуру реализующую эту функцию, чем считать формулы на GPU влоб (но тут, опять таки, надо быть осторожным с точностью).

Работает всё это так: пусть есть координаты в радианах:

lat ϵ (-π/2, π/2)
lon ϵ (-π, π)

взяв

x = lon
y = mercator(lat)

получим координаты на плоскости:

x ϵ (-π, π)
y ϵ (-∞, ∞)

из-за того что y может получаться большим по модулю, входную широту обычно ограничивают до примерно (-85.05°, 85.05°). Если так сделать, на выходе будет квадрат (-π,-π) - (π, π), который уже можно нормировать как удобно, собственно его вы и видите на openstreetmap.org. Да - полюса туда не попадают, и если этот квадрат натянуть на сферу, на полюсах будут дырки.

Можете ещё глянуть https://github.com/AMDmi3/glosm - там геометрия заданная в lat/lon может сворачиваться как в сферу, так и в меркаторную плоскость (http://glosm.amdmi3.ru/). Правда, без текстурирования.

Это потому, что Вы неправильно считаете текстурные координаты.
Почитайте о проекции Меркатора. Вам нужно просто сделать обратную проекцию.

Это я уже понял. Я не могу найти, как пересчитать из проекции меркатора в сферическую.

./libglosm-server/glosm/geomath.h
./libglosm-client/MercatorProjection.cc
или
./libglosm-client/SphericalProjection.cc ?

Первое - сама математика которую я процитировал выше, второе и третье - собственно реализации проекций [lat lon высота] в [x y z], и MercatorProjection использует те самые функции из geomath.

Я непонятно написал, то что они используют geomath.h я увидел, но что из них? Просто там нет комментариев, а мои скудные знания в этой области мне не помогают=)
чем отличаются mercator и unmercator?
И что мне использовать для пересчёта из меркатора в сферические:
MercatorProjection::ProjectImpl
MercatorProjection::UnProjectImpl
SphericalProjection::ProjectImpl
SphericalProjection::UnProjectImpl ?

Вы уж извините, что я не понимаю в этом, зато может другим не придётся спрашивать, если тоже такой вопрос возникнет=)
Спасибо.

оно? нет? ))

http://www.webglearth.com/#ll=0.00000,0.00000;alt=10000000;h=0.000;t=0.000

тут исходники
https://github.com/webglearth/webglearth

просто картинка)
test

почти, но мне нужно не web=) попробую там поискать формулы перевода, мне большего не нужно=)
Спасибо.

Тогда забудьте про glosm, используйте функции mercator/unmercator. Что делает первая я расписал, а вторая выполняет в точности обратное преобразование.

Вам, по идее, нужно всего лишь в текстурные координаты класть не широту и долготу, а mercator от широты и долготу.

У меня тукстурные координаты по Y задаются в диапазоне от 0 до 1 (радиус сферы равен 1).
Для быстрой проверки переписал функцию меркатор на питоне и получил результаты:

После таких результатов я даже не знаю, что туда передавать, градусы или радианы?

Всем спасибо за помощь, решено тут http://www.prog.org.ru/topic_23408_15.html