forked from modrzew/pokeminer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
115 lines (94 loc) · 3.62 KB
/
utils.py
File metadata and controls
115 lines (94 loc) · 3.62 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
import math
from geopy import distance, Point
import config
def get_map_center():
"""Returns center of the map"""
lat = (config.MAP_END[0] + config.MAP_START[0]) / 2
lon = (config.MAP_END[1] + config.MAP_START[1]) / 2
return lat, lon
def get_scan_area():
"""Returns the square kilometers for configured scan area"""
lat1 = config.MAP_START[0]
lat2 = config.MAP_END[0]
lon1 = config.MAP_START[1]
lon2 = config.MAP_END[1]
p1 = Point(lat1, lon1)
p2 = Point(lat1, lon2)
p3 = Point(lat1, lon1)
p4 = Point(lat2, lon1)
width = distance.distance(p1, p2).kilometers
height = distance.distance(p3, p4).kilometers
area = int(width * height)
return area
def get_start_coords(worker_no):
"""Returns center of square for given worker"""
grid = config.GRID
total_workers = grid[0] * grid[1]
per_column = int(total_workers / grid[0])
column = worker_no % per_column
row = int(worker_no / per_column)
part_lat = (config.MAP_END[0] - config.MAP_START[0]) / float(grid[0])
part_lon = (config.MAP_END[1] - config.MAP_START[1]) / float(grid[1])
start_lat = config.MAP_START[0] + part_lat * row + part_lat / 2
start_lon = config.MAP_START[1] + part_lon * column + part_lon / 2
return start_lat, start_lon
def float_range(start, end, step):
"""xrange for floats, also capable of iterating backwards"""
if start > end:
while end < start:
yield start
start += -step
else:
while start < end:
yield start
start += step
def get_gains():
"""Returns lat and lon gain
Gain is space between circles.
"""
start = Point(*get_map_center())
base = config.SCAN_RADIUS * math.sqrt(3)
height = base * math.sqrt(3) / 2
dis_a = distance.VincentyDistance(meters=base)
dis_h = distance.VincentyDistance(meters=height)
lon_gain = dis_a.destination(point=start, bearing=90).longitude
lat_gain = dis_h.destination(point=start, bearing=0).latitude
return abs(start.latitude - lat_gain), abs(start.longitude - lon_gain)
def get_points_per_worker():
"""Returns all points that should be visited for whole grid"""
total_workers = config.GRID[0] * config.GRID[1]
lat_gain, lon_gain = get_gains()
points = [[] for _ in range(total_workers)]
total_rows = math.ceil(
abs(config.MAP_START[0] - config.MAP_END[0]) / lat_gain
)
total_columns = math.ceil(
abs(config.MAP_START[1] - config.MAP_END[1]) / lon_gain
)
for map_row, lat in enumerate(
float_range(config.MAP_START[0], config.MAP_END[0], lat_gain)
):
row_start_lon = config.MAP_START[1]
odd = map_row % 2 != 0
if odd:
row_start_lon -= 0.5 * lon_gain
for map_col, lon in enumerate(
float_range(row_start_lon, config.MAP_END[1], lon_gain)
):
# Figure out which worker this should go to
grid_row = int(map_row / float(total_rows) * config.GRID[0])
grid_col = int(map_col / float(total_columns) * config.GRID[1])
if map_col >= total_columns: # should happen only once per 2 rows
grid_col -= 1
worker_no = grid_row * config.GRID[1] + grid_col
points[worker_no].append((lat, lon))
points = [
sort_points_for_worker(p, i)
for i, p in enumerate(points)
]
return points
def sort_points_for_worker(points, worker_no):
center = get_start_coords(worker_no)
return sorted(points, key=lambda p: get_distance(p, center))
def get_distance(p1, p2):
return math.sqrt(pow(p1[0] - p2[0], 2) + pow(p1[1] - p2[1], 2))