Initial commit: browser OSM city generator

This commit is contained in:
mrleo1nid committed 2026-10-30 18:10:47 +03:00
commit 2d4bad0dc7
32 files changed
+5915

No files matched your search

+96
View File
@@ -0,0 +1,96 @@
# Город сверху — генератор карты по OpenStreetMap (MVP)
Выделяете на карте небольшой город или район → по данным OSM строится подробная карта
с видом строго сверху: дороги реальной ширины с тротуарами и разметкой, парковки
с машинами, деревья, и **у каждого здания — этажи, комнаты, двери, окна, лестницы
и мебель**, нарисованные простыми геометрическими фигурами, как на плане квартиры.
Всё работает в браузере, без сервера: данные берутся из Overpass API, генерация
идёт в Web Worker'ах, готовый мир сохраняется в IndexedDB.
## Запуск
Нужен Node.js 18+.
```bash
npm install
npm run dev # http://localhost:5173/ (пересборка на лету)
npm run build # сборка в dist/ — можно положить на любой статический хостинг
npm run typecheck
```
Без интернета можно проверить на образце: «Другие способы» → «Сгенерировать из выгрузки
Overpass» → `samples/balzers-2013.json` (Бальцерс, Лихтенштейн, данные OSM 2013 года).
Генерация из файла без браузера (для отладки генератора):
```bash
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 по их [правилам использования](https://operations.osmfoundation.org/policies/tiles/);
поиск — Nominatim (не чаще раза в секунду).
Идеи частично подсказаны проектом [KnoxMap](https://github.com/spytheeuclidean-a11y/knoxmap);
код написан с нуля.