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_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. |
| 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 |
| extra | Move the tag to extratags and then ignore it for further processing |
| `<function>`| Advanced handling, see [below](#advanced-main-tag-handling) |

View File

@@ -65,7 +65,19 @@ local table_definitions = {
{ column = 'geometry', type = 'geometry', projection = 'WGS84', not_null = true }
},
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' }
}
}
}
local insert_row = {}
@@ -113,6 +125,7 @@ local PlaceTransform = {}
-- Special transform meanings which are interpreted elsewhere
PlaceTransform.fallback = 'fallback'
PlaceTransform.postcode_area = 'postcode_area'
PlaceTransform.delete = 'delete'
PlaceTransform.extra = 'extra'
@@ -419,11 +432,25 @@ function Place:write_place(k, v, mfunc)
return 0
end
function Place:write_row(k, v)
function Place:geometry_is_valid()
if self.geometry == nil then
self.geometry = self.geom_func(self.object)
if self.geometry == nil or self.geometry:is_null() then
self.geometry = false
return false
end
return true
end
if self.geometry == nil or self.geometry:is_null() then
return self.geometry ~= false
end
function Place:write_row(k, v)
if not self:geometry_is_valid() then
return 0
end
@@ -675,9 +702,6 @@ function module.process_tags(o)
if o.address.country ~= nil and #o.address.country ~= 2 then
o.address['country'] = nil
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
o:write_place('place', 'houses', PlaceTransform.always)
@@ -685,20 +709,41 @@ function module.process_tags(o)
end
-- collect main keys
local postcode_collect = false
for k, v in pairs(o.intags) do
local ktable = MAIN_KEYS[k]
if ktable then
local ktype = ktable[v] or ktable[1]
if type(ktype) == 'function' then
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
fallback = {k, v, PlaceTransform.named}
end
end
end
if fallback ~= nil and o.num_entries == 0 then
o:write_place(fallback[1], fallback[2], fallback[3])
if o.num_entries == 0 then
if fallback ~= nil then
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

View File

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

View File

@@ -92,12 +92,16 @@ Feature: Tag evaluation
n6001 Tshop=bank,addr:postcode=12345
n6002 Tshop=bank,tiger:zip_left=34343
n6003 Tshop=bank,is_in:postcode=9009
n6004 Taddr:postcode=54322
"""
Then place contains exactly
| object | class | address!dict |
| N6001 | shop | 'postcode': '12345' |
| N6002 | shop | 'postcode': '34343' |
| N6003 | shop | - |
And place_postcode contains exactly
| object | postcode | geometry |
| N6004 | 54322 | - |
Scenario: Postcode areas
@@ -107,11 +111,15 @@ Feature: Tag evaluation
n2 x12.36853 y51.42362
n3 x12.63666 y51.42362
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
| object | class | type | name!dict |
| W1 | boundary | postal_code | 'ref': '3456' |
| object |
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
When loading osm data
@@ -192,7 +200,9 @@ Feature: Tag evaluation
| N12001 | tourism | hotel |
| N12003 | building | shed |
| N12004 | building | yes |
| N12005 | place | postcode |
And place_postcode contains exactly
| object | postcode | geometry |
| N12005 | 12345 | - |
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
propagated correctly.
Scenario: Adding a postcode-only node
When loading osm data
"""
@@ -15,11 +14,10 @@ Feature: Update of postcode only objects
"""
n34 Tpostcode=4456
"""
Then place contains exactly
| object | class | type |
| N34 | place | postcode |
When indexing
Then placex contains exactly
Then place_postcode contains exactly
| object | postcode |
| N34 | 4456 |
And place contains exactly
| object |
@@ -28,9 +26,11 @@ Feature: Update of postcode only objects
"""
n34 Tpostcode=4456
"""
Then place contains exactly
| object | class | type |
| N34 | place | postcode |
Then place_postcode contains exactly
| object | postcode |
| N34 | 4456 |
And place contains exactly
| object |
When updating osm data
"""
@@ -38,8 +38,7 @@ Feature: Update of postcode only objects
"""
Then place contains exactly
| object |
When indexing
Then placex contains exactly
And place_postcode contains exactly
| object |
@@ -57,8 +56,10 @@ Feature: Update of postcode only objects
n34 Tpostcode=4456
"""
Then place contains exactly
| object | class | type |
| N34 | place | postcode |
| object |
And place_postcode contains exactly
| object | postcode |
| N34 | 4456 |
When indexing
Then placex contains exactly
| object |
@@ -74,9 +75,9 @@ Feature: Update of postcode only objects
"""
n34 Tpostcode=4456
"""
Then place contains exactly
| object | class | type |
| N34 | place | postcode |
Then place_postcode contains exactly
| object | postcode |
| N34 | 4456 |
When updating osm data
"""
@@ -85,6 +86,8 @@ Feature: Update of postcode only objects
Then place contains exactly
| object | class | type |
| N34 | <class> | <type> |
And place_postcode contains exactly
| object |
When indexing
Then placex contains exactly
| object | class | type |
@@ -96,7 +99,7 @@ Feature: Update of postcode only objects
| place | hamlet |
Scenario: Converting na interpolation into a postcode-only node
Scenario: Converting an interpolation into a postcode-only node
Given the grid
| 1 | 2 |
When loading osm data
@@ -119,14 +122,12 @@ Feature: Update of postcode only objects
| object | class | type |
| N1 | place | house |
| N2 | place | house |
| W34 | place | postcode |
Then place_postcode contains exactly
| object | postcode |
| W34 | 4456 |
When indexing
Then location_property_osmline contains exactly
| osm_id |
And placex contains exactly
| object | class | type |
| N1 | place | house |
| N2 | place | house |
Scenario: Converting a postcode-only node into an interpolation
@@ -144,7 +145,9 @@ Feature: Update of postcode only objects
| N1 | place | house |
| N2 | place | house |
| W33 | highway | residential |
| W34 | place | postcode |
And place_postcode contains exactly
| object | postcode |
| W34 | 4456 |
When updating osm data
"""
@@ -156,6 +159,8 @@ Feature: Update of postcode only objects
| N2 | place | house |
| W33 | highway | residential |
| W34 | place | houses |
And place_postcode contains exactly
| object |
When indexing
Then location_property_osmline contains exactly
| osm_id | startnumber | endnumber |