+ assert_in(key, ('class', 'type', 'street', 'addr_place',
+ 'isin', 'postcode'))
+ self.columns[key] = None if value == '' else value
+
+ def set_key_name(self, value):
+ self.add_hstore('name', 'name', value)
+
+ def set_key_osm(self, value):
+ assert_in(value[0], 'NRW')
+ ok_(value[1:].isdigit())
+
+ self.columns['osm_type'] = value[0]
+ self.columns['osm_id'] = int(value[1:])
+
+ def set_key_admin(self, value):
+ self.columns['admin_level'] = int(value)
+
+ def set_key_housenr(self, value):
+ self.columns['housenumber'] = None if value == '' else value
+
+ def set_key_country(self, value):
+ self.columns['country_code'] = None if value == '' else value
+
+ def set_key_geometry(self, value):
+ self.geometry = self.context.osm.parse_geometry(value, self.context.scene)
+ assert_is_not_none(self.geometry)
+
+ def add_hstore(self, column, key, value):
+ if column in self.columns:
+ self.columns[column][key] = value
+ else:
+ self.columns[column] = { key : value }
+
+ def db_insert(self, cursor):
+ assert_in('osm_type', self.columns)
+ if self.force_name and 'name' not in self.columns:
+ self.add_hstore('name', 'name', ''.join(random.choice(string.printable)
+ for _ in range(int(random.random()*30))))
+
+ if self.columns['osm_type'] == 'N' and self.geometry is None:
+ self.geometry = "ST_SetSRID(ST_Point(%f, %f), 4326)" % (
+ random.random()*360 - 180, random.random()*180 - 90)
+ else:
+ assert_is_not_none(self.geometry, "Geometry missing")
+ query = 'INSERT INTO place (%s, geometry) values(%s, %s)' % (
+ ','.join(self.columns.keys()),
+ ','.join(['%s' for x in range(len(self.columns))]),
+ self.geometry)
+ cursor.execute(query, list(self.columns.values()))
+
+class NominatimID:
+ """ Splits a unique identifier for places into its components.
+ As place_ids cannot be used for testing, we use a unique
+ identifier instead that is of the form <osmtype><osmid>[:<class>].
+ """
+
+ id_regex = re.compile(r"(?P<tp>[NRW])(?P<id>\d+)(:(?P<cls>\w+))?")
+
+ def __init__(self, oid):
+ self.typ = self.oid = self.cls = None
+
+ if oid is not None:
+ m = self.id_regex.fullmatch(oid)
+ assert_is_not_none(m, "ID '%s' not of form <osmtype><osmid>[:<class>]" % oid)
+
+ self.typ = m.group('tp')
+ self.oid = m.group('id')
+ self.cls = m.group('cls')