У нас в 2ГИС давно проходят эксперименты, связанные с рельефом. Мы это делаем не только для того, чтобы получить красивую завораживающую картинку, но и чтобы дать возможность пользователям глубже погружаться в окружающую среду, лучше ориентироваться на местности и принимать решения, от которых зависит качество прогулки или путешествия, комфорт и экономия времени и средств.

Например:

  • выбор горного маршрута для хайкинга или велопрогулки с заранее известными сложными участками;

  • выбор оптимального маршрута для грузового транспорта, чтобы избежать больших перепадов высот для экономии топлива;

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

Предыдущий подход к реализации рельефа

В веб-версии рельеф появился примерно в 2022 году. Это был первый эксперимент и опыт по доставке фичи такого вида на бой. В нём мы использовали регулярный меш на каждый тайл текущего зума. Пиксели тайлов рельефа были достаточно крупными для детальных масштабов — зачастую 120 метров, что соответствует реальной точности спутниковых снимков.

Поскольку значения высот считывались из центра пикселя, то за счёт интерполяции рельеф сглаживался между ними. На картинке ниже вы можете увидеть, как это происходило.

Данный подход имел следующие проблемы:

  • терялось ощущение выраженности гор из-за их превращения в большие холмы.

  • из-за низкой точнос��и отсутствовали мелкие формы рельефа: объекты были просто посажены на высоту в конкретной точке и никак не взаимодействовали с ним.

  • объекты дорожной инфраструктуры были просто «размазаны» по рельефу;

Всё это делало рельеф лишь примерной картиной того, что было в реальной жизни. И перед нами встала задача исправить все эти недостатки.

Новый подход к реализации рельефа

Переход на нерегулярный меш

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

Чтобы избежать этого, мы воспользовались алгоритмом генерации нерегулярного меша — RTIN (Right-Triangulated Irregular Network), который позволяет увеличить количество треугольников в тех местах, где рельеф детальный, и уменьшить там, где он однородный. Более подробно вы сможете узнать об алгоритме, прочитав статью.

Простыми словами весь процесс можно описать так:

  1. У нас есть некоторая территория (тайл определённого уровня зума), например, район железнодорожного вокзала «Роза Хутор».

  2. Также у нас есть карта высот (растровое изображение) рельефа для этого тайла, на которой тёмным цветом выделены низины, а светлым — возвышенности.

  3. На основе растрового изображения строится RTIN, который для данного случая будет иметь вид, как на картинке ниже. Можно заметить, что области с меньшим перепадом высот имеют более крупные треугольники.

  4. Отобразив полученный меш в трёхмерном виде, увидим следующий результат.

Уже можно заметить, как преобразилась форма рельефа по сравнению с предыдущей реализацией. Но мы хотели добиться большей реалистичности: дороги без поперечного уклона, ровный фундамент под зданиями и моделями. Было очевидно, что эти объекты должны участвовать в формировании меша. Так давайте добавим их!

Именно так мы формируем набор ограничителей (constraints) для дальнейшей триангуляции по алгоритму Делоне (CDT). Важно заметить, что ограничители не должны пересекаться, т.к. это приведёт к ошибкам при триангуляции, и мы получим выпадающие из меша треугольники. Также для того, чтобы воссоздать форму рельефа для рукотворных объектов, мы строим буфер вокруг дорог, моделей и зданий, который также участвует в триангуляции.

С таким подходом дороги приобретают более естественную форму:

А у зданий появляется основание:

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

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

А вот такой результат мы получили на обзорных (малых) зумах по сравнению с предыдущей реализацией:

На данном этапе может показаться, что мы достигли нужного результата — наш рельеф стал более выраженным, появились мелкие его формы и даже объекты влияют на него, но без подводных камней не обходится ни один план, а тем более разработка фичи. Далее я расскажу про некоторые из них.

Исправление артефактов исходных данных

Ранее наша команда выпустила статью на тему хилшейда, и вы уже можете знать, что мы используем данные из открытого источника — Японского агентства аэрокосмических исследований (JAXA).

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

Например, так выглядит цифровая модель местности в районе стадиона «Лужники» и Воробьевых гор.

Можно заметить очертание зданий и даже кварталов, а стадион превратился в большую гору, при этом есть и истинный рельеф у Воробьевых гор. Очевидно, что использовав такие данные, мы получим картину далекую от реальности. Например, вот так выглядел бы Комсомольский проспект в Москве.

Подобная картина далека от реальной. Всё это — артефакты от домов, расположенных вдоль дороги.

А вот так выглядит район поселка Сириус и аэропорта в Сочи в данных со спутника:

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

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

Теперь район стадиона Лужников в Москве выглядит так:

А вот побережье Сочи в окрестностях аэропорта:

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

На карте упомянутые выше места после исправления исходных данных выглядят теперь так:

Виртуальная ось для мостов и развязок

На нашей карте есть объекты, которые не зависят от формы рельефа, поскольку они расположены на высоте. К ним относятся различные дорожные развязки, мосты, путепроводы, тоннели и подобное. Единственные точки, которые опираются на высоты рельефа — это въезды на развязки и в тоннели, поэтому перед нами стояла задача придумать механизм, который позволил бы выправить их геометрии над рельефом.

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

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

Суть подхода выглядит так:

И вот такой результат мы получили:

Проработка 3D-моделей

Постепенно мы стараемся заменять скучные коробки зданий на карте реалистичными узнаваемыми моделями — знаковыми сооружениями, памятниками и историческими зданиями. С рельефом здесь появляется отдельная проблема: невозможно изменить геометрию модели без её искажения. У неё есть неоднородная текстура, и любая манипуляция с вершинами сразу будет заметна, в отличие от коробок зданий, имеющих сплошной цвет заливки стен и крыш.

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

Из-за большого количества особенностей у моделей было очевидно, что каким-то одним механизмом взаимодействия модели и рельефа нам не обойтись, поэтому мы разработали целых четыре варианта:

  1. Высота для модели берётся из географических координат модели. Это самый тривиальный случай для самых простых моделей, когда они размещаются на заранее подготовленное для них основание.

  2. Изгибание по рельефу. Подходит для больших по площади и одновременно невысоких моделей и пологого рельефа, поскольку возможные искажения незаметны. Вот пример концертного зала в парке «Зарядье»:

    И если мы искусственно исказим рельеф, увеличив его в 4 раза, то итоговый визуал останется приемлемым.

  3. Смещение точки получения высоты для модели. Используется в случаях, когда мы не можем полагаться на географическую привязку модели (обычно это центроид), например, когда нам нужно выравнивать по высоте рядом стоящие модели. Зачастую такая необходимость возникает у башен и стен кремля, поскольку стена примыкает к башне к её стенке, а не центру. Благодаря этому не видно зазоров и расхождений — это подтверждает одна из башен Казанского кремля.

  4. Интерполяция высоты между двумя точками. Используется только для стен, когда можно исказить модель по высоте вдоль, но не поперёк.

Все подходы можно комбинировать. Например, одна из самых сложных моделей для размещения на рельефе был трамплинный комплекс «Русские горки» на Красной поляне.

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

Что дальше

В статье я рассказал лишь о небольшой части процесса подготовки данных и о наиболее интересных проблемах, с которыми нам пришлось столкнуться. Была проделана огромная работа, в которой участвовало несколько команд, и поверьте, нам есть о чём ещё рассказать про доставку рельефа.

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

Чтобы включить рельеф, нужно нажать на кнопку на главном экране. Второй способ включить новую возможность — через настройки в мобильном приложении: Карта →Рельеф и высотность
Чтобы включить рельеф, нужно нажать на кнопку на главном экране. Второй способ включить новую возможность — через настройки в мобильном приложении: Карта →Рельеф и высотность