From e1d92f19acdf0faa0204fbcda0124a2e89e1fced Mon Sep 17 00:00:00 2001 From: "niehues.mark@gmail.com" <niehues.mark@gmail.com> Date: Thu, 23 Apr 2020 19:14:25 +0200 Subject: [PATCH] routing --- evrouting/osm/imports.py | 25 +++---------------------- evrouting/osm/routing.py | 26 +++++++++++++++++++++++--- tests/osm/test_osm_charge.py | 26 +++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/evrouting/osm/imports.py b/evrouting/osm/imports.py index d0f6b23..06d2bd7 100644 --- a/evrouting/osm/imports.py +++ b/evrouting/osm/imports.py @@ -15,7 +15,6 @@ Added : import copy import xml.sax import logging -from math import radians, cos, sin, asin, sqrt from collections import namedtuple import networkx as nx @@ -24,12 +23,14 @@ import requests from evrouting.graph_tools import CHARGING_COEFFICIENT_KEY from evrouting.osm.const import ms_to_kmh from evrouting.osm.profiles import speed +from evrouting.osm.routing import find_nearest, haversine_distance logger = logging.getLogger(__name__) OsrmConf = namedtuple('OsrmConf', ['server', 'port', 'version', 'profile'], defaults=('v1', 'driving')) + def query_url(service, coordinates, osrm_config: OsrmConf): """Construct query url.""" return f'http://{osrm_config.server}:{osrm_config.port}' \ @@ -41,32 +42,12 @@ def insert_charging_stations(G, charging_stations): for s in charging_stations: lon = s['lon'] lat = s['lat'] - n = list(G.rtree.nearest((lon, lat, lon, lat), 1))[0] + n = find_nearest(G, (lat, lon)) G.nodes[n][CHARGING_COEFFICIENT_KEY] = s['power'] return G -def haversine_distance(lon1, lat1, lon2, lat2, unit_m=True): - """ - Calculate the great circle distance between two points - on the earth (specified in decimal degrees) - default unit : km - """ - # convert decimal degrees to radians - lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) - - # haversine formula - dlon = lon2 - lon1 - dlat = lat2 - lat1 - a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2 - c = 2 * asin(sqrt(a)) - r = 6371 # Radius of the Earth in kilometers. Use 3956 for miles - if unit_m: - r *= 1000 - return c * r - - class OsrmDistance: def __init__(self, osrm_config: OsrmConf = None): diff --git a/evrouting/osm/routing.py b/evrouting/osm/routing.py index fa48bae..acbe584 100644 --- a/evrouting/osm/routing.py +++ b/evrouting/osm/routing.py @@ -1,15 +1,35 @@ from typing import Tuple +from math import radians, cos, sin, asin, sqrt import networkx as nx from evrouting.osm.const import ms_to_kmh -from evrouting.osm.imports import haversine_distance lat = float lon = float point = Tuple[lat, lon] +def haversine_distance(lon1, lat1, lon2, lat2, unit_m=True): + """ + Calculate the great circle distance between two points + on the earth (specified in decimal degrees) + default unit : km + """ + # convert decimal degrees to radians + lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) + + # haversine formula + dlon = lon2 - lon1 + dlat = lat2 - lat1 + a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2 + c = 2 * asin(sqrt(a)) + r = 6371 # Radius of the Earth in kilometers. Use 3956 for miles + if unit_m: + r *= 1000 + return c * r + + def find_nearest(G, v: point): min_dist = None closest_node = None @@ -19,7 +39,7 @@ def find_nearest(G, v: point): for n in G.nodes: d = haversine_distance( G.nodes[n]['lat'], - G.nodes[n]['lot'], + G.nodes[n]['lon'], lat_v, lon_v, unit_m=True @@ -39,7 +59,7 @@ def shortest_path(G, s: point, t: point, profile): def dist(u, v): return haversine_distance( G.nodes[u]['lat'], - G.nodes[u]['lot'], + G.nodes[u]['lon'], G.nodes[v]['lat'], G.nodes[v]['lon'], unit_m=True diff --git a/tests/osm/test_osm_charge.py b/tests/osm/test_osm_charge.py index 0d8406d..fffd316 100644 --- a/tests/osm/test_osm_charge.py +++ b/tests/osm/test_osm_charge.py @@ -6,6 +6,7 @@ import rtree from evrouting.osm.imports import read_osm, insert_charging_stations from evrouting.osm.profiles import car +from evrouting.osm.routing import shortest_path from evrouting.graph_tools import CHARGING_COEFFICIENT_KEY @@ -29,11 +30,13 @@ def graph(): del G -def test_read_osm(): - """Just check if it runs. Todo: Delete.""" +@pytest.fixture +def map_graph(): G = read_osm(os.path.join(os.path.dirname(__file__), 'static/map.osm'), car) - assert True + yield G + del G + def test_insert_charging_stations_close(graph): # Close two node 1 @@ -53,3 +56,20 @@ def test_insert_charging_stations_eq(graph): assert graph.nodes[0][CHARGING_COEFFICIENT_KEY] == 22.0 assert CHARGING_COEFFICIENT_KEY not in graph.nodes[1] + + +def test_shortest_route(map_graph): + s = (51.7769461, 6.9832152) + t = (51.7796487, 6.9795230) + + route = [ + "1827268706", + "1826594887", + "4955446046", + "4955446048", + "34053450", + "4955446051", + "418009799" + ] + + assert route == shortest_path(map_graph, s, t, car) -- GitLab