forked from organicmaps/organicmaps
[mwm.py] Review fixes and python3 support
This commit is contained in:
parent
114ae06469
commit
8bcaac7b8e
3 changed files with 54 additions and 36 deletions
|
@ -4,31 +4,33 @@ import json
|
|||
from mwm import MWM
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print 'Dumps some MWM structures.'
|
||||
print 'Usage: {0} <country.mwm>'.format(sys.argv[0])
|
||||
print('Dumps some MWM structures.')
|
||||
print('Usage: {0} <country.mwm>'.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
|
||||
|
|
|
@ -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} <country.mwm> <type> <string>'.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} <country.mwm> <type> <string>'.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))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue