Как ЛУН совершенствует карту новостроек: технический путь к 3D-моделям и AR
Всем привет! Я Тарас, Front-end developer в ЛУН. С первого своего дня в компании я выбрал работу над картой новостроек. В этой статье я расскажу о том, как от самой простой 2D-карты мы пришли к трехмерным моделям на основе видео с дронов.
Выбор карты неслучаен: это самая интерактивная часть продукта, а значит, наибольшее поле для технического усовершенствования. С продуктовой точки зрения при выборе ЖК карта играет далеко не последнюю роль и лучше всего отвечает на вопрос, где же будет находиться квартира, в которой я буду жить (или выгодно сдавать:)).
Карта 1.0. Пины, полигоны, тормоза
Два года назад наша карта представляла собой Google Maps, пины по координатам ЖК и полигоны (территория ЖК), которые мы наносили с помощью Кадастровой карты.
Версия карты всех новостроек, 2017
Изначально у нас были две проблемы и одна мечта.
Первая проблема — мы не могли быстро отобразить несколько тысяч ЖК Украины на Google Maps. Данные, которые надо было передать клиенту (id + геометрия) для пинов и полигонов, занимали ~10 МВ. Это стало причиной деления карты по городам: «Новостройки Киева», «Новостройки Харькова» и т. д.
Вторая проблема — карта была похожа на одинокого новогоднего зайчика Roshen, которого никто не купил и который до марта лежит на прилавке. Скорость рендера, инерция при drag and drop, плавность zoom — все хотелось сделать круче.
И мечта — как-то отрисовать дома будущего ЖК в 3D. Так, чтобы застройщик еще только поставил забор, показал генплан, а у нас на карте уже есть этот ЖК в 3D.
Карта 2.0. Тысяча и одна новостройка сразу
Начали с проблем. Решить задачу передачи большого объема данных на Front-end можно было с помощью кластеризации. Но кластеризация как способ визуализации данных нам сразу не понравилась, да и с технической стороны это некое поражение: дружок, мы не смогли показать все пины на карте, поэтому держи пока 50 в кружочке и увеличивай карту дальше.
Кластеризация работает быстро, но это неспортивно :)
Изначально показать все и сразу нам помог KML (Keyhole Markup Language). Разбираться с KML нескучно: отдаем KML-файл, а в ответ — ничего. Никаких ошибок от Google Maps, работающий валидатор KML тоже нашли, но почти всегда решает простая валидация на XML. Получилось вот так:
KLM неплох, но эффект испорчен задержками
Круто, ЖК по всей Украине теперь отдаются тайлами. Объем передачи данных минимален — несколько png-картинок. Однако мерцание слоя с данными, пока не будет закеширован каждый зум, конечно, бесит. Немного меньше бесит замыленность пинов: в KML нельзя применить стандартный прием со сжатием картинки в 2 раза.
В поисках улучшений периодически читали документацию по API и SO, как-то даже нашли рабочий пример 3D-дома на Google Maps (примера больше нет, но статья жива). Тогда же и вышли на Mapbox.
Попробовав сервис от Mapbox, как альтернативу Google Maps, мы поняли, что есть смысл оставить клиентскую часть на mapbox-gl-js, а остальное — self-hosted. Для компании, сравнимой с ЛУН по трафику, экономия составляет около $100 000 в год. Экспериментировали с Mapbox по-разному, в итоге вот на чем остановились:
- Подняли в UA-IX tile server на базе nginx для подложки карты.
- Создали свой стиль.
- Включили сжатие nginx + brotli.
Это не только дало нам финансовую выгоду, но и увеличило скорость отдачи тайлов в Украине. Для динамических данных (точки, контуры) у нас подход немного иной:
- Раз в 30 минут с MySQL генерируем GeoJSON.
- GeoJSON упаковываем в mbtiles.
- mbtiles раздается тайлами с помощью tileserver-gl.
В будущем есть желание и здесь уйти от tileserver-gl и делать нарезку сразу же после выгрузки из базы. Результат удовлетворил наши ожидания:
1000 точек без тормозов!
C переходом от тайлов Mapbox к self-hosted мы также решили проблему длительной модерации и обновления данных из Open Street Map. Например, чтобы убрать на карте надпись «тут цигани», у нас уходило несколько месяцев на переписку с Mapbox Support.
Остались задачи модерации (зашквар OSM с картой Крыма не особо актуален, так как мы удалили все ЖК полуострова) и вандализма в OSM, которым в Mapbox, скорее всего, уделяется огромное внимание.
Карта 2.1. Контуры домов на карте
Хорошо выводить на карту, когда есть что выводить. К сожалению, наша страна все еще не opendata friendly, и для нанесения контуров всех домов на карту пришлось потратить год работы команды контента. Примечательно, что у нас генеральные планы с расстановкой всех домов появлялись раньше, чем у некоторых застройщиков:
Контуры всех домов и секций новостроек Украины на карте. Год жизни команды контента
Карта 3.0. Теперь в 3D!
Переход на Mapbox не только помог нам сделать более приятными в использовании уже существующие наработки (не говоря уж о том, насколько расширил наши знания о картах в целом), но и стал площадкой для осуществления давних желаний. Для 3D-домов у нас не было контуров, однако для некоторых ЖК нашлись в базе контуры секций (остались от размещения плана этажа на карте), которые в итоге оказались более удобными при отрисовке дома из-за возможной разности этажности в многосекционном доме. Умножив этажность секции на 3 метра и применив fill-extrusion, мы получаем 3D-дома на генплане:
Еще не построенный Unit.Home теперь в 3D согласно официальному генплану
Paint, render, фильтрация, анимации — все реализовано хорошо. На карту стало приятно заходить не только потому, что вот-вот надо инвестировать, но и просто вместо Facebook — полистать, узнать, что там новенького, не покраснели ли случайно дома корпорации «Укрбуд». Красным цветом мы начали кодировать замороженные и проблемные стройки.
Карта 4.0. Реконструкция настоящего
Первое знакомство с 3D-реконструкцией у нас произошло на совершенно другой задаче. В ЛУН-поиске (сейчас Flatfy), где пользователям предоставляется информация об уже готовых квартирах на вторичном рынке, мы различными способами решали задачу обогащения контента. Однажды пришла идея создать простую 3D-реконструкцию квартиры из имеющихся в объявлении фотографий интерьера и вспомогательной картинки планировки.
Мы были базово знакомы с OpenMVG и в целом с подходом Structure from Motion. Намного больше экспертизы у нас накопилось в обработке изображений, в частности для задачи дедупликации фоток. В совокупности это дало нам понимание, что сначала надо построить point cloud.
Сделав несколько десятков снимков кабинета, мы впервые запустили pipeline-реконструкции. Результат был невпечатляющим:
3D-реконструкция кабинета AI/ML-разработки ЛУН
Спустя две недели прототипирования у нас получилось более качественно:
3D-реконструкция переговорки ЛУН из сотни фотографий
Но даже для такого результата требовалось больше сотни снимков (или видео) помещения и часы обработки.
Пару лет назад мы начали облетать дронами новостройки для «Аэрооблетов 360». Как результат, для большинства новостроек было видео с дрона в 4К. Начали экспериментировать с подходом Structure from Motion, в этот раз использовали по назначению. В результате удалось получить point cloud, а затем и mesh практически фотографического качества:
Mesh 3D-реконструкции с видео аэрооблета дроном, от 200 MB
Размеры моделей были от 200 МВ, что исключало их размещение на карте. Представить дома минимальным количеством полигонов нам помог Mixa Anderson, которого мы нашли по крутым реконструкциям на sketchfab. В процессе используются Metashape, ContextCapture и Meshroom для 3D-реконструкции модели и blender для упрощения геометрии и экспорта результата. Сжав текстуры и конвертировав в glb, мы добились уменьшения модели в ~20 раз.
К этому времени в Mapbox появилась возможность создавать Custom Layer. Для загрузки, камеры и освещения модели выбрали threejs (как альтернативу рассматривали luma.gl от Uber). И вот на карте тот же ЖК Tetris Hall, но уже объемом 2.2 MB:
3D-реконструкция построенного ЖК Tetris Hall на карте ЛУН, 2.2 MB
Так у нас начали появляться реконструкции почти построенных домов. Но на момент окончания строительства ЖК большинство квартир уже продано. Реконструкции явно мало помогают пользователям, которые инвестируют в процессе стройки дома.
Карта 5.0. Реконструкция дизайнерских рендеров
Когда дом в начальной стадии строительства, снимать с дрона нечего. Данных для 3D-реконструкции нет, а хочется наглядно показать, что планируется в финале. В таком случае берем для визуализации модель ЖК. Подключили ребят из FrontVisual, совместно создаем 3D-генпланы для ЖК, например Unit.Home (3.7 MB):
3D-модель строящегося ЖК Unit.Home на карте ЛУН, 3.7 MB
Карта Х. Еще больше 3D
Теперь, собрав оптимизированную реконструкцию или модель ЖК в USDZ, можно отобразить их у себя на столе в AR и скинуть другу через iMessage.
AR-модель ЖК Unit.Home для iPhone, 3.7 MB
Бонусный уровень — Godzilla Mode, когда AR-модель увеличена до роста человека:) Детализации текстуры хватает для просмотра окон в домах комплекса.
Godzilla Mode :)
ToDo: выбор квартиры будущего
После выбора ЖК логичным следующим шагом пользователя будет выбор квартиры. Так как интерактив glb-модели реализовать сложнее (надо создать связь между сущностями в glb и MySQL, поддерживать их актуальность), в качестве baby step мы выбрали построение модели на клиенте. Сейчас наша визуализация квартиры на карте ограничивается зеленым полигоном:
С помощью ребят из vrnet.io и переводом планировок в VR (а сейчас еще и с панорамными окнами ^__^) мы стали получать не только более точные контуры планировок, но и межкомнатные стены. Несложно построить полноценную модель планировки:
Пока есть небольшие проблемы с расхождением площади квартиры по данным застройщика и суммой площади всех полигонов. Да, обводка неидеальна, но есть пара вариантов, как это можно поправить. А растянув планировку, например на 10 этажей, мы уже получаем интерактивный стояк:
Это решение нравится своей масштабируемостью и полным отсутствием ручной работы в построении модели. Как бонус, преобразовав геокоординаты в SVG, мы можем унифицировать весь зоопарк картинок планировок, которые предоставляют застройщики.
Выводы
- Переход к векторным картам добавил к скорости рендера: тайлы зачастую легче, со способностью к overzoom.
- Векторные карты проще кастомизировать. Например, в Mapbox Studio или maputnik.
- Переезд от данных Google к OSM добавил гибкости (проще контрибьютить) и особо не потерял в качестве.
- Поддерживать Google-карту в качестве fallback для тех, у кого не работает WebGL, вышло затратно. Генерируем просто скриншот (placeholder) генплана с помощью Puppeteer.
- Поднять свой tileserver с ходу показалось сложным, но шаг за шагом все сводится к простой раздаче статики через nginx. Тайлы спутника недорого можно взять у HERE.
- Для визуализации большого объема данных лучше использовать тайлы.
- Количество данных, которые хранятся в GeoJSON Feature, сводим к минимуму: меньше вес, меньше потребность в обновлении.
- Рендерить GeoJSON удобно, когда данных мало, а также когда на клиенте нужна точная геометрия (например, продублировать полигон). Из-за того что геометрия одной Feature может быть разрезана между несколькими тайлами, собрать ее обратно сложнее.
- Представление 3D-модели минимальным количеством примитивов (например, одна грань дома — 2 треугольника) дает выигрыш в размере и упрощает AR render.
- Будущее визуализации карт в вебе за mapbox-gl-js.
Работа над картой — еще один маленький шаг, чтобы вывести в онлайн одну из самых дорогих покупок в жизни. Без риелторов, звонков и личных визитов в отдел продаж, где на ранних этапах вам не покажут будущую квартиру, а на момент сдачи дома в популярных ЖК можно купить дороже только то, что никому не надо.
45 коментарів
Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.