Python: how to detect the adjacent nodes of a point in a geopandas dataframe?

Viewed 65

I have a geoepandas dataframe that looks like the following:

df = pd.DataFrame()
df['x']=[0,1,3,0,1,3,0,1,3]
df['y']=[0,0,0,1.5,1.5,1.5,2.5,2.5,2.5]
points=[]
for i in df.index:
    points.append(Point(df['x'][i],df['y'][i]))

gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.x, df.y))
f,ax=plt.subplots()
gdf.plot(color='red',ax=ax)

enter image description here

where gdf is the following

    x     y     geometry
0   0   0.0     POINT (0.00000 0.00000)
1   1   0.0     POINT (1.00000 0.00000)
2   3   0.0     POINT (3.00000 0.00000)
3   0   1.5     POINT (0.00000 1.50000)
4   1   1.5     POINT (1.00000 1.50000)
5   3   1.5     POINT (3.00000 1.50000)
6   0   2.5     POINT (0.00000 2.50000)
7   1   2.5     POINT (1.00000 2.50000)
8   3   2.5     POINT (3.00000 2.50000)

I would like to detect the adjacent nodes (only in the vertical and horizontal directions) and have a dataframe like the following:

    x     y     geometry                   adjacent
0   0   0.0     POINT (0.00000 0.00000)    [1,3]
1   1   0.0     POINT (1.00000 0.00000)    [0,2,4]
2   3   0.0     POINT (3.00000 0.00000)    [1,5]
3   0   1.5     POINT (0.00000 1.50000)    [0,4,6]
4   1   1.5     POINT (1.00000 1.50000)    [1,3,5,7]
5   3   1.5     POINT (3.00000 1.50000)    [2,4,8]
6   0   2.5     POINT (0.00000 2.50000)    [3,7]
7   1   2.5     POINT (1.00000 2.50000)    [4,6]
8   3   2.5     POINT (3.00000 2.50000)    [5,7]
1 Answers

The rook criterion in pysal's Voronoi weights can do this.

import os
import pandas as pd
import geopandas as gpd
import shapely
from shapely.geometry import Point
import matplotlib.pyplot as plt
import pysal
import numpy as np
from libpysal.weights import Voronoi


df = pd.DataFrame()
df['x']=[0,1,3,0,1,3,0,1,3]
df['y']=[0,0,0,1.5,1.5,1.5,2.5,2.5,2.5]
points=[]
for i in df.index:
    points.append(Point(df['x'][i],df['y'][i]))

gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.x, df.y))
f, ax=plt.subplots()
gdf.plot(color='red',ax=ax)


for idx, row in df.iterrows():
    ax.annotate(str(idx), (df['x'][idx], df['y'][idx])
    
    
points = df[['x', 'y']].to_numpy()
w = Voronoi(points, criterion='rook')
neighbors_dict = w.neighbors

df['adjacent'] = df.index.map(neighbors_dict)

print(df)

    x   y   geometry                adjacent
0   0   0.0 POINT (0.00000 0.00000) [1, 3]
1   1   0.0 POINT (1.00000 0.00000) [0, 2, 4]
2   3   0.0 POINT (3.00000 0.00000) [1, 5]
3   0   1.5 POINT (0.00000 1.50000) [0, 4, 6]
4   1   1.5 POINT (1.00000 1.50000) [1, 3, 5, 7]
5   3   1.5 POINT (3.00000 1.50000) [8, 2, 4]
6   0   2.5 POINT (0.00000 2.50000) [3, 7]
7   1   2.5 POINT (1.00000 2.50000) [8, 4, 6]
8   3   2.5 POINT (3.00000 2.50000) [5, 7]
Related