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
Determine a CRS is Projected or Not Using Python OSMnx projection Module
The coordinate reference system (CRS) is a framework that measures locations on the earth's surface as coordinates. Geographic Coordinate Reference System uses latitude and longitude to specify a location on Earth (unit in degrees). On the other hand, the Projected Coordinate System employs a two-di
2 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 Compass Bearing Using Python OSMnx Bearing Module
Bearing is a significant angle for Geographic Information System (GIS) applications. In this article, we will see how to calculate the compass Bearing using the OSMnx bearing module based on lat-Ion Points. What is Bearing?Bearing represents the clockwise angle in degrees between the north and the g
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