如何在Python中找到多边形内的坐标点到多边形边缘的最近距离?

huangapple go评论67阅读模式
英文:

How to find nearest distance from a coordinate point inside a polygon to the edge (border) of the polygon in Python?

问题

我目前有一个数据集,其中包含第一个数据框中的纬度和经度坐标。

然后,我有尼日利亚的形状。

world_filepath = gpd.datasets.get_path('naturalearth_lowres')
world = gpd.read_file(world_filepath)
nigeria = world.loc[world['name'] == 'Nigeria']

我不确定如何找到第一个数据帧中坐标点与尼日利亚形状边界之间的最近距离。我尝试过使用Shapely,但由于坐标在多边形内部,所以一直得到0。

最终结果,我想要计算第一个数据帧中每一行的坐标点到尼日利亚边界的最近距离。

谢谢 如何在Python中找到多边形内的坐标点到多边形边缘的最近距离?

编辑 - 包括更多信息和代码

我将第一个数据集保存为具有点坐标的 'coord_new'。

df = gpd.GeoDataFrame(coord_new, geometry=gpd.points_from_xy(coord_new.longitude, coord_new.latitude))

这是我看到其他人使用的方式来计算点到多边形边界的距离。然而,我一直得到0,然后在 'distance1' 列中得到NaN。

英文:

I currently have a dataset with lat and lon coordinates in my first dataframe.

And then I have a shape of a country, Nigeria.

world_filepath = gpd.datasets.get_path('naturalearth_lowres')

world = gpd.read_file(world_filepath)

nigeria = world.loc[world['name'] == 'Nigeria']

pop_est      continent	name	iso_a3	gdp_md_est	geometry

56 200963599.0 | Africa | Nigeria NGA | 448120 | POLYGON ((26958.294 253210.950, 35554.540 4322..

I am not sure how to find the NEAREST distance between the coord points in my first dataframe to the nigeria shape border. I have tried using shapely i think but I keep getting 0 since the coordinates are inside of the polygon.

At the end result, I want to the distance from the coord point to the nearest distance to the boarder of Nigeria for all the rows in the first dataframe.

Thank you 如何在Python中找到多边形内的坐标点到多边形边缘的最近距离?

Edit -- To include more info and code
I saved the first dataset with the point coordinates as 'coord_new'

df=gpd.GeoDataFrame(coord_new,geometry=gpd.points_from_xy(coord_new.longitude, coord_new.latitude))

#df= df.to_crs(26392)

#nigeria = nigeria.to_crs(26392)

df['distance1']=nigeria.exterior.distance(df)

df['distance1']=nigeria.boundaries.distance(df)

This is the way that I saw other people doing to find the distance from point to the border of the polygon. However, I keep getting 0 and then NaN in the distance1 column.

答案1

得分: 1

你遇到的问题是在使用二进制空间操作距离涉及两个GeoDataFrames时,这两个数据框根据它们的索引进行对齐。

请注意GeoSeries.distance函数的参数:

参数:

  • other: Geoseries或几何对象
    用于查找距离的Geoseries(逐元素)或几何对象。

当你将全球的shapefile子集化为仅匹配名称为"Nigeria"的行时,你仍然得到一个GeoDataFrame,尽管只有一行。因此,距离操作是逐元素执行的,首先将dfnigeria根据它们的索引进行对齐,然后在两个数据框的行之间执行逐元素距离。由于两者之间没有共同的索引,结果是一个NaN列。

这与pandas中的操作方式相同 - 如果将具有不同索引的两个系列相加,即使其中一个长度为1,结果也将是NaN

另一方面,如果nigeria是一个shapely几何对象,而不是GeoSeries或GeoDataFrame,就没有索引可以对齐,geopandas将比较数据框中的每个元素与几何对象。在这里,与pandas类似,添加常数到一个Series,将导致每个元素与常数的有效求和。

因此,你可以修改你的代码以选择出shapely几何对象,然后将其与df中的每个元素进行比较:

# 使用`.at`来提取元素,而不是返回长度为1的DataFrame。结果将是一个shapely几何对象。
nigeria = world.at[world['name'] == 'Nigeria', 'geometry']

type(nigeria)  # shapely.geometry.MultiPolygon

# 将df中的每个元素与Nigeria的边界进行比较
df['distance1'] = df.distance(nigeria.boundary)
英文:

The issue you're encountering is that when using binary spatial operations or distance involving two GeoDataFrames, the DataFrames are aligned on their indexes.

Note the arguments to the GeoSeries.distance function:

> Parameters:
> * other: Geoseries or geometric object
> The Geoseries (elementwise) or geometric object to find the distance to.

When you subset the global shapefile to only rows matching the name "Nigeria", you're still left with a GeoDataFrame, albeit one with only one row. The distance operation is therefore performed elementwise, where first df and nigeria are aligned on their indices, and then the elementwise distance is taken between rows in the two dataframes. Since there are no common indices between the two, the result is a column of NaNs.

This works the same way as in pandas - if you add two series with different indexes together, even if one of them is length 1, you would get NaN as a result.

On the other hand, if nigeria is a shapely geometry object rather than a GeoSeries or GeoDataFrame, there is no index to align on, and geopandas will compare each element in the dataframe to the geometry. The pandas analogue here is adding a constant to a Series, which results in a valid sum of each element with the constant.

So, you can change your code to select out the shapely geometry object, then compare it to each element in df:

# use `.at` to extract the element instead of returning a length-1
# DataFrame. The result will be a shapely geometry.
nigeria = world.at[world['name'] == 'Nigeria', 'geometry']

type(nigeria)  # shapely.geometry.MultiPolygon

# compare each element in df to Nigeria's boundary
df['distance1'] = df.distance(nigeria.boundary)

huangapple
  • 本文由 发表于 2023年2月10日 02:58:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75403236.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定