Когда вы пытаетесь найти многоугольник, содержащий вашу точку, вам сначала нужно сгенерировать многоугольники из многоканальной геометрии. Поскольку вы не предоставили свои данные, я загружаю образец из 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
Вот как это выглядит.
Далее вам нужно получить полигоны ваших блоков, определенных улицами, используя shapely.ops.polygonize
, как я предложил в комментарии выше, и сохраните их как GeoSeries.
polygons = shapely.ops.polygonize(streets.geometry)
polygons = gpd.GeoSeries(polygons)
Единственное, что вам нужно сделать, это найтикакой полигон содержит вашу точку.
target = polygons.loc[polygons.contains(point)]
Снова ее нанесение:
ax = target.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
Если вы хотите знать, какие улицыформируют границу этого многоугольника, просто пересекают его с исходной сетью. Я фильтрую для MultiLineString
, чтобы исключить улицы, которые пересекают полигон только в одной точке.
target_streets = streets.loc[streets.intersection(target.iloc[0]).type == 'MultiLineString']
Вот как выглядит результат.
ax = target_streets2.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
Надеюсь, это поможет.