put postcodes in extra table on import

This commit is contained in:
Sarah Hoffmann
2025-12-23 10:56:53 +01:00
parent 0b11dd0eba
commit 340fe64e8b
5 changed files with 97 additions and 36 deletions

View File

@@ -113,6 +113,7 @@ The following classifications are recognized:
| named | Consider as main tag, when the object has a primary name (see [names](#name-tags) below) | | named | Consider as main tag, when the object has a primary name (see [names](#name-tags) below) |
| named_with_key | Consider as main tag, when the object has a primary name with a domain prefix. For example, if the main tag is `bridge=yes`, then it will only be added as an extra entry, if there is a tag `bridge:name[:XXX]` for the same object. If this property is set, all names that are not domain-specific are ignored. | | named_with_key | Consider as main tag, when the object has a primary name with a domain prefix. For example, if the main tag is `bridge=yes`, then it will only be added as an extra entry, if there is a tag `bridge:name[:XXX]` for the same object. If this property is set, all names that are not domain-specific are ignored. |
| fallback | Consider as main tag only when no other main tag was found. Fallback always implies `named`, i.e. fallbacks are only tried for objects with primary names. | | fallback | Consider as main tag only when no other main tag was found. Fallback always implies `named`, i.e. fallbacks are only tried for objects with primary names. |
| postcode_area | Tag indicates a postcode area. Copy area into the table of postcodes but only when the object is a relation and has a postcode tagged. |
| delete | Completely ignore the tag in any further processing | | delete | Completely ignore the tag in any further processing |
| extra | Move the tag to extratags and then ignore it for further processing | | extra | Move the tag to extratags and then ignore it for further processing |
| `<function>`| Advanced handling, see [below](#advanced-main-tag-handling) | | `<function>`| Advanced handling, see [below](#advanced-main-tag-handling) |

View File

@@ -65,6 +65,18 @@ local table_definitions = {
{ column = 'geometry', type = 'geometry', projection = 'WGS84', not_null = true } { column = 'geometry', type = 'geometry', projection = 'WGS84', not_null = true }
}, },
indexes = {} indexes = {}
},
place_postcode = {
ids = { type = 'any', id_column = 'osm_id', type_column = 'osm_type' },
columns = {
{ column = 'postcode', type = 'text', not_null = true },
{ column = 'country_code', type = 'text' },
{ column = 'centroid', type = 'point', projection = 'WGS84', not_null = true },
{ column = 'geometry', type = 'geometry', projection = 'WGS84' }
},
indexes = {
{ column = 'postcode', method = 'btree' }
}
} }
} }
@@ -113,6 +125,7 @@ local PlaceTransform = {}
-- Special transform meanings which are interpreted elsewhere -- Special transform meanings which are interpreted elsewhere
PlaceTransform.fallback = 'fallback' PlaceTransform.fallback = 'fallback'
PlaceTransform.postcode_area = 'postcode_area'
PlaceTransform.delete = 'delete' PlaceTransform.delete = 'delete'
PlaceTransform.extra = 'extra' PlaceTransform.extra = 'extra'
@@ -419,11 +432,25 @@ function Place:write_place(k, v, mfunc)
return 0 return 0
end end
function Place:write_row(k, v)
function Place:geometry_is_valid()
if self.geometry == nil then if self.geometry == nil then
self.geometry = self.geom_func(self.object) self.geometry = self.geom_func(self.object)
end
if self.geometry == nil or self.geometry:is_null() then if self.geometry == nil or self.geometry:is_null() then
self.geometry = false
return false
end
return true
end
return self.geometry ~= false
end
function Place:write_row(k, v)
if not self:geometry_is_valid() then
return 0 return 0
end end
@@ -675,9 +702,6 @@ function module.process_tags(o)
if o.address.country ~= nil and #o.address.country ~= 2 then if o.address.country ~= nil and #o.address.country ~= 2 then
o.address['country'] = nil o.address['country'] = nil
end end
if POSTCODE_FALLBACK and fallback == nil and o.address.postcode ~= nil then
fallback = {'place', 'postcode', PlaceTransform.always}
end
if o.address.interpolation ~= nil then if o.address.interpolation ~= nil then
o:write_place('place', 'houses', PlaceTransform.always) o:write_place('place', 'houses', PlaceTransform.always)
@@ -685,20 +709,41 @@ function module.process_tags(o)
end end
-- collect main keys -- collect main keys
local postcode_collect = false
for k, v in pairs(o.intags) do for k, v in pairs(o.intags) do
local ktable = MAIN_KEYS[k] local ktable = MAIN_KEYS[k]
if ktable then if ktable then
local ktype = ktable[v] or ktable[1] local ktype = ktable[v] or ktable[1]
if type(ktype) == 'function' then if type(ktype) == 'function' then
o:write_place(k, v, ktype) o:write_place(k, v, ktype)
elseif ktype == 'postcode_area' then
postcode_collect = true
if o.object.type == 'relation'
and o.address.postcode ~= nil
and o:geometry_is_valid() then
insert_row.place_postcode{
postcode = o.address.postcode,
centroid = o.geometry:centroid(),
geometry = o.geometry
}
end
elseif ktype == 'fallback' and o.has_name then elseif ktype == 'fallback' and o.has_name then
fallback = {k, v, PlaceTransform.named} fallback = {k, v, PlaceTransform.named}
end end
end end
end end
if fallback ~= nil and o.num_entries == 0 then if o.num_entries == 0 then
if fallback ~= nil then
o:write_place(fallback[1], fallback[2], fallback[3]) o:write_place(fallback[1], fallback[2], fallback[3])
elseif POSTCODE_FALLBACK and not postcode_collect
and o.address.postcode ~= nil
and o:geometry_is_valid() then
insert_row.place_postcode{
postcode = o.address.postcode,
centroid = o.geometry:centroid()
}
end
end end
end end

View File

@@ -118,7 +118,7 @@ module.MAIN_TAGS.all_boundaries = {
place = 'delete', place = 'delete',
land_area = 'delete', land_area = 'delete',
protected_area = 'fallback', protected_area = 'fallback',
postal_code = 'always'}, postal_code = 'postcode_area'},
landuse = 'fallback', landuse = 'fallback',
place = 'always' place = 'always'
} }

View File

@@ -92,12 +92,16 @@ Feature: Tag evaluation
n6001 Tshop=bank,addr:postcode=12345 n6001 Tshop=bank,addr:postcode=12345
n6002 Tshop=bank,tiger:zip_left=34343 n6002 Tshop=bank,tiger:zip_left=34343
n6003 Tshop=bank,is_in:postcode=9009 n6003 Tshop=bank,is_in:postcode=9009
n6004 Taddr:postcode=54322
""" """
Then place contains exactly Then place contains exactly
| object | class | address!dict | | object | class | address!dict |
| N6001 | shop | 'postcode': '12345' | | N6001 | shop | 'postcode': '12345' |
| N6002 | shop | 'postcode': '34343' | | N6002 | shop | 'postcode': '34343' |
| N6003 | shop | - | | N6003 | shop | - |
And place_postcode contains exactly
| object | postcode | geometry |
| N6004 | 54322 | - |
Scenario: Postcode areas Scenario: Postcode areas
@@ -107,11 +111,15 @@ Feature: Tag evaluation
n2 x12.36853 y51.42362 n2 x12.36853 y51.42362
n3 x12.63666 y51.42362 n3 x12.63666 y51.42362
n4 x12.63666 y51.50618 n4 x12.63666 y51.50618
w1 Tboundary=postal_code,ref=3456 Nn1,n2,n3,n4,n1 w1 Nn1,n2,n3,n4,n1
w2 Tboundary=postal_code,postal_code=443 Nn1,n2,n3,n4,n1
r1 Ttype=boundary,boundary=postal_code,postal_code=3456 Mw1@
""" """
Then place contains exactly Then place contains exactly
| object | class | type | name!dict | | object |
| W1 | boundary | postal_code | 'ref': '3456' | And place_postcode contains exactly
| object | postcode | geometry!wkt |
| R1 | 3456 | (12.36853 51.50618, 12.36853 51.42362, 12.63666 51.42362, 12.63666 51.50618, 12.36853 51.50618) |
Scenario: Main with extra Scenario: Main with extra
When loading osm data When loading osm data
@@ -192,7 +200,9 @@ Feature: Tag evaluation
| N12001 | tourism | hotel | | N12001 | tourism | hotel |
| N12003 | building | shed | | N12003 | building | shed |
| N12004 | building | yes | | N12004 | building | yes |
| N12005 | place | postcode | And place_postcode contains exactly
| object | postcode | geometry |
| N12005 | 12345 | - |
Scenario: Address interpolations Scenario: Address interpolations

View File

@@ -2,7 +2,6 @@ Feature: Update of postcode only objects
Tests that changes to objects containing only a postcode are Tests that changes to objects containing only a postcode are
propagated correctly. propagated correctly.
Scenario: Adding a postcode-only node Scenario: Adding a postcode-only node
When loading osm data When loading osm data
""" """
@@ -15,11 +14,10 @@ Feature: Update of postcode only objects
""" """
n34 Tpostcode=4456 n34 Tpostcode=4456
""" """
Then place contains exactly Then place_postcode contains exactly
| object | class | type | | object | postcode |
| N34 | place | postcode | | N34 | 4456 |
When indexing And place contains exactly
Then placex contains exactly
| object | | object |
@@ -28,9 +26,11 @@ Feature: Update of postcode only objects
""" """
n34 Tpostcode=4456 n34 Tpostcode=4456
""" """
Then place contains exactly Then place_postcode contains exactly
| object | class | type | | object | postcode |
| N34 | place | postcode | | N34 | 4456 |
And place contains exactly
| object |
When updating osm data When updating osm data
""" """
@@ -38,8 +38,7 @@ Feature: Update of postcode only objects
""" """
Then place contains exactly Then place contains exactly
| object | | object |
When indexing And place_postcode contains exactly
Then placex contains exactly
| object | | object |
@@ -57,8 +56,10 @@ Feature: Update of postcode only objects
n34 Tpostcode=4456 n34 Tpostcode=4456
""" """
Then place contains exactly Then place contains exactly
| object | class | type | | object |
| N34 | place | postcode | And place_postcode contains exactly
| object | postcode |
| N34 | 4456 |
When indexing When indexing
Then placex contains exactly Then placex contains exactly
| object | | object |
@@ -74,9 +75,9 @@ Feature: Update of postcode only objects
""" """
n34 Tpostcode=4456 n34 Tpostcode=4456
""" """
Then place contains exactly Then place_postcode contains exactly
| object | class | type | | object | postcode |
| N34 | place | postcode | | N34 | 4456 |
When updating osm data When updating osm data
""" """
@@ -85,6 +86,8 @@ Feature: Update of postcode only objects
Then place contains exactly Then place contains exactly
| object | class | type | | object | class | type |
| N34 | <class> | <type> | | N34 | <class> | <type> |
And place_postcode contains exactly
| object |
When indexing When indexing
Then placex contains exactly Then placex contains exactly
| object | class | type | | object | class | type |
@@ -96,7 +99,7 @@ Feature: Update of postcode only objects
| place | hamlet | | place | hamlet |
Scenario: Converting na interpolation into a postcode-only node Scenario: Converting an interpolation into a postcode-only node
Given the grid Given the grid
| 1 | 2 | | 1 | 2 |
When loading osm data When loading osm data
@@ -119,14 +122,12 @@ Feature: Update of postcode only objects
| object | class | type | | object | class | type |
| N1 | place | house | | N1 | place | house |
| N2 | place | house | | N2 | place | house |
| W34 | place | postcode | Then place_postcode contains exactly
| object | postcode |
| W34 | 4456 |
When indexing When indexing
Then location_property_osmline contains exactly Then location_property_osmline contains exactly
| osm_id | | osm_id |
And placex contains exactly
| object | class | type |
| N1 | place | house |
| N2 | place | house |
Scenario: Converting a postcode-only node into an interpolation Scenario: Converting a postcode-only node into an interpolation
@@ -144,7 +145,9 @@ Feature: Update of postcode only objects
| N1 | place | house | | N1 | place | house |
| N2 | place | house | | N2 | place | house |
| W33 | highway | residential | | W33 | highway | residential |
| W34 | place | postcode | And place_postcode contains exactly
| object | postcode |
| W34 | 4456 |
When updating osm data When updating osm data
""" """
@@ -156,6 +159,8 @@ Feature: Update of postcode only objects
| N2 | place | house | | N2 | place | house |
| W33 | highway | residential | | W33 | highway | residential |
| W34 | place | houses | | W34 | place | houses |
And place_postcode contains exactly
| object |
When indexing When indexing
Then location_property_osmline contains exactly Then location_property_osmline contains exactly
| osm_id | startnumber | endnumber | | osm_id | startnumber | endnumber |