[GIS] Finding all possible adjacent/closest geometrical points from a given point

geopandaspandaspointpythonshapely

So, I have a dataframe like this,

import numpy as np
import pandas as pd
import descartes
from shapely.geometry import Point, Polygon
import geopandas as gpd
import matplotlib.pyplot as plt


df = pd.DataFrame({'Address':['280 Broadway','1 Liberty Island','141 John Street'],
                   'Latitude':[ 40.71,40.69,40.71],
                   'Longitude':[-74.01,-74.05,-74.00]
                    }) 


%matplotlib inline

geometry = [Point(xy) for xy in zip( df["Longitude"],df["Latitude"])]
crs = {'init':'epsg:4326'}
df = gpd.GeoDataFrame(df,
                     crs=crs,
                    geometry=geometry)
df.head()

I converted the lat and lon to geometry points and I am trying to find all possible closest points for each address using the geometrical points. For example, all possible closest points adjacent to 280 Broadway which lies next to each other for one block.There could be more than one point if the points are adjacent to each other containing in a polygon shape.

This was my approach but didn't really get what I wanted,

df.insert(4, 'nearest_geometry', None)
from shapely.geometry import Point, MultiPoint
from shapely.ops import nearest_points

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 

Desired Output:

Address       Lat     Lon    geometry                    nearest_points
280 Broadway  40.71  -74.01  POINT (-74.01000 40.71000)  POINT(NEAREST GEOMETRIC POINT)

Best Answer

I don't know about geopandas specifically, but I would use shapely's STRTree for this task. It has a nearest method:

from shapely.geometry import Point
from shapely.strtree import STRtree

points = [
    Point(1, 1),
    Point(2, 2),
    Point(3, 3)
]

tree = STRtree(points)

print(tree.nearest(Point(0, 0)).wkt)
print(tree.nearest(Point(5, 5)).wkt)

This will yield

POINT (1 1)
POINT (3 3)
Related Question