I want to join a GeoDataFrame with Polygons (circular, were created from Points with buffer) with a GeoDataFrame that has Linestrings. These polygons and lines do not necessarily intersect nor contain each other (might have a polygon in between two lines), and I would like to join them based on which polygon is closest to a linestring.

Is there a way to do so using GeoPandas (not using ArcPy)?

Data sample:

df_pts:                    df_lines:
    id | geometry              id | geometry
    p1 | POLYGON( .. )         l8 | LINESTRING( .. )
    p2 | POLYGON( .. )         l11| LINESTRING( .. )

What I have tried so far:

import geopandas as gpd
from shapely.geometry import Point, LineString

df_pts['buffer'] = df_pts.geometry.buffer(2)
df_lines = gpd.read_file('from_shape_file.shp')
df_join = gpd.sjoin(df_pts, df_lines, how="inner", op='intersects')

The problem with my current code is that it will miss cases where the buffered points in df_pts aren't 'touching' the lines.


The geopandas.sjoin function only supports the 'intersects', 'within' and 'contains' predicates, and not a "nearest" one.

You can write a custom function to find the id of the nearest linestring for each polygon, and then merge on that. This could look like:

def nearest_linestring(polygon, df_lines):
    idx = df_lines.geometry.distance(polygon).idxmin()
    return df_lines.loc[idx, 'id']

df_polygon['id_nearest_line'] = df_polygon.geometry.apply(nearest_linestring, df_lines=df_lines)

pd.merge(df_polygon, df_lines, right_on='id_nearest_line', left_on='id',how='inner')

However, an important remark with this approach: it will only find a single nearest one, so if you had for a certain polygon multiple linestrings that are intersecting with it, it will not give them all. It should be possible to update the function for that though.
Second remark: if you have a lot of data, calculating the distance for all linestrings like the in the function above might not be very efficient. You could use spatial index to improve this, but I would only worry about that if the speed turns out to actually be a problem.

Your Answer

