OSMnx simple_graph с помощью Edge_attrs_differ создает направления смешанной геометрии на двунаправленных краях.Python

Программы на Python
Ответить
Anonymous
 OSMnx simple_graph с помощью Edge_attrs_differ создает направления смешанной геометрии на двунаправленных краях.

Сообщение Anonymous »

Контекст:
Я использую OSMnx для упрощения направленной дорожной сети, построенной на основе данных OpenStreetMap.
График представляет собой MultiDiGraph, где улицы с двусторонним движением представлены двумя взаимно направленными ребрами ( и v→u). Как указано в документации, оба ребра имеют одну и ту же геометрию LineString.
Когда я применяю упрощение OSMnx по умолчанию, геометрия ребер перестраивается и становится согласованной по направлению: геометрия u→v упорядочивается от u до v, а обратное ребро v→u получает обратную геометрию.
Однако, когда я ослабляю определение конечной точки с помощью Edge_attrs_differ, я наблюдаю противоречивый результат:
  • Геометрия некоторых ребер перестраивается и ориентируется в соответствии с направлением ребер.
  • Другие ребра (состоящие ровно из двух конечных точек) не перестраиваются и сохраняют свою исходную ориентацию геометрии.
Как в результате упрощенный граф содержит смесь перевернутой и неперевернутой геометрии по направленным ребрам.
После проверки simplification.py кажется, что это происходит потому, что _get_paths_to_simplify() не генерирует путь, когда ребро соединяет два узла конечных точек напрямую, поэтому его геометрия не восстанавливается с помощью:

Код: Выделить всё

# construct the new consolidated edge's geometry for this path
path_attributes["geometry"] = LineString(
[Point((G.nodes[node]["x"], G.nodes[node]["y"])) for node in path],
)
Вопросы:
  • Является ли эта смешанная геометрическая ориентация ожидаемым поведением simple_graph при использовании Edge_attrs_differ или это ошибка?
  • Если это ожидается, существует ли рекомендуемый или поддерживаемый способ принудительной реконструкции геометрии (или согласованности ориентации) для ребер, состоящих только из двух конечные точки?
Спасибо.
Минимально воспроизводимый пример и результаты, отображаемые в QGis:

Код: Выделить всё

import pyproj
from pyrosm import OSM
import osmnx as ox
import networkx as nx
import geopandas as gpd
from shapely.geometry import Point

def save_geoparquets(graph: nx.MultiDiGraph, base_name) -> None:
# Transform nodes in GeoDataFrame
nodes_data = [
{**data, "node": node, "geometry": Point(data["x"], data["y"])}
for node, data in graph.nodes(data=True)
]
gdf_nodes = gpd.GeoDataFrame(nodes_data, geometry="geometry", crs=4326)

# Transform edges in GeoDataFrame
edges_data = []
for u, v, key, data in graph.edges(keys=True, data=True):
rec = {"u": u, "v": v, "key": key}
for k, val in data.items():
if k == "geometry":
continue
# Stringify lists for Arrow/Parquet compatibility
if isinstance(val, (list, tuple)):
rec[k] = ",".join(map(str, val))
else:
rec[k] = val
rec["geometry"] = data.get("geometry")
edges_data.append(rec)
gdf_edges = gpd.GeoDataFrame(edges_data, geometry="geometry", crs=4326)

# Force object columns to string type for Arrow compatibility
for col in gdf_edges.columns:
if col != "geometry" and gdf_edges[col].dtype == object:
gdf_edges[col] = gdf_edges[col].astype("string")

# Save to Parquet
gdf_nodes.to_parquet(f"{base_name}_nodes.geoparquet")
gdf_edges.to_parquet(f"{base_name}_edges.geoparquet")

# Read OSM PBF file (bbbike extract on AOI)
osm_data = OSM("planet_1.658_43.481_ded13b9b.osm.pbf")

# Get nodes and edges from OSM network
gdf_nodes, gdf_edges = osm_data.get_network(network_type="driving", nodes=True)
print(f"Extracted: {len(gdf_nodes)} nodes | {len(gdf_edges)} edges")

# Transform nodes and edges into a networkx MultiDiGraph
# Geometries in one direction even for bidirectional edges as specified in documentation
graph = osm_data.to_graph(gdf_nodes, gdf_edges, graph_type="networkx")
print(f"Graph created: {graph.number_of_nodes()} nodes | {graph.number_of_edges()} edges")
graph.graph["crs"] = pyproj.CRS("EPSG:4326")
save_geoparquets(graph, "raw")

# Base simplification, got correct geometries in both directions for bidirectional edges
graph_simplified = ox.simplification.simplify_graph(graph)
save_geoparquets(graph_simplified, "simplified")

# Release simplification strictness.  "tags" in this example to ease demonstration, more complex for real: "stop", "bus".
graph_custom_simplification = ox.simplification.simplify_graph(graph, edge_attrs_differ=["tags"])
save_geoparquets(graph_custom_simplification, "custom_simplification")
planet_1.658_43.481_ded13b9b.osm.pbf
Изображение
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»