/
utils.py
102 lines (85 loc) · 2.81 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import csv
import json
from math import sqrt
from itertools import chain
from collections import defaultdict
from geopy.distance import geodesic
import yaml
def load_json(city):
with open(f"data/{city}.json", 'r') as f:
data=f.read()
return json.loads(data)
def load_parameters():
with open('parameters.yaml', 'r') as file:
return yaml.safe_load(file)
def street_dictionary(obj):
streets = defaultdict(list)
for e in obj['elements']:
if e['type'] == 'way':
if 'name' in e['tags']:
streets[e['tags']['name']].append((e['nodes']))
else:
streets['unnamed'].append((e['nodes']))
return streets
def point_hash(p):
return (round(float(p[0]), 3), round(float(p[1]), 3))
def load_completed_csnodes(csnodes_file) -> set:
points = defaultdict(set)
with open(csnodes_file, "r") as f:
for line in f.read().splitlines():
temp = line.strip().split(',')
if temp[1] == 'lat': continue
p = (float(temp[1]), float(temp[2]))
points[point_hash(p)].add(p)
return points
def is_close(d, p, threshold):
points = d[point_hash(p)]
if not points: return False
closest = min(geodesic(p, p2).kilometers for p2 in points)
return closest < threshold
def node_dictionary(obj):
d = {}
for e in obj['elements']:
if e['type'] == 'node':
d[e['id']] = (e['lat'], e['lon'])
return d
def adjacency_list(streets):
adj_list = defaultdict(set)
for _, snodes in streets.items():
for ssnodes in snodes:
for a, b in zip(ssnodes, ssnodes[1:]):
adj_list[a].add(b)
adj_list[b].add(a)
return adj_list
def streets_completed(path, streets):
count = 0
for _, snodes in streets.items():
if all(node in path for node in chain(*snodes)):
count += 1
return count
def dist(x1, x2, y1, y2):
dx, dy = x2 - x1, y2 - y1
return sqrt(dx * dx + dy * dy) * 111
def node_dist(a, b, nodes):
(x1, y1) = nodes[a]
(x2, y2) = nodes[b]
return dist(x1, x2, y1, y2)
def node_geodist(a, b, nodes):
return geodesic(nodes[a], nodes[b]).kilometers
def distance_of_path_precise(p, nodes):
return sum(node_geodist(a, b, nodes) for a, b in zip(p, p[1:]))
def distance_of_path(l, nodes):
res = 0
for a, b in zip(l, l[1:], strict=False):
(x1, y1) = nodes[a]
(x2, y2) = nodes[b]
res += dist(x1, x2, y1, y2)
return res
def total_distance_of_paths(ls, nodes):
return sum(distance_of_path(l, nodes) for l in ls)
def write_nodes_csv(nodes):
with open("nodes.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows([["lat", "lon", "sz", "names", "len_cat"]] + nodes)
def mid_point(vals):
return (vals.max() + vals.min()) / 2