diff --git a/Pipfile b/Pipfile index 396fbfe7bedd4c442be187865d3be3431d187cce..17c4b913cdd89e63c8c2a3286acc7438a76f7dd0 100644 --- a/Pipfile +++ b/Pipfile @@ -10,8 +10,7 @@ pandas = "*" [packages] networkx = "*" network2tikz = {editable = true,path = "/home/mark/Projekte/network2tikz"} -aiohttp = "*" -cchardet = "*" +requests = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index c5f337147a960eb87a18cba62c13a0cd90105056..3dc7f8266da11e8f1cce9a7c770e58a2d2185944 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "fc86a7b43db104513782b90f61e1233a4f1d49415d6fab92cfc6b53a2af94753" + "sha256": "e32e5dcd04aab442923fb70d6bf8cc3b630fbbd8a936b3a45011d74810328e23" }, "pipfile-spec": 6, "requires": { @@ -16,72 +16,12 @@ ] }, "default": { - "aiohttp": { + "certifi": { "hashes": [ - "sha256:1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", - "sha256:259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", - "sha256:2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", - "sha256:32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", - "sha256:344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", - "sha256:460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", - "sha256:4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", - "sha256:50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", - "sha256:6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", - "sha256:65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", - "sha256:ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", - "sha256:b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965" + "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304", + "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519" ], - "index": "pypi", - "version": "==3.6.2" - }, - "async-timeout": { - "hashes": [ - "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", - "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" - ], - "version": "==3.0.1" - }, - "attrs": { - "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" - ], - "version": "==19.3.0" - }, - "cchardet": { - "hashes": [ - "sha256:0f6e4e464e332da776b9c1a34e4e83b6301d38c2724efc93848c46ade66d02bb", - "sha256:217a7008bd399bdb61f6a0a2570acc5c3a9f96140e0a0d089b9e748c4d4e4c4e", - "sha256:27b0f23088873d1dd36d2c8a2e45c9167e312e1aac7e4baeb47f7428a2669638", - "sha256:2a958fb093f69ee5f16be7a1aee5122e07aff4350fa4dc9b953b87c34468e605", - "sha256:2aa1b008965c703ad6597361b0f6d427c8971fe94a2c99ec3724c228ae50d6a6", - "sha256:2c05b66b12f9ab0493c5ffb666036fd8c9004a9cc9d5a9264dc24738b50ab8c3", - "sha256:4096759825a130cb27a58ddf6d58e10abdd0127d29fbf53fde26df7ad879737b", - "sha256:40c199f9c0569ac479fae7c4e12d2e16fc1e8237836b928474fdd228b8d11477", - "sha256:4486f6e5bdf06f0081d13832f2a061d9e90597eb02093fda9d37e3985e3b2ef2", - "sha256:54d2653520237ebbd2928f2c0f2eb7c616ee2b5194d73d945060cd54a7846b64", - "sha256:5e38cfad9d3ca0f571c4352e9ca0f5ab718508f492a37d3236ae70810140e250", - "sha256:68409e00d75ff13dd7a192ec49559f5527ee8959a51a9f4dd7b168df972b4d44", - "sha256:79b0e113144c2ef0050bc9fe647c7657c5298f3012ecd8937d930b24ddd61404", - "sha256:7a2d98df461d3f36b403fdd8d7890c823ed05bd98eb074412ed56fbfedb94751", - "sha256:7bba1cbb4358dc9a2d2da00f4b38b159a5483d2f3b1d698a7c2cae518f955170", - "sha256:84d2ce838cf3c2fe7f0517941702d42f7e598e5173632ec47a113cd521669b98", - "sha256:8b1d02c99f6444c63336a76638741eaf4ac4005b454e3b8252a40074bf0d84a1", - "sha256:8f7ade2578b2326a0a554c03f60c8d079331220179a592e83e143c9556b7f5b2", - "sha256:953fe382304b19f5aa8fc2da4b092a3bb58a477d33af4def4b81abdce4c9288c", - "sha256:acc96b4a8f756af289fa90ffa67ddef57401d99131e51e71872e3609483941ce", - "sha256:af284494ea6c40f9613b4d939abe585eb9290cb92037eab66122c93190fcb338", - "sha256:b76afb2059ad69eab576949980a17413c1e9e5a5624abf9e43542d8853f146b3", - "sha256:ccb9f6f06265382028468b47e726f2d42539256fb498d1b0e473c39037b42b8a", - "sha256:cf134e1cfb0c53f08abb1ab9158a7e7f859c3ddb451d5fe535a2cc5f2958a688", - "sha256:dff9480d9b6260f59ad10e1cec5be13905be5da88a4a2bd5a5bd4d49c49c4a05", - "sha256:e27771798c8ad50df1375e762d59369354af94eb8ac21eca5bfd1eeef589f545", - "sha256:f245f045054e8d6dab2a0e366d3c74f3a47fb7dec2595ae2035b234b1a829c7a", - "sha256:f5c94994d876d8709847c3a92643309d716f43716580a2e5831262366a9ee8b6", - "sha256:fd16f57ce42a72397cd9fe38977fc809eb02172731cb354572f28a6d8e4cf322" - ], - "index": "pypi", - "version": "==2.1.6" + "version": "==2020.4.5.1" }, "chardet": { "hashes": [ @@ -104,28 +44,6 @@ ], "version": "==2.9" }, - "multidict": { - "hashes": [ - "sha256:317f96bc0950d249e96d8d29ab556d01dd38888fbe68324f46fd834b430169f1", - "sha256:42f56542166040b4474c0c608ed051732033cd821126493cf25b6c276df7dd35", - "sha256:4b7df040fb5fe826d689204f9b544af469593fb3ff3a069a6ad3409f742f5928", - "sha256:544fae9261232a97102e27a926019100a9db75bec7b37feedd74b3aa82f29969", - "sha256:620b37c3fea181dab09267cd5a84b0f23fa043beb8bc50d8474dd9694de1fa6e", - "sha256:6e6fef114741c4d7ca46da8449038ec8b1e880bbe68674c01ceeb1ac8a648e78", - "sha256:7774e9f6c9af3f12f296131453f7b81dabb7ebdb948483362f5afcaac8a826f1", - "sha256:85cb26c38c96f76b7ff38b86c9d560dea10cf3459bb5f4caf72fc1bb932c7136", - "sha256:a326f4240123a2ac66bb163eeba99578e9d63a8654a59f4688a79198f9aa10f8", - "sha256:ae402f43604e3b2bc41e8ea8b8526c7fa7139ed76b0d64fc48e28125925275b2", - "sha256:aee283c49601fa4c13adc64c09c978838a7e812f85377ae130a24d7198c0331e", - "sha256:b51249fdd2923739cd3efc95a3d6c363b67bbf779208e9f37fd5e68540d1a4d4", - "sha256:bb519becc46275c594410c6c28a8a0adc66fe24fef154a9addea54c1adb006f5", - "sha256:c2c37185fb0af79d5c117b8d2764f4321eeb12ba8c141a95d0aa8c2c1d0a11dd", - "sha256:dc561313279f9d05a3d0ffa89cd15ae477528ea37aa9795c4654588a3287a9ab", - "sha256:e439c9a10a95cb32abd708bb8be83b2134fa93790a4fb0535ca36db3dda94d20", - "sha256:fc3b4adc2ee8474cb3cd2a155305d5f8eda0a9c91320f83e55748e1fcb68f8e3" - ], - "version": "==4.7.5" - }, "network2tikz": { "editable": true, "path": "/home/mark/Projekte/network2tikz" @@ -164,27 +82,20 @@ ], "version": "==1.18.3" }, - "yarl": { + "requests": { + "hashes": [ + "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee", + "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6" + ], + "index": "pypi", + "version": "==2.23.0" + }, + "urllib3": { "hashes": [ - "sha256:0c2ab325d33f1b824734b3ef51d4d54a54e0e7a23d13b86974507602334c2cce", - "sha256:0ca2f395591bbd85ddd50a82eb1fde9c1066fafe888c5c7cc1d810cf03fd3cc6", - "sha256:2098a4b4b9d75ee352807a95cdf5f10180db903bc5b7270715c6bbe2551f64ce", - "sha256:25e66e5e2007c7a39541ca13b559cd8ebc2ad8fe00ea94a2aad28a9b1e44e5ae", - "sha256:26d7c90cb04dee1665282a5d1a998defc1a9e012fdca0f33396f81508f49696d", - "sha256:308b98b0c8cd1dfef1a0311dc5e38ae8f9b58349226aa0533f15a16717ad702f", - "sha256:3ce3d4f7c6b69c4e4f0704b32eca8123b9c58ae91af740481aa57d7857b5e41b", - "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b", - "sha256:5b10eb0e7f044cf0b035112446b26a3a2946bca9d7d7edb5e54a2ad2f6652abb", - "sha256:6faa19d3824c21bcbfdfce5171e193c8b4ddafdf0ac3f129ccf0cdfcb083e462", - "sha256:944494be42fa630134bf907714d40207e646fd5a94423c90d5b514f7b0713fea", - "sha256:a161de7e50224e8e3de6e184707476b5a989037dcb24292b391a3d66ff158e70", - "sha256:a4844ebb2be14768f7994f2017f70aca39d658a96c786211be5ddbe1c68794c1", - "sha256:c2b509ac3d4b988ae8769901c66345425e361d518aecbe4acbfc2567e416626a", - "sha256:c9959d49a77b0e07559e579f38b2f3711c2b8716b8410b320bf9713013215a1b", - "sha256:d8cdee92bc930d8b09d8bd2043cedd544d9c8bd7436a77678dd602467a993080", - "sha256:e15199cdb423316e15f108f51249e44eb156ae5dba232cb73be555324a1d49c2" + "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", + "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" ], - "version": "==1.4.2" + "version": "==1.25.9" } }, "develop": { diff --git a/evrouting/osm.py b/evrouting/osm.py index 59b4cd05852a082a031d147f88135b8e4f8c2bf2..c08fa26f7d0eff80ebc998e9c3b0f77576345261 100644 --- a/evrouting/osm.py +++ b/evrouting/osm.py @@ -14,14 +14,14 @@ Added : import copy import xml.sax -import time +import logging from math import radians, cos, sin, asin, sqrt from collections import namedtuple import networkx as nx import requests -from evrouting.graph_tools import DISTANCE_KEY +logger = logging.getLogger(__name__) OsrmConf = namedtuple('OsrmConf', ['server', 'port', 'version', 'profile'], @@ -29,48 +29,6 @@ OsrmConf = namedtuple('OsrmConf', ) -class CachedDistance: - def __init__(self, graph, symmetric=True): - self._cache = {} - self.graph = graph - self.symmetric = symmetric - - def d(self, u, v): - raise NotImplemented - - def __getitem__(self, item): - if self.symmetric: - item = sorted(item) - u, v = item - - try: - return self._cache[u, v] - except KeyError: - d = self.d(u, v) - self._cache[u, v] = d - return d - - -class AsyncCachedOSRMDistance(CachedDistance): - def __init__(self, - graph, - session, - symmetric=False, - osrm_config: OsrmConf = OsrmConf(server='0.0.0.0', port=5000) - ): - super().__init__(graph, symmetric) - self.session = session - - self.query_url = query_url - - async def d(self, u, v): - loc_u = (self.graph[u]['lat'], self.graph[u]['long']) - loc_v = (self.graph[v]['lat'], self.graph[v]['long']) - - async with self.session.get(self.query_url('route', [loc_u, loc_v])) as resp: - return resp - - def haversine_distance(lon1, lat1, lon2, lat2, unit_m=True): """ Calculate the great circle distance between two points @@ -91,9 +49,38 @@ def haversine_distance(lon1, lat1, lon2, lat2, unit_m=True): return c * r -def read_osm(osm_xml_data, - osrm_config: OsrmConf = OsrmConf(server='localhost', port=5000) - ) -> nx.DiGraph: +class OsrmDistance: + + def __init__(self, G, osrm_config: OsrmConf = OsrmConf(server='localhost', port=5000)): + self.G = G + self.osrm_config = osrm_config + + def query_url(self, service, coordinates): + return f'http://{self.osrm_config.server}:{self.osrm_config.port}' \ + f'/{service}/{self.osrm_config.version}/{self.osrm_config.profile}/' \ + f'{";".join([f"{lon},{lat}" for lat, lon in coordinates])}' + + def __call__(self, u, v): + """Calc distance between u and v on osrm.""" + url = self.query_url('route', + [ + (self.G.nodes[u]['lat'], self.G.nodes[u]['lon']), + (self.G.nodes[v]['lat'], self.G.nodes[v]['lon']) + ]) + resp = requests.get(url, timeout=0.1) + + try: + resp.raise_for_status() + except requests.HTTPError as e: + logger.error(f'Error {e}: {resp}') + raise + else: + resp = resp.json() + + return resp['routes'][0]['duration'] + + +def read_osm(osm_xml_data, only_roads=True) -> nx.DiGraph: """Read graph in OSM format from file specified by name or by stream object. Parameters ---------- @@ -104,12 +91,6 @@ def read_osm(osm_xml_data, G : Graph """ - only_roads = osrm_config.profile == 'driving' - - def query_url(service, coordinates): - return f'http://{osrm_config.server}:{osrm_config.port}' \ - f'/{service}/{osrm_config.version}/{osrm_config.profile}/' \ - f'{";".join([f"{lon},{lat}" for lat, lon in coordinates])}' osm = OSM(osm_xml_data) G = nx.DiGraph() @@ -133,45 +114,15 @@ def read_osm(osm_xml_data, nx.add_path(G, w.nds[::-1], id=w.id) # Complete the used nodes' information - coordinates_map = {} for n_id in G.nodes(): n = osm.nodes[n_id] G.nodes[n_id]['lat'] = n.lat G.nodes[n_id]['lon'] = n.lon G.nodes[n_id]['id'] = n.id - coordinates_map[n_id] = (n.lon, n.lat) - augment_distances(G, query_url) - G = nx.relabel_nodes(G, coordinates_map) return G -def augment_distances(G, url_factory): - # Estimate the length of each way - i = 0 - for u, v, d in G.edges(data=True): - i += 1 - url = url_factory( - 'route', - [ - (G.nodes[u]['lat'], G.nodes[u]['lon']), - (G.nodes[v]['lat'], G.nodes[v]['lon']) - ]) - try: - resp = requests.get(url, timeout=0.1) - except requests.exceptions.Timeout: - print('Timeout at request: ', i) - raise - - if resp.status_code == 200: - resp = resp.json() - else: - continue - duration = resp['routes'][0]['duration'] - time.sleep(0.005) - G.add_weighted_edges_from([(u, v, duration)], weight=DISTANCE_KEY) - - class Node(object): def __init__(self, id, lon, lat): self.id = id @@ -264,8 +215,7 @@ class OSM(object): def characters(self, chars): pass - with open(osm_xml_data, mode='r') as f: - xml.sax.parse(f, OSMHandler) + xml.sax.parse(osm_xml_data, OSMHandler) self.nodes = nodes self.ways = ways @@ -284,5 +234,7 @@ class OSM(object): for id, way in self.ways.items(): split_ways = way.split(node_histogram) for split_way in split_ways: + if split_way.id in new_ways: + print('Way id already exists.') new_ways[split_way.id] = split_way self.ways = new_ways