Як ЛУН удосконалює карту новобудов: технічний шлях до 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 точок без гальм!
З переходом від тайлів 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 ми вибрали побудову моделі на клієнті. Зараз наша візуалізація квартири на карті обмежується зеленим полігоном:
З перекладом планувань в 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 .
Робота над картою — ще один маленький крок, щоб вивести в онлайн одну з найдорожчих покупок в житті. Без ріелторів, дзвінків і особистих візитів до відділу продажу, де на ранніх етапах вам не покажуть майбутню квартиру, а на момент здачі будинку в популярних РК можна купити дорожче тільки те, що нікому не треба.
Опубліковано: 02/01/20 @ 11:00
Розділ Різне
Рекомендуємо:
Ruby дайджест #34: підсумки року, Ruby 2.7.0, актуальність Ruby on Rails в 2020
Один проект і два PM: можливе ефективне керування
Predictive Software Engineering як шанс для аутсорса підвищити якість послуг
Переїзд до Великобританії. Від студента-футболіста в Києві до Software Developer в Лондоні за 5 років
Здоров'я ІТ-спеціаліста: мігрень, невропатії, тунельний синдром