1

I have successfully fount nearest X,Y point in one GeoPandas data frame to the other X,Y points in the second GeoPandas data frame. My questions is on how to find the second nearest point or (third nearest point if needed). My code is below.

    def get_nearest_values(row, other_gdf, point_column='geometry', value_column="geometry"):
    """Find the nearest point and return the corresponding value from specified value column."""
# Create an union of the other GeoDataFrame's geometries:
other_points = other_gdf["geometry"].unary_union

# Find the nearest points
nearest_geoms = nearest_points(row[point_column], other_points)

# Get corresponding values from the other df
nearest_data = other_gdf.loc[other_gdf["geometry"] == nearest_geoms[1]]

nearest_value = nearest_data[value_column].values[0]

return nearest_value



unary_union = df2.unary_union

df1["nearest_tlm"] = df1.apply(get_nearest_values, other_gdf=df2, point_column="geometry", value_column="language", axis=1)

df1

2 Answers2

1

By simply tweaking the answer provided in following link, you will be able to find the 2nd, 3rd, or nth nearest point

The tweaked code is as follows

import geopandas as gpd
import pandas as pd
import numpy as np
from scipy.spatial import cKDTree

file1 = '/path/to/point1' file2 = '/path/to/point2'

gpd1 = gpd.read_file(file1) gpd2 = gpd.read_file(file2)

def ckdnearest(gdA, gdB, nth_nearest):

nA = np.array(list(gdA.geometry.apply(lambda x: (x.x, x.y))))
nB = np.array(list(gdB.geometry.apply(lambda x: (x.x, x.y))))
btree = cKDTree(nB)
dist, idx = btree.query(nA, k=nth_nearest)
gdB_nearest = gdB.iloc[idx].drop(columns="geometry").reset_index(drop=True)
gdf = pd.concat(
    [
        gdA.reset_index(drop=True),
        gdB_nearest,
        pd.Series(dist, name='dist')
    ], 
    axis=1)

return gdf

gpd_nearest = ckdnearest(gpd1, gpd2, nth_nearest = 2)

S. Thiyaku
  • 855
  • 6
  • 17
1

This is the working code - with modifications from Ujaval Gandhi from www.spatialthoughts.com

def ckdnearest(gdA, gdB, nth_nearest):
nA = np.array(list(gdA.geometry.apply(lambda x: (x.x, x.y))))
nB = np.array(list(gdB.geometry.apply(lambda x: (x.x, x.y))))
btree = cKDTree(nB)
dist, idx = btree.query(nA, k=[nth_nearest])
gdB_nearest = gdB.iloc[idx.squeeze()].drop(columns="geometry").reset_index(drop=True)
gdf = pd.concat(
[
    gdA.reset_index(drop=True),
    gdB_nearest,
    pd.Series(dist.squeeze(), name='dist')
], 
axis=1)

return gdf

MrXsquared
  • 34,292
  • 21
  • 67
  • 117