diff --git a/tools/python/mwm/dump_mwm.py b/tools/python/mwm/dump_mwm.py index 251c5cd03c..dfa0203aa2 100755 --- a/tools/python/mwm/dump_mwm.py +++ b/tools/python/mwm/dump_mwm.py @@ -4,31 +4,33 @@ import json from mwm import MWM if len(sys.argv) < 2: - print 'Dumps some MWM structures.' - print 'Usage: {0} '.format(sys.argv[0]) + print('Dumps some MWM structures.') + print('Usage: {0} '.format(sys.argv[0])) sys.exit(1) mwm = MWM(open(sys.argv[1], 'rb')) mwm.read_types(os.path.join(os.path.dirname(sys.argv[0]), '..', '..', '..', 'data', 'types.txt')) -print 'Tags:' -tvv = sorted([(k, v[0], v[1]) for k, v in mwm.tags.iteritems()], key=lambda x: x[1]) +print('Tags:') +tvv = sorted([(k, v[0], v[1]) for k, v in mwm.tags.items()], key=lambda x: x[1]) for tv in tvv: - print ' {0:<8}: offs {1:9} len {2:8}'.format(tv[0], tv[1], tv[2]) -print 'Version:', mwm.read_version() -print 'Header:', mwm.read_header() -print 'Metadata count:', len(mwm.read_metadata()) + print(' {0:<8}: offs {1:9} len {2:8}'.format(tv[0], tv[1], tv[2])) +v = mwm.read_version() +print('Format: {0}, version: {1}'.format(v['fmt'], v['version'].strftime('%Y-%m-%d %H:%M'))) +print('Header: {0}'.format(mwm.read_header())) +print('Metadata count: {0}'.format(len(mwm.read_metadata()))) cross = mwm.read_crossmwm() if cross: - print 'Outgoing points:', len(cross['out']), 'incoming:', len(cross['in']) - print 'Outgoing regions:', set(cross['neighbours']) + print('Outgoing points: {0}, incoming: {1}'.format(len(cross['out']), len(cross['in']))) + print('Outgoing regions: {0}'.format(set(cross['neighbours']))) -print 'Sample features:' +print('Sample features:') +# Print 5 random features ~10000 features apart count = 5 -probability = 1.0 / 1000 +probability = 1.0 / 10000 for feature in mwm.iter_features(): if random.random() < probability: - print json.dumps(feature, ensure_ascii=False) + print(json.dumps(feature, ensure_ascii=False)) count -= 1 if count <= 0: break diff --git a/tools/python/mwm/find_feature.py b/tools/python/mwm/find_feature.py index 4071e7dc08..87b88066d5 100755 --- a/tools/python/mwm/find_feature.py +++ b/tools/python/mwm/find_feature.py @@ -3,13 +3,17 @@ import sys, os.path, json from mwm import MWM if len(sys.argv) < 4: - print 'Finds features in an mwm file' - print 'Usage: {0} '.format(sys.argv[0]) - print 'Type: t for inside types, et for exact type, n for names' + print('Finds features in an mwm file based on a query') + print('Usage: {0} '.format(sys.argv[0])) + print('') + print('Type:') + print(' t for inside types ("t hwtag" will find all hwtags-*)') + print(' et for exact type ("et shop" won\'t find shop-chemist)') + print(' n for names, case-sensitive ("n Starbucks" for all starbucks)') sys.exit(1) typ = sys.argv[2].lower() -find = sys.argv[3] +find = sys.argv[3].decode('utf-8') mwm = MWM(open(sys.argv[1], 'rb')) mwm.read_header() @@ -27,4 +31,4 @@ for feature in mwm.iter_features(): elif typ == 't' and find in t: found = True if found: - print json.dumps(feature, ensure_ascii=False) + print(json.dumps(feature, ensure_ascii=False)) diff --git a/tools/python/mwm/mwm.py b/tools/python/mwm/mwm.py index abc3552382..99addccf8d 100644 --- a/tools/python/mwm/mwm.py +++ b/tools/python/mwm/mwm.py @@ -46,7 +46,7 @@ class MWM: cnt = self.read_varuint() self.tags = {} for i in range(cnt): - name = self.read_string(True) + name = self.read_string(plain=True) offset = self.read_varuint() length = self.read_varuint() self.tags[name] = (offset, length) @@ -57,13 +57,13 @@ class MWM: def seek_tag(self, tag): self.f.seek(self.tags[tag][0]) - def inside_tag(self, tag): - pos = self.tag_position(tag) - return pos >= 0 and pos < self.tags[tag][1] - - def tag_position(self, tag): + def tag_offset(self, tag): return self.f.tell() - self.tags[tag][0] + def inside_tag(self, tag): + pos = self.tag_offset(tag) + return pos >= 0 and pos < self.tags[tag][1] + def read_version(self): """Reads 'version' section.""" self.seek_tag('version') @@ -128,7 +128,7 @@ class MWM: self.seek_tag('meta') metadatar = {} while self.inside_tag('meta'): - tag_pos = self.tag_position('meta') + tag_pos = self.tag_offset('meta') fields = {} if fmt >= 8: sz = self.read_varuint() @@ -144,7 +144,7 @@ class MWM: t = t & 0x7f t = self.metadata[t] if t < len(self.metadata) else str(t) l = self.read_uint(1) - fields[t] = self.f.read(l) + fields[t] = self.f.read(l).decode('utf-8') if is_last: break @@ -189,7 +189,7 @@ class MWM: neighbours = [] for i in range(neighboursCount): size = self.read_uint(4) - neighbours.append(self.f.read(size)) + neighbours.append(self.f.read(size).decode('utf-8')) return { 'in': incoming, 'out': outgoing, 'matrix': matrix, 'neighbours': neighbours } class GeomType: @@ -314,9 +314,13 @@ class MWM: b = self.f.read(1) if not b: return res - res |= (ord(b[0]) & 0x7F) << shift + try: + bc = ord(b) + except TypeError: + bc = b + res |= (bc & 0x7F) << shift shift += 7 - more = ord(b[0]) >= 0x80 + more = bc >= 0x80 return res def zigzag_decode(self, uint): @@ -353,6 +357,7 @@ class MWM: return self.mwm_decode_delta(u, ref) def to_4326(self, point): + """Convert a point in maps.me-mercator CS to WGS-84 (EPSG:4326).""" if self.coord_size is None: raise Exception('Call read_header() first.') merc_bounds = (-180.0, -180.0, 180.0, 180.0) # Xmin, Ymin, Xmax, Ymax @@ -374,9 +379,10 @@ class MWM: pmax = self.to_4326(rmax) return (pmin[0], pmin[1], pmax[0], pmax[1]) - def read_string(self, plain=False): + def read_string(self, plain=False, decode=True): length = self.read_varuint() + (0 if plain else 1) - return self.f.read(length) + s = self.f.read(length) + return s.decode('utf-8') if decode else s def read_uint_array(self): length = self.read_varuint() @@ -390,13 +396,16 @@ class MWM: if sz & 1 != 0: return str(sz >> 1) sz = (sz >> 1) + 1 - return self.f.read(sz) + return self.f.read(sz).decode('utf-8') def read_multilang(self): def find_multilang_next(s, i): i += 1 while i < len(s): - c = struct.unpack('B', s[i])[0] + try: + c = ord(s[i]) + except: + c = s[i] if c & 0xC0 == 0x80: break if c & 0x80 == 0: @@ -416,13 +425,16 @@ class MWM: i += 1 return i - s = self.read_string() + s = self.read_string(decode=False) langs = {} i = 0 while i < len(s): n = find_multilang_next(s, i) - lng = struct.unpack('B', s[i])[0] & 0x3F + try: + lng = ord(s[i]) & 0x3F + except TypeError: + lng = s[i] & 0x3F if lng < len(self.languages): - langs[self.languages[lng]] = s[i+1:n] + langs[self.languages[lng]] = s[i+1:n].decode('utf-8') i = n return langs