carbassot
carbassot

Reputation: 151

OSMnx: angle between nodes

As I mentioned in the title I need to find the angle between nodes. I have a list of nodes with the ids of the nodes of a route. I have thought on doing it somehow using the 'x' and 'y' coordinates but I am not arriving at any conclusions. Also, I've been told about using 'bearings', but again I don't really know how to use it, hence I don't get the proper result.

(I am using Networkx and OSMnx)

Being id_src and id_dst the ids of two consecutive nodes:

G.edges[(id_src, id_dst, 0)]['bearing']

Upvotes: 2

Views: 1142

Answers (2)

Debjit Bhowmick
Debjit Bhowmick

Reputation: 950

Import OSMnx

import osmnx as ox

Import the graph of Melbourne

address_name='Melbourne'
G=ox.graph_from_address(address_name, distance=50)

Create nodes and edges geodataframes from the graph

nodes, edges = ox.graph_to_gdfs(G, nodes=True, edges=True)

Calculate edge bearings and make a pandas series out of them

import pandas as pd
G = ox.add_edge_bearings(G)
bearings = pd.Series([data['bearing'] for u, v, k, data in G.edges(keys=True, data=True)], name='bearing')

Concatenate the series with the edges geodataframe to have the edge bearings in the same edges geodataframe

edges = pd.concat([edges, bearings], axis=1)

Example:

print('Bearing between nodes '+str(edges['u'][0])+' and '+str(edges['v'][0])+' is '+str(edges['bearing'][0]))

Bearing between nodes 6167413263 and 6167441066 is 69.48

You may use the following function for calculation of bearings between any two nodes, although it does not entirely match up with the calculated bearings, but is fairly accurate.

def bearing(G,node1,node2):
    import math
    node1lat = nodes.at[node1, 'y']
    node1lon = nodes.at[node1, 'x']
    node2lat = nodes.at[node2, 'y']
    node2lon = nodes.at[node2, 'x']
    londiff = node2lon - node1lon 
    print('londiff: '+str(londiff))
    latdiff = node2lat - node1lat
    print('latdiff: '+str(latdiff))
    if latdiff > 0 and londiff > 0: # Quadrant1
        bearing = 90.0 - math.degrees(math.atan2(latdiff,londiff))
    elif latdiff < 0 and londiff > 0: #Qaudrant2
        bearing = 90.0 - math.degrees(math.atan2(latdiff,londiff))
    elif latdiff < 0 and londiff < 0: #Qaudrant3
        bearing = 90.0 - math.degrees(math.atan2(latdiff,londiff))
    elif latdiff > 0 and londiff < 0: #Qaudrant4
        bearing = 450.0 - math.degrees(math.atan2(latdiff,londiff))

    return bearing

Upvotes: 2

gboeing
gboeing

Reputation: 6422

If by angle you mean bearing, then you can use the add_edge_bearings function to get the bearing of each edge (i.e., from node u to nodev if u and v are adjacent in the graph). This gives each edge an absolute bearing attribute, that is, the angle (from the source node) between north and the destination node.

import osmnx as ox
ox.config(use_cache=True, log_console=True)
G = ox.graph_from_place('Piedmont, California, USA', network_type='drive')
G = ox.add_edge_bearings(G)
gdf_edges = ox.graph_to_gdfs(G, nodes=False)
gdf_edges[['u', 'v', 'bearing']].head(1)
# returns 53090322 53090323 140.383

In this example, we can see that the bearing from node 53090322 to node 53090323 is 140.4 degrees.

Upvotes: 3

Related Questions