Программно-информационная система автоматизированного проектирования городских маршрутов пассажирских перевозок. Реализация выпускной квалификационной работы Л.Е. Георга (ОГУ, 09.03.04 «Программная инженерия», шифр ОГУ 09.03.04.3025.755 ПЗ, 2026 г.).
| Слой | Технология |
|---|---|
| Frontend | Next.js 14 (App Router) + TypeScript + ShadcnUI + Tailwind CSS |
| Backend | FastAPI (Python 3.12) + SQLAlchemy 2 + Alembic |
| СУБД | PostgreSQL 16 |
| Кэш | Redis 7 |
| Граф/алгоритмы | NetworkX (Dijkstra, A*) |
| Машинное обучение | scikit-learn (k-means) |
| Карты | Leaflet + OpenStreetMap (без API-ключей) |
| Контейнеризация | Docker + Docker Compose |
┌───────────┐ HTTPS ┌──────────────┐
│ Браузер │ ─────────────► │ Next.js 14 │
│ (Leaflet) │ ◄───────────── │ (frontend) │
└───────────┘ └──────┬───────┘
│ REST / JSON
▼
┌──────────────┐
│ FastAPI │
│ (backend) │
└──┬──────┬────┘
┌─────────┘ └───────┐
▼ ▼
┌─────────────┐ ┌──────────────┐
│ PostgreSQL │ │ Redis │
│ routes, │ │ cache, │
│ bus_stops, │ │ sessions │
│ vehicles… │ │ │
└─────────────┘ └──────────────┘
git clone <this-repo>
cd programm
cp .env.example .env
# отредактируйте .env — обязательно поменяйте POSTGRES_PASSWORD и JWT_SECRETdocker compose up -d --build
# дождитесь, пока контейнеры станут healthy
docker compose logs -f backendПри первом запуске backend автоматически применит миграции Alembic.
Вариант A — демо-данные (быстро, 20 примерных остановок):
docker compose exec backend python -m app.seeds.seed_oremburgСоздаёт: пользователей (admin/admin123, analyst/analyst123, manager/manager123),
типы и модели ТС, парк ТС, ~20 ручных остановочных пунктов и граф связности.
Вариант B — реальные остановки Оренбурга из OpenStreetMap (рекомендуется):
docker compose exec backend python -m app.seeds.seed_oremburg
docker compose exec backend python -m app.seeds.import_osm_stopsЗагружает все реальные остановки Оренбурга через публичный Overpass API (обычно 200+ остановок) и строит граф связности по ближайшим соседям.
Флаги import_osm_stops:
| Флаг | Назначение | По умолчанию |
|---|---|---|
--city ГОРОД |
Город для поиска остановок (по name в OSM) | Оренбург |
--bbox S,W,N,E |
Прямоугольник координат вместо поиска по городу | — |
--neighbours N |
Сколько ближайших соседей соединять в графе | 4 |
--merge-radius N |
Расстояние (м) для объединения дубликатов (разные стороны улицы) | 50 |
--dry-run |
Только запросить OSM и показать статистику, без записи в БД | — |
--no-graph |
Не строить граф связности | — |
--clear |
Удалить все остановки/связи перед импортом | — |
Примеры:
# Предпросмотр для Москвы (без записи в БД)
docker compose exec backend python -m app.seeds.import_osm_stops --city Москва --dry-run
# Импорт Москвы с мягкой дедупликацией (радиус 30 м)
docker compose exec backend python -m app.seeds.import_osm_stops --city Москва --merge-radius 30
# Импорт по точному прямоугольнику
docker compose exec backend python -m app.seeds.import_osm_stops --bbox 51.7,55.0,51.9,55.3Примечание: Overpass API — публичный сервис, при большой нагрузке может вернуть таймаут. В этом случае используйте
--bboxс узким прямоугольником или повторите запрос через минуту.
По умолчанию построение маршрута использует OSRM (Open Source Routing Machine) —
маршрут прокладывается по реальным дорогам OpenStreetMap, не по прямым линиям
между остановками. Через .env:
OSRM_BASE_URL=https://router.project-osrm.org # публичный демо-сервер
Для production-нагрузки рекомендуется поднять собственный OSRM-инстанс
(скачать дамп OSM региона, прогнать osrm-extract/osrm-contract,
запустить osrm-routed в Docker — см. документацию OSRM).
В UI можно выбрать алгоритм:
- OSRM — по реальным дорогам (рекомендуется);
- Дейкстра / A* — поиск по локальному графу
bus_stop_connections(классические алгоритмы из диплома, раздел 1.5).
Всё ходит через nginx (порт 80):
- Frontend: http://localhost/ (или
http://<server-ip>/) - Backend OpenAPI: http://localhost/docs
- Backend ReDoc: http://localhost/redoc
- API endpoints: http://localhost/api/v1/...
Никакой правки кода / hardcoded IP не требуется:
git clone <repo>
cd programm
cp .env.example .env
# при необходимости поменяйте JWT_SECRET и POSTGRES_PASSWORD;
# больше ничего менять НЕ нужно — фронт ходит на относительный /api/v1
docker compose up -d --build
docker compose exec backend python -m app.seeds.seed_oremburg
docker compose exec backend python -m app.seeds.import_osm_stopsВ firewall сервера откройте только TCP 80 (HTTP). При желании добавьте TLS-сертификат через Let's Encrypt + Certbot и порт 443.
programm/
├── docker-compose.yml
├── .env.example
├── .gitignore
├── README.md
├── backend/
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── alembic.ini
│ ├── alembic/ # миграции БД
│ ├── app/
│ │ ├── main.py # точка входа FastAPI
│ │ ├── config.py # настройки (pydantic-settings)
│ │ ├── database.py # SQLAlchemy engine + Session
│ │ ├── deps.py # get_db, get_current_user
│ │ ├── core/ # security, exceptions
│ │ ├── models/ # ORM-модели (User, Route, BusStop, Vehicle, ...)
│ │ ├── schemas/ # Pydantic v2
│ │ ├── services/ # бизнес-логика
│ │ │ ├── route_engine.py # Dijkstra / A*
│ │ │ ├── cluster_service.py # k-means
│ │ │ ├── auth_service.py
│ │ │ └── vis_integration.py
│ │ ├── api/v1/ # роутеры
│ │ └── seeds/ # начальные данные
│ └── tests/
└── frontend/
├── Dockerfile
├── package.json
├── next.config.js
├── tailwind.config.ts
├── components.json # shadcn config
├── app/ # App Router pages
├── components/
│ ├── ui/ # shadcn компоненты
│ ├── layout/
│ ├── map/ # LeafletMap
│ └── routes/
├── lib/ # api wrapper, utils
├── hooks/
└── stores/ # Zustand
| Метод | Endpoint | Описание |
|---|---|---|
| POST | /api/v1/auth/login |
Авторизация, получение JWT |
| GET | /api/v1/auth/me |
Текущий пользователь |
| GET | /api/v1/routes |
Список маршрутов |
| POST | /api/v1/routes |
Создание маршрута |
| GET | /api/v1/routes/{id} |
Карточка маршрута со списком остановок и геометрией |
| POST | /api/v1/routes/build |
Расчёт маршрута с промежуточными точками (OSRM/Dijkstra/A*) |
| GET | /api/v1/bus_stops |
Список остановок |
| POST | /api/v1/bus_stops |
Добавить остановку |
| GET | /api/v1/connections |
Рёбра графа сети |
| POST | /api/v1/connections |
Добавить ребро |
| GET | /api/v1/vehicles |
Парк ТС |
| GET | /api/v1/passenger_flows |
Замеры пассажиропотока |
| POST | /api/v1/analytics/cluster |
Кластерный анализ маршрутов |
| GET | /api/v1/reports |
Аналитические отчёты |
| GET | /api/v1/health |
Health-check |
Полная интерактивная документация: http://localhost:8000/docs.
В приложении используются бесплатные тайлы OpenStreetMap без необходимости
получения API-ключей. Тайл-сервер задаётся переменной NEXT_PUBLIC_MAP_TILE_URL
в .env. По умолчанию: https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png.
Примечание: для production-нагрузок (>5 000 запросов в день на пользователя) следует развернуть собственный tile-сервер либо использовать платный CDN (Stadia Maps, Mapbox, Yandex Maps API).
cd backend
python -m venv .venv
source .venv/bin/activate # macOS/Linux
# .venv\Scripts\activate # Windows PowerShell
pip install -r requirements.txt
alembic upgrade head
uvicorn app.main:app --reloadcd frontend
npm install
npm run dev# Backend
docker compose exec backend pytest -v
# Frontend
docker compose exec frontend npm test# Создать новую миграцию по изменениям моделей
docker compose exec backend alembic revision --autogenerate -m "описание"
# Применить
docker compose exec backend alembic upgrade head
# Откатить на одну
docker compose exec backend alembic downgrade -1Соответствует разделу 2.3 пояснительной записки:
routes— справочник маршрутов;bus_stops— справочник остановочных пунктов (lat/lon);bus_stop_routes— связь «остановка ↔ маршрут» (порядок);bus_stop_connections— рёбра графа дорожной сети (расстояние, время);vehicle_types,vehicle_models,vehicles— парк подвижного состава;passenger_flows— замеры пассажиропотока;trips— журнал рейсов;analytics_reports— аналитические отчёты;users— пользователи системы.