From 1b8e60abad25a62cbd15b3473fc76563c7d92d62 Mon Sep 17 00:00:00 2001 From: Ilya Zverev Date: Thu, 7 Jun 2018 13:04:15 +0300 Subject: [PATCH] [python] Refactor osm id codes --- tools/python/mwm/decode_id.py | 29 ++++++++++++--- tools/python/mwm/mwm.py | 69 ++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 35 deletions(-) diff --git a/tools/python/mwm/decode_id.py b/tools/python/mwm/decode_id.py index 376c91295f..ba120e9ea2 100755 --- a/tools/python/mwm/decode_id.py +++ b/tools/python/mwm/decode_id.py @@ -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: {} '.format(sys.argv[0])) + print('Usage: {} { | }'.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) diff --git a/tools/python/mwm/mwm.py b/tools/python/mwm/mwm.py index 3259a518d1..6d322e09fe 100644 --- a/tools/python/mwm/mwm.py +++ b/tools/python/mwm/mwm.py @@ -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