Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Граф улично-дорожной сети

Сетевой анализ — это направление пространственного анализа, в котором объекты рассматриваются как элементы сети, соединённые между собой связями.

Например, в сетевом анализе все измерения выполняются вдоль сети — например, по улично-дорожной сети или транспортным маршрутам. Благодаря этому такой подход позволяет более реалистично моделировать перемещение и доступность в городской среде.

Для формального описания и анализа сетей используется теория графов — раздел математики, изучающий структуры, состоящие из узлов и рёбер.

Граф — это математическая модель сети, представляющая собой множество узлов (вершин) и рёбер (связей) между ними.

В контексте улично-дорожной сети (УДС):

  • узлы (nodes) — перекрёстки, развязки или тупики,

  • рёбра (edges) — это участки дорог, соединяющие узлы.

Граф

--

В этом разделе мы получим граф улично-дорожной сети на основе данных OpenStreetMap (OSM) и изучим его основные характеристики

0. Импорт библиотек

import osmnx as ox
import networkx as nx
import matplotlib.pyplot as plt
  • NetworkX (networkx) — библиотека Python для создания, анализа и визуализации графов и сетей. Позволяет работать с узлами и рёбрами, рассчитывать метрики центральности, находить кратчайшие пути и исследовать структуру сетей. Широко используется для сетевого анализа в задачах транспорта, социальных сетей и пространственной аналитики.

1. Граф улично-дорожной сети из OSMnx

Библиотека osmnx предоставляет удобные инструменты для получения и анализа улично-дорожной сети на основе данных OpenStreetMap.

В osmnx используется ориентированный мультиграф (MultiDiGraph):

  • рёбра имеют направление (например, учитывается одностороннее движение),

  • между двумя узлами может существовать несколько рёбер,

  • рёбра содержат атрибуты, такие как длина, тип дороги, ограничения движения и другие характеристики.

Такое представление позволяет применять методы сетевого анализа: рассчитывать маршруты, оценивать доступность, анализировать структуру сети и строить зоны достижимости.

1.1 Получение графа уличной сети

Сначала получим граф улично-дорожной сети для выбранного района на основе данных OpenStreetMap (OSM).

Для этого используем функцию ox.graph_from_place(), которая загружает данные OSM по заданному названию территории и автоматически преобразует их в граф.

В параметрах функции мы указываем:

  • название территории (area_name),

  • тип сети (network_type), который определяет, какие дороги будут включены в граф (например, автомобильные, пешеходные или велосипедные).

В предыдущих разделах мы работали с Центральным районом Санкт-Петербурга. В этом разделе в качестве примера рассмотрим Ленинский район Екатеринбурга — это связано с тем, что его структура позволяет нагляднее продемонстрировать некоторые показатели анализа.

# Указываем район
area_name = "Ленинский район, Екатеринбург"

# Получаем граф улично-дорожной сети из OpenStreetMap
# network_type='drive' — автомобильная сеть (учитываются дороги, доступные для движения на машине)
graph = ox.graph_from_place(area_name, network_type='drive')

# Визуализируем граф
ox.plot_graph(graph)
<Figure size 800x800 with 1 Axes>
(<Figure size 800x800 with 1 Axes>, <Axes: >)

2. Общие характеристики сети

После получения графа улично-дорожной сети можно рассчитать его базовые характеристики. Они позволяют получить общее представление о структуре сети и служат отправной точкой для дальнейшего анализа.

К таким характеристикам относятся:

  • количество узлов (перекрёстков и концов улиц),

  • количество рёбер (участков дорог),

  • распределение степеней узлов (структура перекрёстков).

2.1 Количество узлов и рёбер

Одной из самых простых характеристик графа является число узлов и рёбер. Эти показатели позволяют оценить общий размер сети.

# Количество узлов и рёбер в графе
num_nodes = len(graph.nodes)
num_edges = len(graph.edges)

print(f"Количество узлов: {num_nodes}")
print(f"Количество рёбер: {num_edges}")
Количество узлов: 558
Количество рёбер: 1303

2.2 Степени узлов

Степень узла — это количество рёбер, которые с ним связаны.
Для улично-дорожной сети этот показатель помогает понять структуру перекрёстков.

Например:

  • узел со степенью 1 может соответствовать тупику,

  • узел со степенью 3 или 4 — обычному перекрёстку,

  • узлы с более высокой степенью могут соответствовать крупным развязкам.

Анализ степеней узлов позволяет оценить, насколько сеть разветвлённая и как устроены её соединения.

# Получаем степени узлов
node_degrees = dict(graph.degree())

# Берём значения степеней
degree_values = list(node_degrees.values())

# Строим гистограмму
plt.figure()
plt.hist(degree_values, bins=range(min(degree_values), max(degree_values)+2))

plt.xlabel("Степень узла")
plt.ylabel("Количество узлов")
plt.title("Распределение степеней узлов")

plt.show()
<Figure size 640x480 with 1 Axes>

По распределению степеней узлов можно сделать вывод о структуре уличной сети. Например, большое количество узлов со степенью 1 указывает на наличие тупиков, а преобладание степеней 3–4 и более характерно для регулярной городской застройки.

2.3 Показатели связности

Связность сети показывает, насколько её элементы соединены между собой.

На начальном этапе можно использовать простые показатели:

  • количество компонент связности,

  • размер крупнейшей компоненты.

Компонента связности — это часть графа, внутри которой все узлы соединены друг с другом путями.
Если компонент несколько, это может означать, что сеть состоит из отдельных несвязанных частей.

# Для анализа связности преобразуем граф в неориентированный
graph_undirected = graph.to_undirected()

# Находим компоненты связности
components = list(nx.connected_components(graph_undirected))

print(f"Количество компонент связности: {len(components)}")
print(f"Размер крупнейшей компоненты: {len(max(components, key=len))}")
Количество компонент связности: 1
Размер крупнейшей компоненты: 558

3. Перепроецирование графа

При работе с улично-дорожной сетью важно учитывать систему координат, в которой представлены данные.

Граф, полученный с помощью osmnx, по умолчанию находится в географической системе координат (WGS84, EPSG:4326), где координаты задаются в градусах.

Это удобно для хранения и визуализации, но может быть проблемой для некоторых типов анализа.

При этом в графе уже есть атрибут length, который хранит длину рёбер в метрах — поэтому многие алгоритмы (например, поиск кратчайшего пути) работают корректно даже без перепроецирования. Однако для операций, связанных с геометрией (например, буферизация или измерение расстояний), рекомендуется перепроецирование.

Библиотека osmnx позволяет автоматически перепроецировать граф в подходящую систему координат (обычно UTM) с помощью ox.project_graph()

graph_utm = ox.project_graph(graph)

Проверим систему координат:

graph_utm.graph["crs"]
<Projected CRS: EPSG:32641> Name: WGS 84 / UTM zone 41N Axis Info [cartesian]: - E[east]: Easting (metre) - N[north]: Northing (metre) Area of Use: - name: Between 60°E and 66°E, northern hemisphere between equator and 84°N, onshore and offshore. Afghanistan. Islamic Republic of Iran. kazakhstan. Pakistan. Russian Federation. Turkmenistan. Uzbekistan. - bounds: (60.0, 0.0, 66.0, 84.0) Coordinate Operation: - name: UTM zone 41N - method: Transverse Mercator Datum: World Geodetic System 1984 ensemble - Ellipsoid: WGS 84 - Prime Meridian: Greenwich

4. Преобразование графа в GeoDataFrame

Иногда бывает нужно для анализа и визуализации преобразовать граф в GeoDataFrame. В этом случае узлы и рёбра представляются как пространственные объекты (точки и линии), с которыми можно выполнять стандартные операции геообработки.

Для этого используется функция ox.graph_to_gdfs(), которая преобразует граф в два GeoDataFrame:

  • nodes — слой с узлами (точки),

  • edges — слой с рёбрами (линии).

# Получаем узлы и ребра в формате GeoDataFrame
nodes, edges = ox.graph_to_gdfs(graph)

# Визуализируем ребра
edges.plot(figsize=(10, 10), color='blue')
<Axes: >
<Figure size 1000x1000 with 1 Axes>

Итог

В этом разделе мы познакомились с представлением улично-дорожной сети в виде графа.

Мы узнали:

  • как получить граф улично-дорожной сети на основе данных OpenStreetMap;

  • как устроен граф (узлы и рёбра) и какие атрибуты он содержит;

  • как рассчитывать основные характеристики сети: количество узлов и рёбер, степени узлов и связность;

  • как преобразовывать граф в GeoDataFrame для пространственного анализа.

В рассмотренном примере мы анализировали улично-дорожную сеть конкретного района. Однако аналогичный подход можно применять для исследования структуры и связности любых территорий.

В следующем разделе мы перейдём к конкретным задачам сетевого анализа.