Извлечь ограниченный многоугольник с помощью OSMnx - PullRequest
2 голосов
/ 11 декабря 2019

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

До сих пор мне удавалось только построить визуализацию графика на карте и найти ближайшийкрай / узел к точке X.

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

enter image description here

1 Ответ

2 голосов
/ 30 декабря 2019

Когда вы пытаетесь найти многоугольник, содержащий вашу точку, вам сначала нужно сгенерировать многоугольники из многоканальной геометрии. Поскольку вы не предоставили свои данные, я загружаю образец из OSM с использованием OSMnx.

import osmnx as ox
import geopandas as gpd
import shapely

point = (40.742623, -73.977857)

streets_graph = ox.graph_from_point(point, distance=500, network_type='drive')
streets_graph = ox.project_graph(streets_graph)

Я перепроектировал его, поскольку это намного удобнее, чем работа с градусами, особенно если вы хотите что-то измерить.

Затем вам нужно преобразовать график OSMnx в геопанду GeoDataFrame.

streets = ox.save_load.graph_to_gdfs(streets_graph, nodes=False, edges=True,
                                     node_geometry=False, fill_edge_geometry=True)

Чтобы получить точку, с которой я могу работать, я просто воспользуюсь точкой в ​​центре этого геоданных.

point = streets.unary_union.centroid

Вот как это выглядит.

network and point overlayed

Далее вам нужно получить полигоны ваших блоков, определенных улицами, используя shapely.ops.polygonize, как я предложил в комментарии выше, и сохраните их как GeoSeries.

polygons = shapely.ops.polygonize(streets.geometry)
polygons = gpd.GeoSeries(polygons)

polygonized network

Единственное, что вам нужно сделать, это найтикакой полигон содержит вашу точку.

target = polygons.loc[polygons.contains(point)]

Снова ее нанесение:

ax = target.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')

final polygon

Если вы хотите знать, какие улицыформируют границу этого многоугольника, просто пересекают его с исходной сетью. Я фильтрую для MultiLineString, чтобы исключить улицы, которые пересекают полигон только в одной точке.

target_streets = streets.loc[streets.intersection(target.iloc[0]).type == 'MultiLineString']

Вот как выглядит результат.

ax = target_streets2.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')

streets intersecting polygon

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...