AAYMA
RU
Войти

Astana City Systems

Городской симулятор Астаны: пользователь выбирает проекты (автобусная полоса, школа, поликлиника, парк) в рамках бюджетного лимита, система…

Рабочий MVP
Команда «AirBenders» 11💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: AirBenders
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Рабочий MVP

Задача кейса: «Аким на 5 часов»: городской симулятор, распределяющий бюджет по 5 направлениям и 5 районам

Суть

Городской симулятор Астаны: пользователь выбирает проекты (автобусная полоса, школа, поликлиника, парк) в рамках бюджетного лимита, система прогоняет транспортную микросимуляцию до/после и показывает эффект на 3D-карте.

Как устроено

FastAPI-сервер скачивает снимок центра Астаны через Overpass, строит сеть через netconvert и запускает два прогона Eclipse SUMO с одинаковым синтетическим спросом и seed (база и проект). Автобусная полоса реализована patch-ем сети, социальные объекты добавляются в пешеходный граф OSM, покрытие считается многоточечным Dijkstra (доля точек в 15 минутах). Бюджет учитывает CAPEX в первый год и ежегодный OPEX, превышение лимита отклоняется. Фронтенд на MapLibre показывает «До/После/Разница», скорости по рёбрам, CO₂ (HBEFA).

Ключевые решения

  • Eclipse SUMO микросимуляция
  • netconvert patch сети
  • OpenStreetMap/Overpass
  • многоточечный Dijkstra
  • 15-минутная доступность
  • CAPEX/OPEX бюджетирование
  • HBEFA CO₂

Особенности

Настоящая транспортная микросимуляция SUMO на реальной OSM-сети Астаны с воспроизводимостью (хеши OSM/сети/спроса, seed) и корректным сравнением только одинаковых завершённых поездок; явно описаны ограничения модели.

Стек

Python · FastAPI · Eclipse SUMO · JavaScript · MapLibre · OpenFreeMap · unittest


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-af6afd4e-airbenders.

README

README.md

Astana City Systems

Локальный рабочий пилот: реальная дорожная геометрия Астаны из OpenStreetMap, два прогона Eclipse SUMO и сравнение сценария на 3D-карте. API-ключи и платные сервисы не нужны.

Запуск на Windows

Нужен Python 3.11+ (проверено на Python 3.13, Windows x64).

.\start.ps1

Или вручную, если PowerShell не разрешает запуск скриптов:

py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe -m server

Открыть http://127.0.0.1:8000. index.html нужно открывать через этот сервер: обычный Live Server не предоставляет расчётное API. Сервер слушает только локальный адрес. Другой порт: python -m server --port 8001.

Установленные SUMO и netconvert входят в пакет eclipse-sumo; ручная установка приложения не нужна. Альтернатива — официальный SUMO в PATH или SUMO_HOME.

На Linux/macOS используются те же зависимости, python3 -m venv .venv и .venv/bin/python -m server (эти платформы здесь не проверялись).

Работа с симулятором

  1. Нажать «Подготовить карту OSM» или сразу «Рассчитать в SUMO». Первый запуск скачает снимок центральной Астаны через Overpass и выполнит netconvert.
  2. Выбрать проекты, годовой учебный лимит и горизонт бюджета. CAPEX оплачивается в первом году, OPEX — ежегодно с года ввода. При превышении лимита сервер отклоняет сценарий.
  3. Задать количество машин, период отправления, интервал условных автобусов и seed.
  4. Запустить расчёт. Один worker последовательно выполняет базовый и проектный прогоны SUMO. Статус виден в интерфейсе; перезагрузка страницы восстанавливает активный или последний завершённый прогон.
  5. Переключать «До / После / Разница» и слои. Нажатие на улицу показывает её скорости; на контрольную точку — время пешком. JSON результата можно скачать справа.

Что действительно считается

  • Транспорт: автомобили и автобусы в SUMO; время поездки, потери времени, задержка выезда, число завершённых поездок, скорости по рёбрам и CO₂ за прогон.
  • Автобусная полоса: правый ряд выбранных многополосных рёбер улицы возле точки проекта резервируется для автобусов через patch сети netconvert. Карта показывает конкретный коридор и результат, который может быть как положительным, так и отрицательным.
  • Школа, поликлиника, парк: добавление объекта в пешеходный граф OSM и многоточечный Dijkstra до ближайшего объекта. Покрытие — доля пространственных контрольных точек в пределах 15 минут. Это не оценка населения или вместимости.
  • Бюджет: CAPEX, ежегодный OPEX, остаток лимита по годам.

Одинаковые O/D-пары, моменты отправления, seed и типы транспорта используются до/после. Пути заново рассчитываются в каждом варианте сети. Средние изменения сравнивают только одни и те же завершённые поездки; число незавершённых всегда возвращается отдельно. Если все машины не успели завершить поездку, результат отмечается как ограниченный. Сценарий без проектов должен давать нулевую разницу.

Ограничения модели

Спрос синтетический, вес дороги при выборе O/D пропорционален её длине. Наблюдаемых потоков, калибровки светофоров, прогрева сети и полноценной OD-матрицы нет. Динамический выбор маршрутов, изменение спроса от новой школы, пассажиропотоки и переход из машины в автобус не моделируются. Автобусная линия и остановки условные; это не GTFS города. CO₂ рассчитывается для заданных классов HBEFA и не является AQI или годовым прогнозом.

Пешеходная сеть учитывает OSM foot/access, но неполные тротуары, входы, ограждения и центроиды объектов ограничивают точность. Учреждения не проверены на фактическую работу; мощности школ/клиник неизвестны. Цены, обслуживание, места проектов и ежегодный лимит — явные учебные допущения. Горизонт меняет бюджет, а не интенсивность трафика по годам.

Снимок — текущая выгрузка OSM с отдельной датой osmTimestamp, не исторический baseline 2024. Исходные API могут быть недоступны: приложение сообщает ошибку, не подменяя OSM выдуманной сетью. После подготовки расчёты используют локальный снимок; карта-подложка всё ещё требует интернет.

Устройство проекта

  • server/app.py — FastAPI, валидация, один фоновый worker, статусы и результаты на диске.
  • server/data.py — Overpass, provenance/хеши, кеш снимка и netconvert.
  • server/simulation.py — одинаковый спрос, автобусная полоса, SUMO subprocess, результаты и GeoJSON.
  • server/accessibility.py — пешеходный граф, Dijkstra и контрольные точки.
  • server/catalog.py — каталог проектов, координаты, цены, OPEX и бюджет по годам.
  • index.html, src/pilot.css, src/logic/pilot-*.js, src/logic/simulation-api.js — подключённый интерфейс.
  • Старые src/logic/app-controller.js и остальные модули прежнего GIS-макета оставлены как исходный прототип, новая страница их не подключает. e-Saulet в рабочем расчёте не используется.

Старый URL /outputs/astana-3d/real-city.html сервер направляет на тот же интерфейс.

Отдельный статический прототип, добавленный командой, сохранён в real-city.html и доступен по адресу http://127.0.0.1:8000/real-city.html. Его прежняя инструкция находится в docs/static-prototype.md. Для расчётов SUMO используйте главную страницу; статический прототип не подключён к расчётному API.

Артефакты и воспроизводимость

.runtime/snapshot/ хранит OSM XML, сеть SUMO и метаданные источника. .runtime/runs/<jobId>/ — запрос, статус, результат, одинаковый спрос, patch сети, GeoJSON, команды и XML результатов. В папках before/ и after/ лежат simulation.sumocfg, которые можно открыть в sumo-gui из установленного пакета. Они содержат абсолютные локальные пути: для переноса прогон нужно создать заново.

Результат содержит seed, параметры, версии модели/SUMO, хеши OSM, сети и спроса. Кеш исключён из git. Не заменяйте снимок при работающем worker. Для обновления сохраните нужные результаты, остановите сервер, переименуйте .runtime/snapshot, затем выполните подготовку снова.

Подготовка из терминала:

.\.venv\Scripts\python.exe -m server --prepare

API: GET /api/v1/health, GET /api/v1/projects/catalog, POST /api/v1/prepare, GET /api/v1/city/snapshot, POST /api/v1/scenarios/run, GET /api/v1/runs/{jobId}, GET /api/v1/runs/{jobId}/results, GET /api/v1/runs/{jobId}/layers/{traffic|school|clinic|park}. POST требует Content-Type: application/json; тело подготовки — {}. Интерактивная схема — /docs.

Проверки

.\.venv\Scripts\python.exe -m unittest discover -s tests -p test_logic.py
.\.venv\Scripts\python.exe -m server --prepare
.\.venv\Scripts\python.exe -m unittest discover -s tests -p test_sumo.py

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

Источники

Звёзды
⭐ 0
Форки
0
Язык
HTML
Последний push
в прошлом месяце
Коммиты
9
Авторы
3
Файлы
31
Ветки
4

Авторы коммитов

Adil Sovet 5Indiangiver0 2zhanmieru 2

История коммитов

  • 2026-09-23 17:51Add files via uploadzhanmieru
  • 2026-09-23 17:49Add files via uploadzhanmieru
  • 2026-09-23 17:57fix(integration): merge main and preserve both city interfacesIndiangiver0
  • 2026-09-23 17:55feat(simulation): integrate local SUMO scenarios and city accessibilityIndiangiver0
  • 2026-09-23 17:50Merge pull request #2 from BAITC-Hacks/math-logic-1Adil Sovet
  • 2026-09-23 17:48Add files via uploadAdil Sovet
  • 2026-09-23 17:06Add Astana simulation logic prototypeAdil Sovet
  • 2026-09-23 15:30Add remaining Astana prototype filesAdil Sovet
Все коммиты (9)
  • 2026-09-23 15:26Initial Astana 3D city prototypeAdil Sovet
Структура репозитория (31 файлов)
.gitignore
README.md
docs/logic-architecture.md
docs/static-prototype.md
index.html
outputs/astana-3d/real-city.html
real-city.html
requirements.txt
server/__init__.py
server/__main__.py
server/accessibility.py
server/app.py
server/catalog.py
server/data.py
server/simulation.py
src/logic/accessibility-model.js
src/logic/app-controller.js
src/logic/arcgis-client.js
src/logic/astana-data.js
src/logic/budget-model.js
src/logic/config.js
src/logic/map-layer-controller.js
src/logic/pilot-app.js
src/logic/pilot-map.js
src/logic/scenario-runner.js
src/logic/simulation-api.js
src/logic/transport-model.js
src/pilot.css
start.ps1
tests/test_logic.py
tests/test_sumo.py
Ветки (4)

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.