diff --git a/docs/customize/Tokenizers.md b/docs/customize/Tokenizers.md index 11c27e38b9..6199ea4252 100644 --- a/docs/customize/Tokenizers.md +++ b/docs/customize/Tokenizers.md @@ -229,6 +229,14 @@ The following is a list of sanitizers that are shipped with Nominatim. rendering: heading_level: 6 +#### tag-japanese + +::: nominatim.tokenizer.sanitizers.tag_japanese + selection: + members: False + rendering: + heading_level: 6 + #### Token Analysis Token analyzers take a full name and transform it into one or more normalized diff --git a/nominatim/tokenizer/sanitizers/tag_japanese.py b/nominatim/tokenizer/sanitizers/tag_japanese.py new file mode 100644 index 0000000000..3663860af9 --- /dev/null +++ b/nominatim/tokenizer/sanitizers/tag_japanese.py @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# This file is part of Nominatim. (https://nominatim.org) +# +# Copyright (C) 2022 by the Nominatim developer community. +# For a full list of authors see the git log. +""" +This sanitizer maps OSM data to Japanese block addresses. +It replaces blocknumber and housenumber with housenumber, +and quarter and neighbourhood with place. +""" + + +from typing import Callable +from typing import List, Optional + +from nominatim.tokenizer.sanitizers.base import ProcessInfo +from nominatim.tokenizer.sanitizers.config import SanitizerConfig +from nominatim.data.place_name import PlaceName + +def create(_: SanitizerConfig) -> Callable[[ProcessInfo], None]: + """Set up the sanitizer + """ + return tag_japanese + +def reconbine_housenumber( + new_address: List[PlaceName], + tmp_housenumber: Optional[str], + tmp_blocknumber: Optional[str] +) -> List[PlaceName]: + """ Recombine the tag of housenumber by using housenumber and blocknumber + """ + if tmp_blocknumber and tmp_housenumber: + new_address.append( + PlaceName( + kind='housenumber', + name=f'{tmp_blocknumber}-{tmp_housenumber}', + suffix='' + ) + ) + elif tmp_blocknumber: + new_address.append( + PlaceName( + kind='housenumber', + name=tmp_blocknumber, + suffix='' + ) + ) + elif tmp_housenumber: + new_address.append( + PlaceName( + kind='housenumber', + name=tmp_housenumber, + suffix='' + ) + ) + return new_address + +def reconbine_place( + new_address: List[PlaceName], + tmp_neighbourhood: Optional[str], + tmp_quarter: Optional[str] +) -> List[PlaceName]: + """ Recombine the tag of place by using neighbourhood and quarter + """ + if tmp_neighbourhood and tmp_quarter: + new_address.append( + PlaceName( + kind='place', + name=f'{tmp_quarter}{tmp_neighbourhood}', + suffix='' + ) + ) + elif tmp_neighbourhood: + new_address.append( + PlaceName( + kind='place', + name=tmp_neighbourhood, + suffix='' + ) + ) + elif tmp_quarter: + new_address.append( + PlaceName( + kind='place', + name=tmp_quarter, + suffix='' + ) + ) + return new_address +def tag_japanese(obj: ProcessInfo) -> None: + """Recombine kind of address + """ + if obj.place.country_code != 'jp': + return + tmp_housenumber = None + tmp_blocknumber = None + tmp_neighbourhood = None + tmp_quarter = None + + new_address = [] + for item in obj.address: + if item.kind == 'housenumber': + tmp_housenumber = item.name + elif item.kind == 'block_number': + tmp_blocknumber = item.name + elif item.kind == 'neighbourhood': + tmp_neighbourhood = item.name + elif item.kind == 'quarter': + tmp_quarter = item.name + else: + new_address.append(item) + + new_address = reconbine_housenumber(new_address, tmp_housenumber, tmp_blocknumber) + new_address = reconbine_place(new_address, tmp_neighbourhood, tmp_quarter) + + obj.address = [item for item in new_address if item.name is not None] diff --git a/settings/icu-rules/unicode-digits-to-decimal.yaml b/settings/icu-rules/unicode-digits-to-decimal.yaml index 55b3274a3a..db6c842086 100644 --- a/settings/icu-rules/unicode-digits-to-decimal.yaml +++ b/settings/icu-rules/unicode-digits-to-decimal.yaml @@ -1,14 +1,14 @@ -- "[๐žฅ๐’ ฿€๐–ญ๊ค€๐–ฉ ๐‘“๐‘‘๐‘‹ฐ๐‘„ถ๊ฉ๊˜ แฑ€แญแฎฐแ แŸ แฅ†เผ เป๊งฐแ‚แชแช€แง๐‘ต๊ฏฐแฑ๐‘ฑ๐‘œฐ๐‘›€๐‘™๐‘‡๊ง๊ฃเทฆ๐‘ฆ๏ผ๐Ÿถ๐Ÿ˜๐Ÿฌ๐ŸŽ๐Ÿขโ‚€โ“ฟโ“ชโฐ] > 0" -- "[๐žฅ‘๐’ก฿๐–ญ‘๊ค๐–ฉก๐‘“‘๐‘‘‘๐‘‹ฑ๐‘„ท๊ฉ‘๊˜กแฑแญ‘แฎฑแ ‘แŸกแฅ‡เผกเป‘๊งฑแ‚‘แช‘แชแง‘๐‘ต‘๊ฏฑแฑ‘๐‘ฑ‘๐‘œฑ๐‘›๐‘™‘๐‘‡‘๊ง‘๊ฃ‘เทง๐‘ง๏ผ‘๐Ÿท๐Ÿ™๐Ÿญ๐Ÿ๐Ÿฃโ‚ยนโ‘ โ‘ดโ’ˆโถโž€โžŠโ“ต] > 1" -- "[๐žฅ’๐’ข฿‚๐–ญ’๊ค‚๐–ฉข๐‘“’๐‘‘’๐‘‹ฒ๐‘„ธ๊ฉ’๊˜ขแฑ‚แญ’แฎฒแ ’แŸขแฅˆเผขเป’๊งฒแ‚’แช’แช‚แง’๐‘ต’๊ฏฒแฑ’๐‘ฑ’๐‘œฒ๐‘›‚๐‘™’๐‘‡’๊ง’๊ฃ’เทจ๐‘จ๏ผ’๐Ÿธ๐Ÿš๐Ÿฎ๐Ÿ๐Ÿคโ‚‚ยฒโ‘กโ‘ตโ’‰โทโžโž‹โ“ถ] > 2" -- "[๐žฅ“๐’ฃ฿ƒ๐–ญ“๊คƒ๐–ฉฃ๐‘““๐‘‘“๐‘‹ณ๐‘„น๊ฉ“๊˜ฃแฑƒแญ“แฎณแ “แŸฃแฅ‰เผฃเป“๊งณแ‚“แช“แชƒแง“๐‘ต“๊ฏณแฑ“๐‘ฑ“๐‘œณ๐‘›ƒ๐‘™“๐‘‡“๊ง“๊ฃ“เทฉ๐‘ฉ๏ผ“๐Ÿน๐Ÿ›๐Ÿฏ๐Ÿ‘๐Ÿฅโ‚ƒยณโ‘ขโ‘ถโ’Šโธโž‚โžŒโ“ท] > 3" -- "[๐žฅ”๐’ค฿„๐–ญ”๊ค„๐–ฉค๐‘“”๐‘‘”๐‘‹ด๐‘„บ๊ฉ”๊˜คแฑ„แญ”แฎดแ ”แŸคแฅŠเผคเป”๊งดแ‚”แช”แช„แง”๐‘ต”๊ฏดแฑ”๐‘ฑ”๐‘œด๐‘›„๐‘™”๐‘‡”๊ง”๊ฃ”เทช๐‘ช๏ผ”๐Ÿบ๐Ÿœ๐Ÿฐ๐Ÿ’๐Ÿฆโ‚„โดโ‘ฃโ‘ทโ’‹โนโžƒโžโ“ธ] > 4" -- "[๐žฅ•๐’ฅ฿…๐–ญ•๊ค…๐–ฉฅ๐‘“•๐‘‘•๐‘‹ต๐‘„ป๊ฉ•๊˜ฅแฑ…แญ•แฎตแ •แŸฅแฅ‹เผฅเป•๊งตแ‚•แช•แช…แง•๐‘ต•๊ฏตแฑ•๐‘ฑ•๐‘œต๐‘›…๐‘™•๐‘‡•๊ง•๊ฃ•เทซ๐‘ซ๏ผ•๐Ÿป๐Ÿ๐Ÿฑ๐Ÿ“๐Ÿงโ‚…โตโ‘คโ‘ธโ’Œโบโž„โžŽโ“น] > 5" -- "[๐žฅ–๐’ฆ฿†๐–ญ–๊ค†๐–ฉฆ๐‘“–๐‘‘–๐‘‹ถ๐‘„ผ๊ฉ–๊˜ฆแฑ†แญ–แฎถแ –แŸฆแฅŒเผฆเป–๊งถแ‚–แช–แช†แง–๐‘ต–๊ฏถแฑ–๐‘ฑ–๐‘œถ๐‘›†๐‘™–๐‘‡–๊ง–๊ฃ–เทฌ๐‘ฌ๏ผ–๐Ÿผ๐Ÿž๐Ÿฒ๐Ÿ”๐Ÿจโ‚†โถโ‘ฅโ‘นโ’โปโž…โžโ“บ] > 6" -- "[๐žฅ—๐’ง฿‡๐–ญ—๊ค‡๐–ฉง๐‘“—๐‘‘—๐‘‹ท๐‘„ฝ๊ฉ—๊˜งแฑ‡แญ—แฎทแ —แŸงแฅเผงเป—๊งทแ‚—แช—แช‡แง—๐‘ต—๊ฏทแฑ—๐‘ฑ—๐‘œท๐‘›‡๐‘™—๐‘‡—๊ง—๊ฃ—เทญ๐‘ญ๏ผ—๐Ÿฝ๐ŸŸ๐Ÿณ๐Ÿ•๐Ÿฉโ‚‡โทโ‘ฆโ‘บโ’Žโผโž†โžโ“ป] > 7" -- "[๐žฅ˜๐’จ฿ˆ๐–ญ˜๊คˆ๐–ฉจ๐‘“˜๐‘‘˜๐‘‹ธ๐‘„พ๊ฉ˜๊˜จแฑˆแญ˜แฎธแ ˜แŸจแฅŽเผจเป˜๊งธแ‚˜แช˜แชˆแง˜๐‘ต˜๊ฏธแฑ˜๐‘ฑ˜๐‘œธ๐‘›ˆ๐‘™˜๐‘‡˜๊ง˜๊ฃ˜เทฎ๐‘ฎ๏ผ˜๐Ÿพ๐Ÿ ๐Ÿด๐Ÿ–๐Ÿชโ‚ˆโธโ‘งโ‘ปโ’โฝโž‡โž‘โ“ผ] > 8" -- "[๐žฅ™๐’ฉ฿‰๐–ญ™๊ค‰๐–ฉฉ๐‘“™๐‘‘™๐‘‹น๐‘„ฟ๊ฉ™๊˜ฉแฑ‰แญ™แฎนแ ™แŸฉแฅเผฉเป™๊งนแ‚™แช™แช‰แง™๐‘ต™๊ฏนแฑ™๐‘ฑ™๐‘œน๐‘›‰๐‘™™๐‘‡™๊ง™๊ฃ™เทฏ๐‘ฏ๏ผ™๐Ÿฟ๐Ÿก๐Ÿต๐Ÿ—๐Ÿซโ‚‰โนโ‘จโ‘ผโ’โพโžˆโž’โ“ฝ] > 9" -- "[๐‘œบโ‘ฉโ‘ฝโ’‘โฟโž‰โž“โ“พ] > '10'" +- "[๐žฅ๐’ ฿€๐–ญ๊ค€๐–ฉ ๐‘“๐‘‘๐‘‹ฐ๐‘„ถ๊ฉ๊˜ แฑ€แญแฎฐแ แŸ แฅ†เผ เป๊งฐแ‚แชแช€แง๐‘ต๊ฏฐแฑ๐‘ฑ๐‘œฐ๐‘›€๐‘™๐‘‡๊ง๊ฃเทฆ๐‘ฆ๏ผ๐Ÿถ๐Ÿ˜๐Ÿฌ๐ŸŽ๐Ÿขโ‚€โ“ฟโ“ชโฐ้›ถ] > 0" +- "[๐žฅ‘๐’ก฿๐–ญ‘๊ค๐–ฉก๐‘“‘๐‘‘‘๐‘‹ฑ๐‘„ท๊ฉ‘๊˜กแฑแญ‘แฎฑแ ‘แŸกแฅ‡เผกเป‘๊งฑแ‚‘แช‘แชแง‘๐‘ต‘๊ฏฑแฑ‘๐‘ฑ‘๐‘œฑ๐‘›๐‘™‘๐‘‡‘๊ง‘๊ฃ‘เทง๐‘ง๏ผ‘๐Ÿท๐Ÿ™๐Ÿญ๐Ÿ๐Ÿฃโ‚ยนโ‘ โ‘ดโ’ˆโถโž€โžŠโ“ตไธ€] > 1" +- "[๐žฅ’๐’ข฿‚๐–ญ’๊ค‚๐–ฉข๐‘“’๐‘‘’๐‘‹ฒ๐‘„ธ๊ฉ’๊˜ขแฑ‚แญ’แฎฒแ ’แŸขแฅˆเผขเป’๊งฒแ‚’แช’แช‚แง’๐‘ต’๊ฏฒแฑ’๐‘ฑ’๐‘œฒ๐‘›‚๐‘™’๐‘‡’๊ง’๊ฃ’เทจ๐‘จ๏ผ’๐Ÿธ๐Ÿš๐Ÿฎ๐Ÿ๐Ÿคโ‚‚ยฒโ‘กโ‘ตโ’‰โทโžโž‹โ“ถไบŒ] > 2" +- "[๐žฅ“๐’ฃ฿ƒ๐–ญ“๊คƒ๐–ฉฃ๐‘““๐‘‘“๐‘‹ณ๐‘„น๊ฉ“๊˜ฃแฑƒแญ“แฎณแ “แŸฃแฅ‰เผฃเป“๊งณแ‚“แช“แชƒแง“๐‘ต“๊ฏณแฑ“๐‘ฑ“๐‘œณ๐‘›ƒ๐‘™“๐‘‡“๊ง“๊ฃ“เทฉ๐‘ฉ๏ผ“๐Ÿน๐Ÿ›๐Ÿฏ๐Ÿ‘๐Ÿฅโ‚ƒยณโ‘ขโ‘ถโ’Šโธโž‚โžŒโ“ทไธ‰] > 3" +- "[๐žฅ”๐’ค฿„๐–ญ”๊ค„๐–ฉค๐‘“”๐‘‘”๐‘‹ด๐‘„บ๊ฉ”๊˜คแฑ„แญ”แฎดแ ”แŸคแฅŠเผคเป”๊งดแ‚”แช”แช„แง”๐‘ต”๊ฏดแฑ”๐‘ฑ”๐‘œด๐‘›„๐‘™”๐‘‡”๊ง”๊ฃ”เทช๐‘ช๏ผ”๐Ÿบ๐Ÿœ๐Ÿฐ๐Ÿ’๐Ÿฆโ‚„โดโ‘ฃโ‘ทโ’‹โนโžƒโžโ“ธๅ››] > 4" +- "[๐žฅ•๐’ฅ฿…๐–ญ•๊ค…๐–ฉฅ๐‘“•๐‘‘•๐‘‹ต๐‘„ป๊ฉ•๊˜ฅแฑ…แญ•แฎตแ •แŸฅแฅ‹เผฅเป•๊งตแ‚•แช•แช…แง•๐‘ต•๊ฏตแฑ•๐‘ฑ•๐‘œต๐‘›…๐‘™•๐‘‡•๊ง•๊ฃ•เทซ๐‘ซ๏ผ•๐Ÿป๐Ÿ๐Ÿฑ๐Ÿ“๐Ÿงโ‚…โตโ‘คโ‘ธโ’Œโบโž„โžŽโ“นไบ”] > 5" +- "[๐žฅ–๐’ฆ฿†๐–ญ–๊ค†๐–ฉฆ๐‘“–๐‘‘–๐‘‹ถ๐‘„ผ๊ฉ–๊˜ฆแฑ†แญ–แฎถแ –แŸฆแฅŒเผฆเป–๊งถแ‚–แช–แช†แง–๐‘ต–๊ฏถแฑ–๐‘ฑ–๐‘œถ๐‘›†๐‘™–๐‘‡–๊ง–๊ฃ–เทฌ๐‘ฌ๏ผ–๐Ÿผ๐Ÿž๐Ÿฒ๐Ÿ”๐Ÿจโ‚†โถโ‘ฅโ‘นโ’โปโž…โžโ“บๅ…ญ] > 6" +- "[๐žฅ—๐’ง฿‡๐–ญ—๊ค‡๐–ฉง๐‘“—๐‘‘—๐‘‹ท๐‘„ฝ๊ฉ—๊˜งแฑ‡แญ—แฎทแ —แŸงแฅเผงเป—๊งทแ‚—แช—แช‡แง—๐‘ต—๊ฏทแฑ—๐‘ฑ—๐‘œท๐‘›‡๐‘™—๐‘‡—๊ง—๊ฃ—เทญ๐‘ญ๏ผ—๐Ÿฝ๐ŸŸ๐Ÿณ๐Ÿ•๐Ÿฉโ‚‡โทโ‘ฆโ‘บโ’Žโผโž†โžโ“ปไธƒ] > 7" +- "[๐žฅ˜๐’จ฿ˆ๐–ญ˜๊คˆ๐–ฉจ๐‘“˜๐‘‘˜๐‘‹ธ๐‘„พ๊ฉ˜๊˜จแฑˆแญ˜แฎธแ ˜แŸจแฅŽเผจเป˜๊งธแ‚˜แช˜แชˆแง˜๐‘ต˜๊ฏธแฑ˜๐‘ฑ˜๐‘œธ๐‘›ˆ๐‘™˜๐‘‡˜๊ง˜๊ฃ˜เทฎ๐‘ฎ๏ผ˜๐Ÿพ๐Ÿ ๐Ÿด๐Ÿ–๐Ÿชโ‚ˆโธโ‘งโ‘ปโ’โฝโž‡โž‘โ“ผๅ…ซ] > 8" +- "[๐žฅ™๐’ฉ฿‰๐–ญ™๊ค‰๐–ฉฉ๐‘“™๐‘‘™๐‘‹น๐‘„ฟ๊ฉ™๊˜ฉแฑ‰แญ™แฎนแ ™แŸฉแฅเผฉเป™๊งนแ‚™แช™แช‰แง™๐‘ต™๊ฏนแฑ™๐‘ฑ™๐‘œน๐‘›‰๐‘™™๐‘‡™๊ง™๊ฃ™เทฏ๐‘ฏ๏ผ™๐Ÿฟ๐Ÿก๐Ÿต๐Ÿ—๐Ÿซโ‚‰โนโ‘จโ‘ผโ’โพโžˆโž’โ“ฝไน] > 9" +- "[๐‘œบโ‘ฉโ‘ฝโ’‘โฟโž‰โž“โ“พๅ] > '10'" - "[โ‘ชโ‘พโ’’โ“ซ] > '11'" - "[โ‘ซโ‘ฟโ’“โ“ฌ] > '12'" - "[โ‘ฌโ’€โ’”โ“ญ] > '13'" diff --git a/settings/icu_tokenizer.yaml b/settings/icu_tokenizer.yaml index 1fa467befe..c5a809c683 100644 --- a/settings/icu_tokenizer.yaml +++ b/settings/icu_tokenizer.yaml @@ -45,6 +45,7 @@ sanitizers: whitelist: [bg,ca,cs,da,de,el,en,es,et,eu,fi,fr,gl,hu,it,ja,mg,ms,nl,no,pl,pt,ro,ru,sk,sl,sv,tr,uk,vi] use-defaults: all mode: append + - step: tag-japanese token-analysis: - analyzer: generic - id: "@housenumber" diff --git a/test/bdd/db/query/japanese.feature b/test/bdd/db/query/japanese.feature new file mode 100644 index 0000000000..4960c50b4f --- /dev/null +++ b/test/bdd/db/query/japanese.feature @@ -0,0 +1,30 @@ +@DB +Feature: Searches in Japan + Test specifically for searches of Japanese addresses and in Japanese language. + @fail-legacy + Scenario: A block house-number is parented to the neighbourhood + Given the grid with origin JP + | 1 | | | | 2 | + | | 3 | | | | + | | | 9 | | | + | | | | 6 | | + And the places + | osm | class | type | name | geometry | + | W1 | highway | residential | ้›‰ๅญๆฉ‹้€šใ‚Š | 1,2 | + And the places + | osm | class | type | housenr | addr+block_number | addr+neighbourhood | geometry | + | N3 | amenity | restaurant | 2 | 6 | 2ไธ็›ฎ | 3 | + And the places + | osm | class | type | name | geometry | + | N9 | place | neighbourhood | 2ไธ็›ฎ | 9 | + And the places + | osm | class | type | name | geometry | + | N6 | place | quarter | ๅŠ ็€ฌ | 6 | + When importing + Then placex contains + | object | parent_place_id | + | N3 | N9 | + When sending search query "2ไธ็›ฎ 6-2" + Then results contain + | osm | + | N3 | diff --git a/test/python/tokenizer/sanitizers/test_tag_japanese.py b/test/python/tokenizer/sanitizers/test_tag_japanese.py new file mode 100644 index 0000000000..946f137ce7 --- /dev/null +++ b/test/python/tokenizer/sanitizers/test_tag_japanese.py @@ -0,0 +1,80 @@ +from nominatim.data.place_info import PlaceInfo +from nominatim.data.place_name import PlaceName +from nominatim.tokenizer.place_sanitizer import PlaceSanitizer +from typing import Mapping, Optional, List +import pytest + +class TestTagJapanese: + @pytest.fixture(autouse=True) + def setup_country(self, def_config): + self.config = def_config + + def run_sanitizer_on(self,type, **kwargs): + place = PlaceInfo({ + 'address': kwargs, + 'country_code': 'jp' + }) + sanitizer_args = {'step': 'tag-japanese'} + _, address = PlaceSanitizer([sanitizer_args], self.config).process_names(place) + tmp_list = [(p.name,p.kind) for p in address] + return sorted(tmp_list) + + def test_on_address(self): + res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz') + assert res == [('bar','ref'),('baz','ref_abc'),('foo','name')] + + def test_housenumber(self): + res = self.run_sanitizer_on('address', housenumber='2') + assert res == [('2','housenumber')] + + def test_blocknumber(self): + res = self.run_sanitizer_on('address', block_number='6') + assert res == [('6','housenumber')] + + def test_neighbourhood(self): + res = self.run_sanitizer_on('address', neighbourhood='8') + assert res == [('8','place')] + + def test_quarter(self): + res = self.run_sanitizer_on('address', quarter='kase') + assert res==[('kase','place')] + + def test_housenumber_blocknumber(self): + res = self.run_sanitizer_on('address', housenumber='2', block_number='6') + assert res == [('6-2','housenumber')] + + def test_quarter_neighbourhood(self): + res = self.run_sanitizer_on('address', quarter='kase', neighbourhood='8') + assert res == [('kase8','place')] + + def test_blocknumber_housenumber_quarter(self): + res = self.run_sanitizer_on('address', block_number='6', housenumber='2', quarter='kase') + assert res == [('6-2','housenumber'),('kase','place')] + + def test_blocknumber_housenumber_quarter_neighbourhood(self): + res = self.run_sanitizer_on('address', block_number='6', housenumber='2', neighbourhood='8') + assert res == [('6-2','housenumber'),('8','place')] + + def test_blocknumber_quarter_neighbourhood(self): + res = self.run_sanitizer_on('address',block_number='6', quarter='kase', neighbourhood='8') + assert res == [('6','housenumber'),('kase8','place')] + + def test_blocknumber_quarter(self): + res = self.run_sanitizer_on('address',block_number='6', quarter='kase') + assert res == [('6','housenumber'),('kase','place')] + + def test_blocknumber_neighbourhood(self): + res = self.run_sanitizer_on('address',block_number='6', neighbourhood='8') + assert res == [('6','housenumber'),('8','place')] + + def test_housenumber_quarter_neighbourhood(self): + res = self.run_sanitizer_on('address',housenumber='2', quarter='kase', neighbourhood='8') + assert res == [('2','housenumber'),('kase8','place')] + + def test_housenumber_quarter(self): + res = self.run_sanitizer_on('address',housenumber='2', quarter='kase') + assert res == [('2','housenumber'),('kase','place')] + + def test_housenumber_blocknumber_neighbourhood_quarter(self): + res = self.run_sanitizer_on('address', block_number='6', housenumber='2', quarter='kase', neighbourhood='8') + assert res == [('6-2','housenumber'),('kase8','place')]