簡體   English   中英

如何使用 geopanda 或 shapely 在同一地理數據框中找到最近的點

[英]How to use geopanda or shapely to find nearest point in same geodataframe

我有一個顯示約 25 個位置的地理數據框,表示為點幾何。 我試圖想出一個腳本,通過每個點,標識最近的位置並返回最近位置的名稱和距離。

如果我使用 shapely.ops 庫中的nearest_points(geom1, geom2) 有不同的地理數據框,我可以輕松地做到這一點。 然而,我所有的位置都存儲在一個地理數據框中。 我正在嘗試循環,這就是我遇到麻煩的地方

這是我的示例文件:

geofile = gpd.GeoDataFrame([[0, 'location A', Point(55, 55)],
                            [1, 'location B', Point(66, 66)],
                            [2, 'Location C', Point(99, 99)],
                            [3, 'Location D', Point(11, 11)]],
                           columns=['ID','Location','geometry'])

這是我創建的循環無濟於事。

for index, row in geofile.iterrows():
    nearest_geoms=nearest_points(row, geofile)
    print('location:' + nearest_geoms[0])
    print('nearest:' + nearest_geoms[1])
    print('-------')

我收到此錯誤:

AttributeError: 'Series' object has no attribute '_geom'

但是我認為我的問題超出了錯誤原因,我必須排除我正在循環的行,因為它是那個位置,它將自動返回為最近的位置。

我對一個位置的最終結果如下:

([0,'location A','location B', '5 miles', Point(55,55)], columns=['ID','Location','Nearest', 'Distance',geometry'])

Shapely的Nearest_points函數比較形狀的幾何形狀。 要將單個Point幾何與多個其他Point幾何進行比較,可以使用.unary_union與生成的MultiPoint幾何進行比較。 是的,在每個行操作中,都放下相應的點,這樣就不會將其與自身進行比較。

import geopandas as gpd
from shapely.geometry import Point
from shapely.ops import nearest_points

df = gpd.GeoDataFrame([[0, 'location A', Point(55,55)], 
                       [1, 'location B', Point(66,66)],
                       [2, 'Location C', Point(99,99)],
                       [3, 'Location D' ,Point(11,11)]], 
                      columns=['ID','Location','geometry'])
df.insert(3, 'nearest_geometry', None)

for index, row in df.iterrows():
    point = row.geometry
    multipoint = df.drop(index, axis=0).geometry.unary_union
    queried_geom, nearest_geom = nearest_points(point, multipoint)
    df.loc[index, 'nearest_geometry'] = nearest_geom

導致

    ID  Location    geometry        nearest_geometry
0   0   location A  POINT (55 55)   POINT (66 66)
1   1   location B  POINT (66 66)   POINT (55 55)
2   2   Location C  POINT (99 99)   POINT (66 66)
3   3   Location D  POINT (11 11)   POINT (55 55)

在此處輸入圖片說明

這是另一種基於scipy.spatial.distance.cdist 通過使用 numpy 掩碼數組避免了iterrows

import geopandas as gpd
from scipy.spatial import distance
import numpy.ma as ma

df = gpd.GeoDataFrame([[0, 'location A', Point(55,55)], 
                       [1, 'location B', Point(66,66)],
                       [2, 'Location C', Point(99,99)],
                       [3, 'Location D' ,Point(11,11)]], 
                      columns=['ID','Location','geometry'])

coords = np.stack(df.geometry.apply(lambda x: [x.x, x.y]))
distance_matrix = ma.masked_where((dist := distance.cdist(*[coords] * 2)) == 0, dist)
df["closest_ID"] = np.argmin(distance_matrix, axis=0)
df = df.join(df.set_index("ID").geometry.rename("nearest_geometry"), on="closest_ID")
df.drop("closest_ID", axis=1)

# Out:
   ID    Location               geometry           nearest_geometry
0   0  location A  POINT (55.000 55.000)  POINT (66.00000 66.00000)
1   1  location B  POINT (66.000 66.000)  POINT (55.00000 55.00000)
2   2  Location C  POINT (99.000 99.000)  POINT (66.00000 66.00000)
3   3  Location D  POINT (11.000 11.000)  POINT (55.00000 55.00000)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM