[python] Refactor osm id codes

This commit is contained in:
Ilya Zverev 2018-06-07 13:04:15 +03:00 committed by Slava
parent 34db723f4f
commit 1b8e60abad
2 changed files with 63 additions and 35 deletions

View file

@ -1,12 +1,29 @@
#!/usr/bin/env python3
#!/usr/bin/env python
import sys
import mwm
import re
if len(sys.argv) < 2:
print('This script unpacks maps.me OSM id to an OSM object link.')
print('Usage: {} <id>'.format(sys.argv[0]))
print('Usage: {} {<id> | <url>}'.format(sys.argv[0]))
sys.exit(1)
osm_id = mwm.unpack_osmid(int(sys.argv[1]))
type_abbr = {'n': 'node', 'w': 'way', 'r': 'relation'}
print('https://www.openstreetmap.org/{}/{}'.format(
type_abbr[osm_id[0]], osm_id[1]))
if sys.argv[1].isdigit():
osm_id = mwm.unpack_osmid(int(sys.argv[1]))
type_abbr = {'n': 'node', 'w': 'way', 'r': 'relation'}
print('https://www.openstreetmap.org/{}/{}'.format(
type_abbr[osm_id[0]], osm_id[1]))
else:
m = re.search(r'/(node|way|relation)/(\d+)', sys.argv[1])
if m:
oid = int(m.group(2))
if m.group(1) == 'node':
oid |= mwm.OsmIdCode.NODE
elif m.group(1) == 'way':
oid |= mwm.OsmIdCode.WAY
elif m.group(1) == 'relation':
oid |= mwm.OsmIdCode.RELATION
print(oid)
else:
print('Unknown parameter format')
sys.exit(2)

View file

@ -13,6 +13,39 @@ from datetime import datetime
# - Find feature ids in the 'dat' section, or find a way to read the 'offs' section
class OsmIdCode:
NODE = 0x4000000000000000
WAY = 0x8000000000000000
RELATION = 0xC000000000000000
RESET = ~(NODE | WAY | RELATION)
@staticmethod
def is_node(code):
return code & OsmIdCode.NODE == OsmIdCode.NODE
@staticmethod
def is_way(code):
return code & OsmIdCode.WAY == OsmIdCode.WAY
@staticmethod
def is_relation(code):
return code & OsmIdCode.RELATION == OsmIdCode.RELATION
@staticmethod
def get_type(code):
if OsmIdCode.is_relation(code):
return 'r'
elif OsmIdCode.is_node(code):
return 'n'
elif OsmIdCode.is_way(code):
return 'w'
return None
@staticmethod
def get_id(code):
return code & OsmIdCode.RESET
class MWM:
# coding/multilang_utf8_string.cpp
languages = ["default",
@ -222,12 +255,6 @@ class MWM:
AREA = 1 << 6
POINT_EX = 3 << 5
class OsmIdCode:
NODE = 0x4000000000000000
WAY = 0x8000000000000000
RELATION = 0xC000000000000000
RESET = ~(NODE | WAY | RELATION)
def iter_features(self, metadata=False):
"""Reads 'dat' section."""
if not self.has_tag('dat'):
@ -307,15 +334,10 @@ class MWM:
osmids = []
for i in range(count):
encid = self.read_uint(8)
if encid & MWM.OsmIdCode.NODE == MWM.OsmIdCode.NODE:
typ = 'n'
elif encid & MWM.OsmIdCode.WAY == MWM.OsmIdCode.WAY:
typ = 'w'
elif encid & MWM.OsmIdCode.RELATION == MWM.OsmIdCode.RELATION:
typ = 'r'
else:
typ = ''
osmids.append('{0}{1}'.format(typ, encid & MWM.OsmIdCode.RESET))
osmids.append('{0}{1}'.format(
OsmIdCode.get_type(encid) or '',
OsmIdCode.get_id(encid)
))
feature['osmIds'] = osmids
if self.f.tell() > next_feature:
@ -489,22 +511,11 @@ def read_varint(f):
return zigzag_decode(read_varuint(f))
NODE = 0x4000000000000000
WAY = 0x8000000000000000
RELATION = 0xC000000000000000
RESET = ~(NODE | WAY | RELATION)
def unpack_osmid(num):
if num & RELATION == RELATION:
typ = 'r'
elif num & WAY == WAY:
typ = 'w'
elif num & NODE == NODE:
typ = 'n'
else:
typ = OsmIdCode.get_type(num)
if typ is None:
return None
return typ, num & RESET
return typ, OsmIdCode.get_id(num)
# TODO(zverik, mgsergio): Move this to a separate module, cause it has nothing