有没有办法找到一个点坐标列表,其中 3 条或更多条线在 python 中使用 shapely 和 geopandas 相互接触?
Is there way to find a list of point coordinates where 3 or more lines touch eachother using shapely and geopandas in python?
我有一个 Geopandas DataFrame,每一行都包含一个整齐的 LineString。我需要找到三个或更多 LineString 相互接触的点列表。例如,在图Input image中,我需要三个彩色线相交点的坐标。
找到所有三条线相交的点后,我需要将三条线合并成两条线:1) 粉色 + 紫色 2) 绿色 + 紫色。重叠应该没问题。
如有任何帮助,我们将不胜感激。谢谢!
- 使用了几个国家作为 LINESTRINGS
的来源
- 对于这个数据集,只有两个点与三个选定的国家相交(根据可视化)
- 关键概念是内部连接点到点,然后找到重复次数超过要求的点
import geopandas as gpd
import shapely.geometry
import pandas as pd
import plotly.express as px
# some polygons
# fmt: off
gdf = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")).loc[lambda d: d["iso_a3"].isin(["BEL", "LUX", "NLD", "DEU", "AUT","POL"]), ["geometry", "iso_a3"]].reset_index(drop=True)
# fmt: on
# change to linestrings as per question
gdf["geometry"] = gdf["geometry"].apply(
lambda p: shapely.geometry.LineString(p.exterior.coords)
)
# generate series of points from linestrings
points = (
gdf["geometry"].apply(lambda l: l.coords).rename("point").explode().reset_index()
)
# 1. join all points to all points
# 2. exclude point to self
points = (
points.merge(points, on=["point"])
.drop_duplicates()
.loc[lambda d: d["index_x"] != d["index_y"]]
)
# now find points that appera N times
n_times = (
points.groupby(["point"])
.size()
.loc[lambda s: s >= 3]
.reset_index()["point"]
.apply(pd.Series)
)
# visualize to test...
px.scatter_mapbox(n_times, lon=0, lat=1, mapbox_style="carto-positron",).update_traces(
marker_size=20
).update_layout(mapbox={"layers": [{"source": gdf.__geo_interface__, "type": "line"}]})
我有一个 Geopandas DataFrame,每一行都包含一个整齐的 LineString。我需要找到三个或更多 LineString 相互接触的点列表。例如,在图Input image中,我需要三个彩色线相交点的坐标。
找到所有三条线相交的点后,我需要将三条线合并成两条线:1) 粉色 + 紫色 2) 绿色 + 紫色。重叠应该没问题。
如有任何帮助,我们将不胜感激。谢谢!
- 使用了几个国家作为 LINESTRINGS 的来源
- 对于这个数据集,只有两个点与三个选定的国家相交(根据可视化)
- 关键概念是内部连接点到点,然后找到重复次数超过要求的点
import geopandas as gpd
import shapely.geometry
import pandas as pd
import plotly.express as px
# some polygons
# fmt: off
gdf = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")).loc[lambda d: d["iso_a3"].isin(["BEL", "LUX", "NLD", "DEU", "AUT","POL"]), ["geometry", "iso_a3"]].reset_index(drop=True)
# fmt: on
# change to linestrings as per question
gdf["geometry"] = gdf["geometry"].apply(
lambda p: shapely.geometry.LineString(p.exterior.coords)
)
# generate series of points from linestrings
points = (
gdf["geometry"].apply(lambda l: l.coords).rename("point").explode().reset_index()
)
# 1. join all points to all points
# 2. exclude point to self
points = (
points.merge(points, on=["point"])
.drop_duplicates()
.loc[lambda d: d["index_x"] != d["index_y"]]
)
# now find points that appera N times
n_times = (
points.groupby(["point"])
.size()
.loc[lambda s: s >= 3]
.reset_index()["point"]
.apply(pd.Series)
)
# visualize to test...
px.scatter_mapbox(n_times, lon=0, lat=1, mapbox_style="carto-positron",).update_traces(
marker_size=20
).update_layout(mapbox={"layers": [{"source": gdf.__geo_interface__, "type": "line"}]})