Files
citygen/README.md
T

8.0 KiB
Raw Blame History

Город сверху — генератор карты по OpenStreetMap (MVP)

Выделяете на карте небольшой город или район → по данным OSM строится подробная карта с видом строго сверху: дороги реальной ширины с тротуарами и разметкой, парковки с машинами, деревья, и у каждого здания — этажи, комнаты, двери, окна, лестницы и мебель, нарисованные простыми геометрическими фигурами, как на плане квартиры.

Всё работает в браузере, без сервера: данные берутся из Overpass API, генерация идёт в Web Worker'ах, готовый мир сохраняется в IndexedDB.

Запуск

Нужен Node.js 18+.

npm install
npm run dev        # http://localhost:5173/  (пересборка на лету)
npm run build      # сборка в dist/ — можно положить на любой статический хостинг
npm run typecheck

Для автоматических проверок сетевого клиента нужен Node.js 22+: npm test. Тесты проверяют таймауты, переключение серверов и отмену без обращения к сети.

Данные сначала запрашиваются у maps.mail.ru, затем у overpass-api.de и overpass.private.coffee. На каждый запрос отводится 45 секунд, включая загрузку ответа; после ошибки или таймаута используется следующий сервер. Лимит обработки запроса на стороне Overpass — 30 секунд. Кнопка «Отмена» прерывает запрос и ожидание перед повтором.

Без интернета можно проверить на образце: «Другие способы» → «Сгенерировать из выгрузки Overpass» → samples/balzers-2013.json (Бальцерс, Лихтенштейн, данные OSM 2013 года).

Генерация из файла без браузера (для отладки генератора):

npm run cli -- samples/balzers-2013.json 47.058 9.492 47.074 9.518 world.json

Управление

  • перетаскивание — сдвиг, колесо / щипок — масштаб, двойной клик — приблизить;
  • справа — этаж для всей карты (⌂ — крыши), PgUp/PgDn или [ ];
  • клик по зданию — карточка: вид, этажность (из OSM или оценка), квартиры, спальные места, свой переключатель этажей только для этого здания;
  • «Экспорт мира» — весь мир одним файлом .json.gz (будущий формат для игры).

Как устроена генерация

Overpass JSON ─► city.ts ──────────────► зоны, дороги, контуры зданий, деревья, парковки
                   │  classify.ts          вид здания (по тегам, POI внутри, landuse, площади) и этажность
                   ▼
              interior.ts (в воркерах) ─► этажи: сетка 0.5 м в осях здания
                   │  схема: секции с подъездами | коридор | простая раскладка
                   │  деление на комнаты по программе (м²), несколько попыток с оценкой
                   │  двери = остовное дерево по графу смежности, санузлы и спальни — тупики
                   │  вход с фасада к дороге, окна с шагом по типу здания
                   ▼
              furnish.ts + catalog.ts ──► мебель по правилам для каждого типа комнаты
                   ▼
              finalize.ts ──────────────► общие модели предметов, округление до 1 см
  • Сид здания = OSM-id ⊕ сид мира — один и тот же город всегда генерируется одинаково.
  • Многоквартирные дома — секционные: подъезд с лестницей (и лифтом от 5 этажей), площадка, 1–4 квартиры вокруг неё; на первом этаже — проход к входу, у домов с магазинами вместо квартир магазины со своими входами с улицы.
  • Офисы, школы, больницы, гостиницы — коридорная схема.
  • Дома, магазины, кафе, цеха, склады, храмы, гаражи — простая раскладка (у гаражных рядов — отдельные боксы с воротами).

Модель данных мира (src/types.ts)

Заложено под будущую симуляцию:

Что Зачем потом
Door.rooms = [комната, комната | 'outside'] рёбра графа навигации внутри здания
Stairs (одно место на всех этажах, up/down), лифты переходы между этажами
Unit — квартира / магазин / офис с roomIds и beds домохозяйства и рабочие места для жителей
Prop.blocksMove, Prop.blocksSight, tags (sleep:2, sit:4, work, cook, storage…) коллизии, линия обзора, что агент может сделать с предметом
Wall с разрывами под двери и окна, Window коллизии и видимость (окна прозрачны для взгляда)
Road с шириной, тротуарами, oneway, слоями граф улиц для перемещения по городу
все объекты с id хранение состояния: открытая дверь, взятый предмет

Координаты — метры в локальной проекции вокруг центра области (x — восток, y — юг).

Ограничения MVP

  • Область до 6 км². Публичные серверы Overpass рассчитаны на умеренную нагрузку; для публичной игры понадобится своё зеркало или заранее нарезанные данные (например, экстракт Geofabrik → статические файлы).
  • Подвалы, мансарды, балконы, береговая линия морей пока не генерируются.
  • Нестандартные контуры (сильно изломанные) дают менее аккуратные планировки.

Данные и лицензии

Данные карты © участники OpenStreetMap, лицензия ODbL. Если вы распространяете сгенерированные миры, укажите «© OpenStreetMap contributors». Тайлы на экране выбора области — стандартные тайлы OSM по их правилам использования; поиск — Nominatim (не чаще раза в секунду).

Идеи частично подсказаны проектом KnoxMap; код написан с нуля.