diff --git a/lib-lua/themes/nominatim/init.lua b/lib-lua/themes/nominatim/init.lua index 41eaafe1..fd15968b 100644 --- a/lib-lua/themes/nominatim/init.lua +++ b/lib-lua/themes/nominatim/init.lua @@ -387,7 +387,6 @@ function Place:grab_address_parts(data) if atype ~= nil then if atype == 'main' then - self.has_name = true self.address[strip_address_prefix(k)] = v count = count + 1 elseif atype == 'extra' then @@ -708,24 +707,22 @@ function module.process_tags(o) local fallback = o:grab_name_parts{groups=NAME_FILTER} -- address keys - if o:grab_address_parts{groups=ADDRESS_FILTER} > 0 and fallback == nil then - fallback = {'place', 'house', address_fallback} - end + local fallback_address = (o:grab_address_parts{groups=ADDRESS_FILTER} > 0) if o.address.country ~= nil and #o.address.country ~= 2 then o.address['country'] = nil end if o.address.interpolation ~= nil - and (o.address.housenumber == nil or string.find(o.address.housenumber, '-') ~= nil) then + and (o.address.housenumber == nil + or string.find(o.address.housenumber, '^%d+%-%d+$') ~= nil) then if o:geometry_is_valid() then local extra_addr = nil for k, v in pairs(o.address) do if k ~= 'interpolation' then if extra_addr == nil then - extra_addr = {k = v} - else - extra_addr[k] = v + extra_addr = {} end + extra_addr[k] = v end end local nodes = nil @@ -738,8 +735,10 @@ function module.process_tags(o) nodes = nodes, geometry = o.geometry } + fallback_address = false + else + return end - return end -- collect main keys @@ -761,8 +760,8 @@ function module.process_tags(o) geometry = o.geometry } end - elseif ktype == 'fallback' and o.has_name then - fallback = {k, v, PlaceTransform.named} + elseif ktype == 'fallback' and (fallback_address or o.has_name) then + fallback = {k, v, PlaceTransform.always} end end end @@ -770,6 +769,8 @@ function module.process_tags(o) if o.num_entries == 0 then if fallback ~= nil then o:write_place(fallback[1], fallback[2], fallback[3]) + elseif fallback_address then + o:write_place('place', 'house', address_fallback) elseif POSTCODE_FALLBACK and not postcode_collect and o.address.postcode ~= nil and o:geometry_is_valid() then diff --git a/test/bdd/features/osm2pgsql/import/interpolation.feature b/test/bdd/features/osm2pgsql/import/interpolation.feature new file mode 100644 index 00000000..ce4349bc --- /dev/null +++ b/test/bdd/features/osm2pgsql/import/interpolation.feature @@ -0,0 +1,44 @@ +Feature: Import of interpolations + Test if interpolation objects are correctly imported into the + place_interpolation table + + Background: + Given the grid + | 1 | 2 | + | 4 | 3 | + + Scenario: Simple address interpolations + When loading osm data + """ + n1 + n2 + w13001 Taddr:interpolation=odd,addr:street=Blumenstrasse Nn1,n2 + w13002 Taddr:interpolation=even,place=city Nn1,n2 + w13003 Taddr:interpolation=odd Nn1,n1 + """ + Then place contains exactly + | object | class | type | + | W13002 | place | city | + And place_interpolation contains exactly + | object | type | address!dict | nodes!ints | geometry!wkt | + | W13001 | odd | "street": "Blumenstrasse" | 1,2 | 1,2 | + | W13002 | even | - | 1,2 | 1,2 | + + Scenario: Address interpolation with housenumber + When loading osm data + """ + n1 + n2 + n3 + n4 + w34 Taddr:interpolation=all,addr:housenumber=2-4,building=yes Nn1,n2,n3,n4,n1 + w35 Taddr:interpolation=all,addr:housenumber=5,building=yes Nn1,n2,n3,n4,n1 + w36 Taddr:interpolation=all,addr:housenumber=2a-c,building=yes Nn1,n2,n3,n4,n1 + """ + Then place contains exactly + | object | class | type | address!dict | + | w35 | building | yes | "housenumber" : "5", "interpolation": "all" | + | w36 | building | yes | "housenumber" : "2a-c", "interpolation": "all" | + Then place_interpolation contains exactly + | object | type | address!dict | nodes!ints | geometry!wkt | + | W34 | all | "housenumber": "2-4" | - | (1,2,3,4,1) | diff --git a/test/bdd/features/osm2pgsql/import/tags.feature b/test/bdd/features/osm2pgsql/import/tags.feature index b59da688..f27847a4 100644 --- a/test/bdd/features/osm2pgsql/import/tags.feature +++ b/test/bdd/features/osm2pgsql/import/tags.feature @@ -205,24 +205,6 @@ Feature: Tag evaluation | N12005 | 12345 | - | - Scenario: Address interpolations - Given the grid - | 1 | 2 | - When loading osm data - """ - n1 - n2 - w13001 Taddr:interpolation=odd Nn1,n2 - w13002 Taddr:interpolation=even,place=city Nn1,n2 - """ - Then place contains exactly - | object | - And place_interpolation contains exactly - | object | type | address!dict | - | W13001 | odd | - | - | W13002 | even | - | - - Scenario: Footways When loading osm data """ diff --git a/test/bdd/utils/checks.py b/test/bdd/utils/checks.py index 1d09f378..ade29438 100644 --- a/test/bdd/utils/checks.py +++ b/test/bdd/utils/checks.py @@ -2,7 +2,7 @@ # # This file is part of Nominatim. (https://nominatim.org) # -# Copyright (C) 2025 by the Nominatim developer community. +# Copyright (C) 2026 by the Nominatim developer community. # For a full list of authors see the git log. """ Helper functions to compare expected values. @@ -61,6 +61,8 @@ COMPARISON_FUNCS = { 'fm': lambda val, exp: re.fullmatch(exp, val) is not None, 'dict': lambda val, exp: (val is None if exp == '-' else (val == ast.literal_eval('{' + exp + '}'))), + 'ints': lambda val, exp: (val is None if exp == '-' + else (val == [int(i) for i in exp.split(',')])), 'in_box': within_box } @@ -84,6 +86,8 @@ class ResultAttr: !fm - consider comparison string a regular expression and match full value !wkt - convert the expected value to a WKT string before comparing !in_box - the expected value is a comma-separated bbox description + !dict - compare as a dictitionary, member order does not matter + !ints - compare as integer array """ def __init__(self, obj, key, grid=None):