Сервис по анализу городской топологии — веб-приложение для исследования улично-дорожной сети города на основе данных OpenStreetMap (OSM). Система загружает карту города, строит граф улиц (пересечения/соединения — узлы, уличные сегменты — ребра), визуализирует его и вычисляет топологические показатели.
Проект предназначен для исследовательского анализа городской структуры: он помогает выявлять и сравнивать самоорганизующиеся городские пространства и территории с регулярной (плановой) планировкой через показатели связности уличной сети, а также проводить сравнение районов внутри одного города.
Проект создан для "Центра аналитики динамических процессов и систем СПбГУ".
- Определять среднее число связей (пересечений) для улиц по всему городу и по районам.
- Дать исследователям инструмент для выявления самоорганизации городской среды и сравнения с регулярным планированием.
- Визуализировать топологию уличной сети в виде графа и рассчитывать основные параметры этой топологии.
- Разработать веб-приложение для анализа улично-дорожной сети любого города.
- Реализовать загрузку и обработку OSM-данных: построение графа улиц и вычисление числа связей.
- Реализовать представление и визуализацию графа (узлы/ребра) и поддержку анализа с фильтрацией по районам.
Предметная область включает анализ городской топологии улиц на стыке GIS и графового анализа: работа с OSM-данными, представление уличной сети в виде графа и вычисление метрик связности для города и отдельных районов.
- Предварительные действия
- Запуск приложения
- Выключение сервера
- Тесты
- Анализ графов
- Граф придомовых проездов
- Экспорт CSV
- Утилиты в каталоге
tools
- Скачайте PBF-файлы исследуемых городов и поместите их в директорию
/cities_pbf/в корне проекта (создайте её, если отсутствует). - Названия файлов должны иметь вид:
{Название города с большой буквы}.pbf. Пример:Москва.pbf. - Для скачивания готовых файлов можно воспользоваться https://extract.bbbike.org/ или скриптом
tools/osm_fetch.py(функцияdownload_city).
Перед запуском приложения задайте обязательные переменные окружения (можно использовать локальный .env, который не попадает в Git, или файл secrets/*.env с ограниченными правами доступа):
DADATA_TOKEN— действующий API-токен DaData. Токен передается внутрь контейнера (webserver) и используется модулемstreet_name_parser. При отсутствии переменной сервис завершает работу с ошибкой.
- Перейдите на https://dadata.ru/profile/#info и создайте бесплатный аккаунт (подтвердите почту/телефон, если потребуется).
- В личном кабинете откройте раздел API-ключи и скопируйте значение поля «Стандартный API-ключ».
- Сохраните ключ в локальном
.envили файлеsecrets/*.envкакDADATA_TOKEN=<ваш_ключ>и перезапустите контейнеры (docker compose up --build), чтобы переменная попала в backend.
В production-среде храните значения POSTGRES_USER, POSTGRES_PASSWORD, DATABASE_URL, DADATA_TOKEN и других чувствительных параметров в секретном хранилище или файлах secrets/*.env, которые доступны только системе деплоя.
Для запуска серверной части приложения необходимо выполнить из основной директории проекта команду:
docker compose up --build
После выполнения команды, по окончании сборки контейнера, доступ к сайту и серверу базы данных можно получить по следующим ссылкам:
| Веб-приложение | Backend API (Swagger) |
|---|---|
| http://localhost:4200/ | http://localhost:8901/docs/ |
Для того чтобы корректно завершить работу сервера в консоли выполните команду:
docker compose down
Все тесты находятся в каталоге api/backend/tests. Перед запуском перейдите в папку api и активируйте виртуальное окружение (source venv/bin/activate), если оно ещё не активно.
-
Прогнать унифицированный набор тестов с отображением покрытия в терминале:
venv/bin/python -m pytest --cov=backend --cov-report=term-missing -
Сгенерировать HTML-отчёт о тестах и покрытии:
venv/bin/python -m pytest backend/tests --cov=backend --cov-report=html --html=report.html --self-contained-htmlПосле выполнения появятся файлы
report.html(результаты тестов) и каталогhtmlcov/index.html(детальное покрытие). Их можно открыть в браузере для наглядного просмотра.
В каталоге /analytics лежат ноутбуки, которые используются для поиска степенного закона (degrees.ipynb), для вычисления мер центральности (centrality.ipynb) и betweenness'а.
Для работы с данными ноутбуками требуется библиотека graph-tool. На момент написания README самый удобный способ ее использования - контейнеры. В каталоге также лежит Dockerfile для того, чтобы данный контейнер можно было поднять.
На вход ноутбуки принимают JSON-файл, который возвращают в качестве ответа методы /api/city/graph/region/ и /api/city/graph/bbox/{city_id}/.
При импорте города из PBF теперь дополнительно строится вспомогательный граф подъездных/дворовых дорог. Новые таблицы AccessNodes и AccessEdges содержат:
- Узлы (
AccessNodes):node_type = 'building'— отдельно стоящие здания (центроиды контуровbuilding=*).node_type = 'intersection'— перекрёстки и развилки малых дорог (service,residential,living_street,unclassified,track,road).
- Рёбра (
AccessEdges):road_typeравен исходномуhighway(илиbuilding_linkдля синтетического ребра «здание → дорога»).is_building_link = trueиспользуется для выделения подъездов.
Эти таблицы заполняются автоматически во время import_city_graph. В ответах /api/city/graph/* данные придомового слоя включены в общие CSV-поля:
points_csvсодержит объединённые узлы (layer=base|access) и колонкиid,longitude,latitude,layer,node_type,source_type,source_id,name.edges_csvсодержит объединённые рёбра (layer=base|access) и колонкиid,id_way,source,target,name,layer,source_way_id,road_type,length_m,is_building_link.
Фронтенд (виджет «Дороги») отображает новый слой поверх основного графа: здания показаны зелёными маркерами, внутренние узлы — оранжевыми, подъездные рёбра — выделенными линиями.
Для скачивания полного набора CSV (узлы, рёбра, свойства и метрики) добавлен эндпоинт POST /api/city/graph/region/export/. Он принимает тот же набор параметров, что и /api/city/graph/region/, а в ответ отдаёт ZIP-архив со следующими файлами:
nodes.csv— объединённые узлы основного и придомового графов с признаком слоя (layer=base|access).edges.csv— объединённые рёбра с дополнительными колонками (road_type,length_m,is_building_link,layer).points_properties.csv,ways_properties.csv,metrics.csv— исходные файлы из основного ответа.
Файл можно использовать для дальнейшего анализа или сторонних визуализаций без необходимости ручного склеивания слоёв.
В папке tools/ лежат небольшие CLI-скрипты, которые помогают проверять и визуализировать графы вне основного приложения:
export_buildings_csv.py— парсит.pbfнапрямую и выгружает CSV со всеми зданиями (source_id, координаты, имя), которые обнаруживает обработчик придомового графа.visualize_buildings_map.py— строит интерактивную карту (Folium/Leaflet) по зданиям из.pbf; можно ограничить число точек через--limit, результат сохраняется в HTML.visualize_export.py— принимает распакованную папку из ZIP-экспорта (nodes.csv,edges.csv) и рендерит оба слоя (основной и придомовой) на карте с переключаемыми слоями.inspect_cache.py— анализирует JSON-файлы кэша (data/caches/*.json), выводит сводную статистику и подсвечивает узлы без метрик, а также рёбра с отсутствующими вершинами.osm_fetch.py— скачивает OSM-выгрузку по названию города или произвольному bbox через Overpass; удобный способ быстро пополнитьcities_pbf/.
Каждый скрипт можно запустить напрямую из корня проекта, например:
python tools/visualize_export.py city-73-октябрьский --output graph.html
python tools/inspect_cache.py api/backend/data/caches/73_1_2.jsonДля визуализации требуется установленный folium (установите pip install folium, если ещё не ставили).