Трёхмерные здания в Mapnik

Мало того этой пристройки кафешной в сборке для Garmin нет (см. выше), я всем точкам на пристройках без адресных добавляю адресную инфу, впрочем я ее добавляю на всех POI.

Стоит ли рекомендовать такой способ?
Внимание, много трафа:






http://latlon.org/buildings?zoom=18&lat=53.36143&lon=83.71441&layers=BT
http://www.photosynth.net/view.aspx?cid=a68dfe6e-802a-41f9-b355-761ac727dcc3&m=false&i=0:0:23&c=0.406813:-0.689949:0.0322088&z=447.46204697997&d=4.23216022839935:-1.43647672572073:-2.02462224829947&p=0:0&t=False

Разве лицензия фотосинта разрешает так использовать полученные данные (облако точек)?

Думаете, почему с бандлером возятся…

кхм…
http://osm.kosmosnimki.ru/buildings/18/192031/84954.png?1300331005141
The requested URL /buildings/18/192030/84954.png was not found on this server.

у меня открыло

Два НО по этому зданию:

  • все отмеченные объекты являются building:part, а не building ;
  • высота колокольни и основной части 33 и 27 метров (плюс-минус 2), а не 15 и 13

Уж сколько раз твердили миру, что не нужно затачивать данные под интерпретатор (рендер), а все туда же, даже совместимость с легаси предлагаете.

Возможно я где-то ошибаюсь или изобретаю велосипед, но английскую часть форумов про 3D я пока не осилил, думаю к ней вернуться чуточку позже, поэтому сразу извиняюсь за возможные грубые ошибки.

Хочу сказать, что с 2D-рендерингом у меня было возни было гораздо больше, нежели с 3D, ибо рисовать надо было все в реалтайме. Если создавать кучу part-объектов, то конвертор офигеет от такой радости и нужно будет изобретать костыли, дабы все это вместе склеить. Костыли вида “если объекты достаточно близко или имеют адрес - используем сложение полигонов и замазываем дырки”. Делать такое и сложно, да и толку нет, от глюков все равно не уйти. Я даже для низших уровней переделывал домики в линии, дабы на телефоне проще рисовать было. Помните, что есть масса девайсов, которые просто не потянут кучу мелких кубиков, а пост-процессить с угадыванием чего же там было - сложно.

Зато я бы хотел иметь на 2D-рендерере все башни, пристройки и шпили, здесь дело даже не в красоте, это поможет мне знать, где можно побыстрее срезать путь и где лучше пройти. Рендерить это можно как полутонами, отображающими высоту, вспомогательными надписями, да хоть тенями, в результате получаем качественную и информативную 2D-картинку. Для этого нужно иметь средство для описания одного объекта, но с несколько большей детализацией, проставлять этажи отдельным частям и не только. Я сейчас не говорю про 3D вообще. Вот к примеру, больница: http://www.openstreetmap.org/?lat=54.190446&lon=45.186219&zoom=18&layers=M - фактически это не 2 здания, а 1, но южная часть имеет 3 этажа, северная 4 этажа и немного шире, хотя западная стена у обоих “зданий” выстроена в 1 линию, между ними переход метра 3-4, высотой в 2 (или 3?) этажа (т.е. с уровня земли это 1 здание), главный вход расположен почти на границе пересечения. Что здесь будет “пристройкой”? Как эту “пристройку” правильнее рисовать? И если объявлять войну нарисованным пристройкам, не пропадет ли половина больницы? А если рисовать как одним полигоном, то сколько ставить этажей? Я не хочу ставить ни 3, ни 4. Свое предложение я опишу чуточку ниже.

Теперь о 3D:

Соглашусь с идеей, что доминантные строения будут ориентирами, а следовательно наиболее приоритетны и должны как можно точнее передавать свой облик. Но в этом случае можно дойти до памятников / разных фонтанов / особых деревьев / телеэкранов, которые могут быть ориентирами - как тут быть? Порой у них не менее причудливая форма, я думаю стоит учесть и их. Причем как тут заметили, 98000 полигонов на здание - это вовсе не плохо, все зависит от платформы, где потом эта моделька будет использована, LOD-ы никто не отменял, отсечения тоже, зато можно будет рассматривать каждый балкон. Если этого хочет пользователь. Да, не вижу ничего страшного в балконах, сделанных building=yes / minheigth=30m / height=31m, такое можно автоматически детектить и аккуратно переносить в модельку. Возможны глюки с “угадыванием”, но вреда от таких объектов не так уж и много, гораздо меньше, чем от кучи пристроек.

Почему-то никто не написал о замечательном теге, описанном в вики building:shape - Approximate shape of the building (pyramid, tower, dome), я предлагаю чуточку расширить идею. Дать ссылку на dae/obj всегда можно, а дальше играть с полигонами не везде можно, да и вырисовывать модельки люди не захотят. Давать ссылки на дома из 10 сегментов? Тоже некрасиво, мало кто захочет переключаться в отдельный редактор, дабы нарисовать там несколько кубиков, да к тому же это замусорит уже 3D-базу. Поэтому я предлагаю развить building:shape - Approximate shape of the building (pyramid, tower, dome). Фактически это параметрическое описание. Вспомним основные методы 3D-моделирования:

Extrude - рисуем шейп и вытягиваем его. Собственно, как рендерер Котяры и работает.

Chamfer - аналогично, но масштаб шейпа можно менять (да и вообще позиции вертексов), идеально для простых башен и скошенных крыш.

Loft - чуть более продвинутый вариант: рисуется шейп (набор шейпов) и основа, вдоль которых их можно вытягивать. Останкинскую башню можно реализовать как вертикальный шейп-основу и набор шейпов-этажей (произвольной формы, между этажами интерполяция). Здания вида http://www.almerenjoy.nl/silverline1_h350.jpg можно представить как прямоугольник, натянутый на изогнутую основу. Сильным недостатком такого метода является то, что стержневому шейпу нужна высота.

Lathe - опять используется стержневой шейп, только вдоль него ничего не вытягивается, а он сам вращается, образуя меш: http://www.republicofcode.com/tutorials/3ds/spline_lathe_stealth/ - таким методом можно моделировать различные круглые объекты, такие как рюмки или купола церквей, стадионы и промышленные сооружения. Недостаток - это опять то, что шейп рисуется в высоту.

Сплайновый - он же предложенный метод “стенок”, когда описываются стены (преграды), каждая на своем уровне, а потом из этого аппроксимируется меш.

Library - библиотеки готовых объектов, такие как крыши, тег building:roof:shape уже есть и хорошо описан. Такие теги как building:roof:ridge / building:roof:extent напоминают нам, что библиотечный объект может быть параметрическим.

Boolean - сложение и вычитание объектов. Позволяет склеить все вышеперечисленное, или наоборот, нарезать дырочек разных форм в других формах.

Есть множество других методов моделирования, но у нас не 3D-редактор, думаю этого будет достаточно. Что же со всем этим делать? Я предлагаю что-то вроде такого, на примере больницы:

building:level:0=shapeID1 (шейп по фундаменту)
building:level:0:height=3m (опционально)
building:level:1=shapeID1 (опционально)
building:level:2=shapeID1 (опционально)
building:level:3=shapeID2 (шейп южной части)
building:approx3d=custom,shapeID1(pos=onGroundLevel):extrude(level=3),shapeID2(pos=onCurrentMaxHeight):extrude(level=1):boolean(op=join,solid=true,with=all)

Что мы получаем:

  1. получаем единое здание, которое можем рендерить как угодно и нам не надо собирать кусочки
  2. получаем точное количество этажей, возможность адресации в офисных зданиях (для оверлеев вроде 2гис)
  3. получаем возможность развития building:levelPlan, для проекта который я делал раньше это было важно
  4. можем пилить внешний вид “под рендер” для неугомонных, ибо заставлять людей нет смысла, надо направлять.
  5. данные параметрические, весят почти ничего, для КАРТО-рендера их более чем достаточно
  6. можно заливать модельки (building:model - URL of 3D model of the building) хоть со 100к полигонов, ничего страшного не будет, дальше все на совести пользователя рендерера
  7. нет необходимости использовать внешние ресурсы, которые могут быть недоступны (картинки из этого треда местами прокисли уже)
  8. нет необходимости использовать внешнее ПО для описания строения

Конечно же, это только набросок, на синтаксис не смотреть, а вот мнения услышать быть хотелось.


Я вроде бы изобретал самые разные костыли, но до такого не доходил.
Гугль использует Collada, из нее все великолепно импортируется куда угодно.
Если нужны костыли и имена текстур - считай мд5 от них и находи в итоговом экспорте, найти копию картинки всегда сможешь.

текущими средствами OSM? Или вообще? Если вообще, то как же тогда быть с корректностью данных?

Не согласен на счет рендерера. Да и рендерер может быть разным, например, голосовым для слабовидящих людей.

Такие вещи в первую очередь нужны для точной адресации, дабы можно было точно и сразу идентифицировать любую дверь на фасаде, любую фирму в офисном здании, а если у нас есть “здание”, то достаточно сложно понять, где же таки находится искомое. Вот ищу я фирму “рога и копыта”, вижу ее в навигаторе, вижу, что она расположена в здании, которое занимает целый квартал. Куда мне идти? Куда прокладывать роутинг? Ну в режиме автомобиля понятно - до парковки (парковка при этом должна иметь семантическую связь со зданием), а куда роутить человека?

Saransk, это уже лучше, в том смысле что позволяет забить на 3д тем, кому оно не интересно.
Но всё-таки делать адресацию через 3д-модель - это имхо лишнее. Лучше уж подъезды обозначить.

Дело за малым: нужны прототипы редактора и визуализатора для этого языка :slight_smile:
И да, в тег влезает всего 256 байт

А кто сказал, что адресация будет в модельке? Моделька где-то далеко, по ссылке, у нас же только писание здания, которое не имеет к рендеру никакого отношения. Для рендерера у нас есть аппроксимация того, что ему можно нарисовать, причем только если это 3д-рендерер.

Язык можно подсмотреть в готовых визуализаторах, скажем http://www.povray.org/documentation/view/3.6.1/273/
Редактор для параметрических вещей - текстовый. Гуй если и делать, то тоже текстовый с кучей попапов, а это долго.
Визуализатор - можно набросать скриптик для того же povray или блендера.
Основная проблема - это собственно изобрести метод разметки, необходимый для “микромоделей”, а учитывая специфику - сделать модельки параметрическими, дабы можно было их использовать несколько раз. Правда тут можно случайно изобрести CityEngine.

256 байт при компактной записи хватит на 5-10 команд, вполне достаточно для аппроксимации. Если нужно точнее - это уже моделька и ее лоды.

Ух ты, нечто новенькое. Правда пример я не очень понял. Может в JOSM оттежите больницу и сохраните отдельную xml и запостите на форум или в вики?

Потому как непонятно следующее:

Я так понял здание рисуется 1 полигоном по фундаменту, если так то кто такой shapeID1? Это id полигона в osm нужной формы или это название некоторой общей формы допускающей параметризацию

Кто такой shapeID2 и как будет описываться что он не на весь этаж? Если это ссылка на полигон в osm то понятно, а если некоторое формальное описание формы - то не понятно как указать что оно не на все здание

Пока я сам не уверен, как это сделать лучше :]
Сделаю позже, когда придумаю.

Ну я же подписал, что:
shapeID1 - полигон по фундаменту (в самом осм)
shapeID2 - полигон с формой северной части, того 4 этажа, который выступает. Описывается на весь этаж, ссылка в массиве levels

Т.е. отрисовываем только сам фундамент и выступающую часть (четвертый этаж северной части). Все.

Тут надо покопаться на буржуйских частях, посмотреть на возможные реализации.

Получается, нарезаем домик на части по этажам. В принципе я не против, для зданий это вполне логично +удобно размечать этажи.

Как будет выглядеть к примеру Lathe (На примере останкинской башни)?
Тут просто есть опасность: отрисовали вы ось вращения и профиль, “положили” их рядышком.

  1. Многие будут кривить лицо - что это тут дескать за непонятные веи лежат.
  2. При неудачном стечении обстоятельств есть шанс обрезать профиль и/или ось при нарезке данных. Вероятность такого события конечно крайне мала, но пожалуй она есть.

256 байт - можно заюзать стековую запись операндов, ка в post script

1233455 shp 0 30 extrude 65443321 shp 30 10 extrude boolAdd m units

1233455 shp – загрузить шейп 1233455
1233455 shp 0 30 extrude – выдавить его от уровня 0 на 30 единиц
65443321 shp – загрузить шейп 65443321
65443321 shp 30 10 extrude – выдавить его от 30 на 10
//теперь в стеке 2 объекта
1233455 shp 0 30 extrude 65443321 shp 30 10 extrude boolAdd – объединили 2 куска в 1
… m units задали тому что объекдинили единицы измерения - метры (по сути scale)

Если для команд использовать сокращения - можно записать очень компактно. Но у многих такая форма записи вызывает острое FUUUUUUUUU!!!

Вообще, не обязательно по этажам, поэтажная разметка несколько проще в данном случае. Например, если надо сделать в доме арку - рисовать 2 полигона для первого этажа? Согласись, это не слишком удобно. Зато можно взять заготовку для арок и вырезать дырку в доме по ее форме.

Вот это главная проблема OSM 3D, что высотных данных в нем нет. Нет вообще.
Имеющийся Levels скорее представляет из себя справочные данные (общая этажность), польза от таких сведений примерно как от года постройки или фамилии архитектора.
Есть ele, но его нельзя навешивать на произвольные ноды, да и сложно вычислять высоту над уровнем моря, нам скорее нужна высота над локальной поверхностью. Остается изобретать костыли. В этом плане создание тега:
my3dcustomshape=123 345 567 67 23 456 2398 398273 22693 239048 2282 34028 938
не будет выглядеть чем-то странным.

Можно говорить о загрязнении базы, ибо такие объекты в ней явно лишние. С другой стороны, You can use any tags you like as long as the values are verifiable, а данные наши не с потолка, пусть они не имеют такой точности, какую можно получить с лазерным сканером, но вполне верифицируемы.

В конечном итоге есть же широкие дороги, которые отрисованы 2-3 нодами, а места занимают гораздо больше, нежели прилегающие дома. Опять получается, что данные используются не по назначению (ноды фактически не содержат в себе признаков объекта, а только общее значение “тут у нас дорога”).

Еще момент: если нет высоты, то непонятно что и рисовать: может быть фундамент, может быть проекцию, а может быть поэтажный план. Есть множество случаев, когда это все будет одним, а есть множество случаев, когда нет.

Вот я сейчас изучаю форумы буржуев и чото мне уныло от всего этого :frowning:

Очень хорошая идея, я бы до нее не додумался! Я предлагаю добавить сюда регистр SP как минимум и можно несколько общих регистров, дабы можно было вернуться к произвольной части стека и что-то там сделать. Или подцепить внешние данные, скажем положение и ориентация библиотечного объекта (арки), с которой будем комбинировать наш объект. В итоге не надо указывать “place on = object”, только выравнивание, выражения просты, прозрачны, синтаксис тоже нормальный, все красиво и удобно. Я бы начал сочинять пропозал :wink:

SP - self pointer или что то другое?

Если self то простой случай остается простым (и это главное!)
sp shp 0 30 extrude - вытяни меня на 30 метров.

С арками была следующая мысль: обращаться к внешнему хранилищу за моделькой арки - неохота, тогда уж и целиком домик загрузить зарисовать можно. Хотелось бы loft вдоль дороги которая идет в арке, только параметрический. Что то типа:
sp shp 0 30 extrude 3 5 round_ark_shp 123123 shp loft boolSub

3 5 round_ark_shp - генератор шейпа для арки со скругленной крышей 3 - ширина 5 высота. И получаем шейп для арки с уже указанной базовой точкой

Есть правда еще одно но по поводу такой записи - не очень красиво добавляются опциональные параметры, надо либо какой то маркер вводить конец_набора_аргументов либо элиасы для команд с различным количеством опреандов использовать. Правда для штук типа
my3dcustomshape=123 345 567 67 23 456 2398 398273 22693 239048 2282 34028 938
такой маркер всеравно понадобиться.

Завел болванку на вики http://wiki.openstreetmap.org/wiki/3dapproximation

SP - stack pointer, дабы можно было обращаться к произвольному элементу
я не призываю сюда копировать архитектуру процессоров, просто у нас все больше ассемблер получается :slight_smile:

Насчет Loft - это достаточно затратная операция, арку можно нарисовать и экструдом, если за основу вертикальный шейп взять. Но вертикально мы рисовать не можем, у нас нет средств, можно рисовать горизонтально и поворачивать, то это порушит семантику. Рисовать в горизонтальном разделении, т.е. сначала опоры, а потом остальное - неудобно. Поэтому буль будет самым простым

load shape1
extrude 30
loadlib arc982 10 20 (параметрический объект из библиотеки, НЕ внешнего ресурса)
roadsurf wayID (расположить вдоль улицы, но тут надо бы еще положение задать)
boolsub

или можно иначе:

drawrect 50 30 (создать прямоугольник)
drawarc 25 10
boolsub (вычитаем, получаем шейп в виде прямоугольника с вырезанным кругом)
extrude 30 (вытягиваем результат

Хотя тут можно много вариантов придумать.

Да, удивлен, что никто не сказал про http://wiki.openstreetmap.org/wiki/CityEngine
В соседнем треде про 3D-рендеринг я постил ссылки на демки:
http://www.youtube.com/watch?v=lXVIuoPlMpY - небольшое демо
http://www.youtube.com/watch?v=hP0rI58FVZ8 - пример параметрических улиц

http://forum.openstreetmap.org/viewtopic.php?id=8179

Saransk, за такую цену я пас :slight_smile: 3d рисовалка города…