-
Notifications
You must be signed in to change notification settings - Fork 0
/
bbbikeExtract.py
134 lines (112 loc) · 4.05 KB
/
bbbikeExtract.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals
import xml.etree.ElementTree as ET
import math, sys
import win32clipboard
'''
Given a gpx file, find all bounding boxes of a given surface
'''
class BoundingBox(object):
"""
A 2D bounding box
"""
def __init__(self):
self.sw_lng, self.sw_lat = float("inf"), float("inf")
self.ne_lng, self.ne_lat = float("-inf"), float("-inf")
self.count = 0
def addPoint(self, x, y):
self.count += 1
# Set min coords
if x < self.sw_lng:
self.sw_lng = x
if y < self.sw_lat:
self.sw_lat = y
# Set max coords
if x > self.ne_lng:
self.ne_lng = x
elif y > self.ne_lat:
self.ne_lat = y
@property
def w_lng(self):
return self.ne_lng - self.sw_lng
@property
def w_lat(self):
return self.ne_lat - self.sw_lat
@property
def distance_lng(self):
try:
a = (self.ne_lat + self.sw_lat)/2.0
return self.w_lng * math.cos(math.radians(a)) * 111.0
except ValueError:
return 0.0
@property
def distance_lat(self):
try:
return self.w_lat * 111.0
except ValueError:
return 0.0
@property
def surface(self):
return self.distance_lng * self.distance_lat
def __repr__(self):
return "BoundingBox({}, {}, {}, {})".format(
self.sw_lng, self.ne_lng, self.sw_lat, self.ne_lat)
def parseGpx(filname, maxSurface):
ns = '{http://www.topografix.com/GPX/1/1}'
data = []
with open(filname, 'r') as xml_file:
tree = ET.parse(xml_file)
root = tree.getroot()
for trk in root.findall('{}{}'.format(ns, 'trk')):
name = trk.find('{}{}'.format(ns, 'name')).text
index = 0
for trkseg in trk.findall('{}{}'.format(ns, 'trkseg')):
b = BoundingBox()
index += 1
for trkpt in trkseg.findall('{}{}'.format(ns, 'trkpt')):
b.addPoint(float(trkpt.get('lon')), float(trkpt.get('lat')))
if b.surface > maxSurface:
data.append((name + '_' + str(index), b))
index += 1
b = BoundingBox()
if b.count > 1:
data.append((name + '_' + str(index), b))
return data
def parseGpx1(filname, maxSurface):
ns = '{http://www.topografix.com/GPX/1/1}'
data = []
with open(filname, 'r') as xml_file:
tree = ET.parse(xml_file)
root = tree.getroot()
b = BoundingBox()
index = 0
name = 'Track'
for trk in root.findall('{}{}'.format(ns, 'trk')):
for trkseg in trk.findall('{}{}'.format(ns, 'trkseg')):
for trkpt in trkseg.findall('{}{}'.format(ns, 'trkpt')):
b.addPoint(float(trkpt.get('lon')), float(trkpt.get('lat')))
if b.surface > maxSurface:
data.append((name + '_' + str(index), b))
index += 1
b = BoundingBox()
if b.count > 1:
data.append((name + '_' + str(index), b))
return data
def Format(b, name):
return 'https://extract.bbbike.org/?sw_lng={0:.3f}&sw_lat={1:.3f}&ne_lng={2:.3f}&ne_lat={3:.3f}&format=osm.xz&city={4}&lang=en'.format(b.sw_lng, b.sw_lat, b.ne_lng, b.ne_lat, name)
def CopyClip(data):
win32clipboard.OpenClipboard()
win32clipboard.SetClipboardData(win32clipboard.CF_UNICODETEXT, data)
win32clipboard.CloseClipboard()
# Usage example:
if __name__ == '__main__':
if len(sys.argv) > 1:
size = float(sys.argv[2]) if len(sys.argv) > 2 else 4000.0
results = parseGpx1(sys.argv[1], size)
for result in results:
b = result[1]
print('{} w={} h={} dx={} dy={}, s={}'.format(result, b.w_lng, b.w_lat, b.distance_lng, b.distance_lat, b.surface) )
for result in results:
s = result[0]
print(Format(result[1], s))
CopyClip('\n'.join([Format(x[1], x[0]) for x in results]))