Skip to content

Instantly share code, notes, and snippets.

@mvexel
Created November 17, 2025 01:36
Show Gist options
  • Select an option

  • Save mvexel/32905874ef2a5d3625263b6eb3efb8c2 to your computer and use it in GitHub Desktop.

Select an option

Save mvexel/32905874ef2a5d3625263b6eb3efb8c2 to your computer and use it in GitHub Desktop.
-- Define shops table
local poi = osm2pgsql.define_table({
name = 'poi',
ids = {
type = 'any',
id_column = 'osm_id',
type_column = 'osm_type'
},
columns = {{
column = 'name',
type = 'text'
}, {
column = 'address',
type = 'text'
}, {
column = 'phone',
type = 'text'
}, {
column = 'website',
type = 'text'
}, {
column = 'email',
type = 'text'
}, {
column = 'category',
type = 'text'
}, {
column = 'tags',
type = 'jsonb'
}, {
column = 'geom',
type = 'point',
projection = 4326,
not_null = true
}}
})
local function load_mapping(tag_key, tag_value)
-- Load mapping k/v to category from CSV file into a matrix
local mapping = {}
local file = io.open('mapping.csv', 'r')
if file then
for line in file:lines() do
-- skip header line
local key, value, category = line:match('([^,]+),([^,]+),([^,]+)')
if key and value and category then
if key == "public_transport" then
print("Loading mapping:", key, value, category) -- Debug print
end
if not mapping[key] then mapping[key] = {} end
mapping[key][value] = category
end
end
file:close()
end
return mapping
end
-- load mapping into memory
local category_mapping = load_mapping()
-- Helper function to concatenate address parts from OSM tag values
local function concat_address(tags)
local address = ''
for _, part in ipairs({'house_number', 'street', 'city', 'postcode'}) do
part = tags["addr:" .. part]
if part and part ~= '' then
if part == tags["addr:street"] then
address = address .. part .. ', '
else
address = address .. part .. ' '
end
end
end
-- Trim leading/trailing spaces
return address:match("^%s*(.-)%s*$")
end
-- Helper function to find category from tags
local function get_category(tags)
for key, value in pairs(tags) do
if category_mapping[key] and category_mapping[key][value] then
-- if key == 'public_transport' then
-- print("Matched key/value:", key, value) -- Debug print
-- print("Matched category:", category_mapping[key][value])
-- end
return category_mapping[key][value]
end
end
return nil
end
function osm2pgsql.process_node(object)
if object.tags then
local category = get_category(object.tags)
if category then
local address = concat_address(object.tags)
poi:insert({
name = object.tags.name,
address = address,
phone = object.tags.phone,
website = object.tags.website,
email = object.tags.email,
category = category,
tags = object.tags,
geom = object:as_point()
})
end
end
end
function osm2pgsql.process_way(object)
if object.is_closed then
if object.tags then
local category = get_category(object.tags)
if category then
local address = concat_address(object.tags)
poi:insert({
name = object.tags.name,
address = address,
phone = object.tags.phone,
website = object.tags.website,
email = object.tags.email,
category = category,
tags = object.tags,
geom = object:as_polygon():centroid()
})
end
end
end
end
function osm2pgsql.process_relation(object)
if object.tags.type == 'multipolygon' then
if object.tags then
local category = get_category(object.tags)
if category then
local address = concat_address(object.tags)
poi:insert({
name = object.tags.name,
address = address,
phone = object.tags.phone,
website = object.tags.website,
email = object.tags.email,
category = category,
tags = object.tags,
geom = object:as_multipolygon():centroid()
})
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment