Find the Nearest Node to a Point Using OSMnx Distance Module
Last Updated :
21 Mar, 2024
Nearest neighbor search algorithms are crucial for robust navigation. OSMnx makes use of different types of nearest neighbor search algorithms for the projected and unprotected graph. In this article, we will see how we can find the nearest node to a point using OSMnx distance module in Python.
Syntax of osmnx.distance.nearest_nodes() Function
osmnx.distance.nearest_nodes(G, X, Y, return_dist=False)
Parameters:
- G (networkx.MultiDiGraph) – graph in which to find nearest nodes
- X (float or list) – points’ x (longitude) coordinates, in same CRS/units as graph and containing no nulls
- Y (float or list) – points’ y (latitude) coordinates, in same CRS/units as graph and containing no nulls
- return_dist (bool) – optionally also return distance between points and nearest nodes
Returns: nn or (nn, dist) – nearest node IDs or optionally a tuple where dist contains distances between the points and their nearest nodes
Return Type: int/list or tuple
Note: install geopandas==0.14.3, osmnx==1.9.1, notebook==7.0.7, folium==0.15.1, matplotlib==3.8.2, mapclassify==2.6.1
Nearest Node to a Point for an Unprojected Graph Using OSMnx Module
If graph is unprojected, OSMnx distance module uses Ball Tree algorithm for nearest neighbor search. In Ball Tree algorithm, the total space of training data is divided into multiple circular blocks. Each circular block has a centroid point and has set of node points (location points).
For nearest node search, ball tree algorithm calculates the distance of a node with the centroid point rather than calculating the distance with all nodes in the data set. Then the training data set (to identify the nearest node) is taken from the circular block, which has the nearest centroid point.
Note: requires scikit-learn as an optional dependency
Let's find the nearest node to a point for an unprojected graph using osmnx distance module. As a first step, we need multidigraph of a place. Below code fetch multidigraph of Punalur, Kerala.
Python3
import osmnx as ox
# fecth multi digraph from place
multi_digraph = ox.graph_from_place('Punalur, Kerala')
Review the Nodes
Let's review the nodes by plotting it on a map. The code as follows:
Python3
# convert multidigraph nodes to geodataframe
gdf_nodes = ox.utils_graph.graph_to_gdfs(
multi_digraph, nodes=True, edges=False, node_geometry=True,
fill_edge_geometry=False)
# display it on map
gdf_nodes.explore()
Output
Punalur nodesFind Nearest Node
Now we can use the osmnx distance module to find the nearest node. Let's take Chadayamangalam as a point and we need to identify the nearest node from our multidigraph. The code as follows:
Python3
# chadayamangalam coordinates
chadaya_lat, chadaya_lon = 8.873103284974913, 76.86933422158793
nearest_node = ox.distance.nearest_nodes(multi_digraph,
chadaya_lon, chadaya_lat,
return_dist=True)
Output
(8245709348, 1367.182397021979)
Fetch Geometry of Node ID
It returns the nearest node id and the distance in meters. Let's fetch the geometry of the node id from the above geodataframe.
Python3
# fetch the node geometry based on node id
nearest_node_id = nearest_node[0]
gdf_nodes.loc[nearest_node_id]
Output
y 8.881764
x 76.860501
highway NaN
street_count 3
geometry POINT (76.8605012 8.8817642)
Name: 8245709348, dtype: object
Let's review by plotting it on a map.
Python3
import geopandas as gpd
from shapely import (
Point, LineString)
# create a new geodataframe with the nearest node and new point
nearest_node_dict = {'col1': ['Chadayamangalam', 'Nearest Node'],
'geometry': [Point(chadaya_lon, chadaya_lat),
LineString([
Point(gdf_nodes.loc[nearest_nodeid].x,
gdf_nodes.loc[nearest_nodeid].y),
Point(chadaya_lon, chadaya_lat)])]}
# convert dictionary to geodataframe
nearest_node_gdf = gpd.GeoDataFrame(nearest_node_dict, crs="EPSG:4326")
# nearest node map reference
nearest_node_map = nearest_node_gdf.explore(color="red")
# combine nearest node with existing node map
gdf_nodes.explore(m=nearest_node_map)
Output
Nearest Node You can notice a line (in red color) from chadayamangalam to the nearest node in our punalur geodataframe.
Nearest Node to a Point for an Projected Graph Using OSMnx Module
If graph is projected, OSMnx distance module uses KD tree algorithm for nearest neighbor search. In K-D tree algorithm, the points can be organized in a K-Dimensional space. A non-leaf node in K-D tree divide the space into two parts. Points to the left of the space are represented by the left subtree of the node and points to the right of the space are represented by the right subtree.
The root node has an x-aligned plane (right aligned). For a new node, if the x value of root node is less than the x value of new node, then the new node will be left aligned (y aligned). If the node is x aligned then the x value is considered for comparison or if the node is y aligned then the y value is considered. If the points are equal, then the node is considered as right aligned.
Note: requires scipy as an optional dependency
Let's take the same multidigraph (Punalur) from the above code. The point to note, here we need projected graph. But our existing multidigraph is an unprotected graph. Let's check it.
Python3
import geopandas as gpd
import osmnx as ox
# fecth multi digraph from place
multi_digraph = ox.graph_from_place('Punalur, Kerala')
# fetch the crs from multidigraph
crs = multi_digraph.graph["crs"]
# check whether the crs is projected
gpd.GeoSeries(crs=crs).crs.is_projected
Output
False
Since our graph is unprojected, we need to convert it to a projected graph. As a first step, we need to convert multidigraph to geodataframe and then change it to projected graph using geopandas. Finally convert the projected geodataframe back to multidigraph. The code as follows:
Python3
import osmnx as ox
import geopandas as gpd
# convert multidigraph nodes to geodataframe
gdf_nodes = ox.utils_graph.graph_to_gdfs(
multi_digraph, nodes=True, edges=False,
node_geometry=True, fill_edge_geometry=False)
# convert multidigraph edges to geodataframe
gdf_edges = ox.utils_graph.graph_to_gdfs(
multi_digraph, nodes=False, edges=True,
node_geometry=False, fill_edge_geometry=True)
# convert geodataframe nodes to projected gdf noded
gdf_nodes['geometry'] = gdf_nodes.geometry.to_crs("EPSG:7781")
# let's change the x and y columns with projected geometry coordinates
gdf_nodes['x'] = gdf_nodes['geometry'].x
gdf_nodes['y'] = gdf_nodes['geometry'].y
# convert geodataframe edges to projected gdf edges
gdf_edges['geometry'] = gdf_edges.geometry.to_crs("EPSG:7781")
# set crs attribute
graph_attrs = {"crs": "EPSG:7781"}
# convert projected geodataframe to multidigraph
proj_multidigraph = ox.utils_graph.graph_from_gdfs(
gdf_nodes, gdf_edges, graph_attrs=graph_attrs)
# check for projection
crs = proj_multidigraph.graph["crs"]
gpd.GeoSeries(crs=crs).crs.is_projected
Output
True
Note: EPSG:7781 is a projected coordinate system for Kerala
Now we have a projected MultiDigraph of Punalur. Let's find the nearest node using OSMnx distance module. Since we have a projected multidigraph, It is important to pass the X and Y coordinate in the same CRS. We can take Kokad coordinates and check for the nearest node in our multidigraph from Kokad.
The code to get projected coordinates of Kokad as follows:
Python3
import geopandas as gpd
from shapely import Point
# set geodataframe
kokad_lat, kokad_lon = 8.984569551375083, 76.87386194013466
kokad_node_dict = {'col1': ['Kokad'],
'geometry': [Point(kokad_lon, kokad_lat)]}
kokad_node_gdf = gpd.GeoDataFrame(kokad_node_dict, crs="EPSG:4326")
# convert it to projected coordinates
kokad_node_gdf['geometry'] = kokad_node_gdf.geometry.to_crs("EPSG:7781")
# get projected coordinates
kokad_proj_lon = kokad_node_gdf['geometry'].x
kokad_proj_lat = kokad_node_gdf['geometry'].y
Now let's make use of OSMnx distance module to find the nearest node from Kokad. The code as show below:
Python3
# find the nearest node from kokad
nearest_node = ox.distance.nearest_nodes(
proj_multidigraph, kokad_proj_lon, kokad_proj_lat,
return_dist=True)
Output
(8249763424, 1082.6126641017327)
The nearest node id from Kokad is 8249763424 and the distance is 1082.6126641017327 meters.
Python3
nearest_nodeid = nearest_node[0]
# fetch the data based om node id
gdf_nodes.loc[nearest_nodeid]
Output
y 831489.012826
x 1096441.200688
highway NaN
street_count 3
geometry POINT (1096441.200687849 831489.0128263424)
Name: 8249763424, dtype: object
Let's plot it in map for better understanding. The code as follows:
Python3
# get the nearest node id
nearest_nodeid = nearest_node[0]
# create a dictionary with Kokad point and Nearest node coordinates
nearest_node_dict = {'col1': ['Kokad', 'Nearest Node'],
'geometry': [Point(kokad_proj_lon, kokad_proj_lat),
LineString([
Point(gdf_nodes.loc[nearest_nodeid].x,
gdf_nodes.loc[nearest_nodeid].y),
Point(kokad_proj_lon, kokad_proj_lat)])]}
# convert to geodataframe
nearest_node_gdf = gpd.GeoDataFrame(nearest_node_dict, crs="EPSG:7781")
# get nearest node map and display it with our dataset
nearest_node_map = nearest_node_gdf.explore(color="red")
gdf_nodes.explore(m=nearest_node_map)
Output
You can notice a line (in red color) from Kokad to the nearest node in our punalur geodataframe.
Nearest node projected graph
Similar Reads
Find the Nearest Edge to a Point Using Python OSMnx Distance Module OSMnx distance module can find the nearest edge to a point using the nearest_edges functionality. In this article, we will see how to find the nearest edge to a point using the OSMnx distance Module in Python. Syntax of osmnx.distance.nearest_edges() FunctionHere, the below function uses an R-tree s
5 min read
Get OSM Features Within a Distance of a Point Using Python OSMnx Feature Module In this article, we will see how we can get open street map features within a distance of a point (latitude-longitude) using the OSMnx feature module in Python. Syntax of osmnx.features.features_from_point() FunctionThe function creates a GeoDataFrame of OSM features within some distance of a point
3 min read
Calculate Euclidean Distance Using Python OSMnx Distance Module Euclidean space is defined as the line segment length between two points. The distance can be calculated using the coordinate points and the Pythagoras theorem. In this article, we will see how to calculate Euclidean distances between Points Using the OSMnx distance module. Syntax of osmnx.distance.
4 min read
Get OSM Features Within a Distance of Address Using OSMnx Feature Module OpenStreetMap provides physical features on the ground (e.g ., roads, buildings, etc.) using tags attached to its basic data structure (nodes, ways, and relations). Each tag describes a geographic attribute of the feature for the specific node, way, or relation. In this article, we will see how we c
6 min read
Find the nearest value and the index of NumPy Array In this article, let's discuss finding the nearest value and the index in an array with Numpy. We will make use of two of the functions provided by the NumPy library to calculate the nearest value and the index in the array. Those two functions are numpy.abs() and numpy.argmin(). Example Input Arra
3 min read
Find Shortest Path Using Python OSMnx Routing Module This article demonstrates how to use the OSMnx routing module to find the shortest path, illustrated with practical examples. Syntax of osmnx.routing.shortest_path() FunctionOSMnx routing module has the 'shortest_path' functionality to find the nearest path from the origin node to the destination no
3 min read
Calculate Great Circle Distances Between Pairs of Points Using OSMnx Module The Great Circle Distance evaluates the shortest distance between two points considering Earth as a sphere. It is an arc linking two points on a sphere. Here, we will see how to calculate great circle distances between pairs of points using the OSMnx distance module. Syntax of osmnx.distance.great_c
3 min read
Calculate Graph Total Edge Length Using Python OSMnx Stats Module In this article, we will see how to calculate graphs' total edge length using the OSMNx stats Module. Explore urban connectivity with precision using the OSMnx stats module, which allows us to effortlessly calculate the total edge length of graphs derived from OpenStreetMap data, providing valuable
2 min read
Calculate the Euclidean distance using NumPy Euclidean distance is the shortest between the 2 points irrespective of the dimensions. In this article to find the Euclidean distance, we will use the NumPy library. This library used for manipulating multidimensional array in a very efficient way. Let's discuss a few ways to find Euclidean distanc
2 min read
Calculate Average Street Circuity Using OSMnx stats Module Circuity is defined as a lack of straightforwardness and it is a result of a circulation network configuration. It impacts how we use urban space for settlement and travel. Calculating the average circuity of a city provides insights about direct routes in a transportation network. In this article,
2 min read