Сетевой анализ — это направление пространственного анализа, в котором объекты рассматриваются как элементы сети, соединённые между собой связями.
Например, в сетевом анализе все измерения выполняются вдоль сети — например, по улично-дорожной сети или транспортным маршрутам. Благодаря этому такой подход позволяет более реалистично моделировать перемещение и доступность в городской среде.
Для формального описания и анализа сетей используется теория графов — раздел математики, изучающий структуры, состоящие из узлов и рёбер.
Граф — это математическая модель сети, представляющая собой множество узлов (вершин) и рёбер (связей) между ними.
В контексте улично-дорожной сети (УДС):
узлы (nodes) — перекрёстки, развязки или тупики,
рёбра (edges) — это участки дорог, соединяющие узлы.

--
В этом разделе мы получим граф улично-дорожной сети на основе данных OpenStreetMap (OSM) и изучим его основные характеристики
0. Импорт библиотек¶
import osmnx as ox
import networkx as nx
import matplotlib.pyplot as pltNetworkX (
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>, <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()
По распределению степеней узлов можно сделать вывод о структуре уличной сети. Например, большое количество узлов со степенью 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: Greenwich4. Преобразование графа в 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: >
Итог¶
В этом разделе мы познакомились с представлением улично-дорожной сети в виде графа.
Мы узнали:
как получить граф улично-дорожной сети на основе данных OpenStreetMap;
как устроен граф (узлы и рёбра) и какие атрибуты он содержит;
как рассчитывать основные характеристики сети: количество узлов и рёбер, степени узлов и связность;
как преобразовывать граф в GeoDataFrame для пространственного анализа.
В рассмотренном примере мы анализировали улично-дорожную сеть конкретного района. Однако аналогичный подход можно применять для исследования структуры и связности любых территорий.
В следующем разделе мы перейдём к конкретным задачам сетевого анализа.