[Tile-serving] [openstreetmap/osm2pgsql] Something wrong with indexes during import (#1436)

Andrey Novikov notifications at github.com
Thu Mar 25 17:04:04 UTC 2021


```
local srid = 3857

local prefix = 'osm_'

local tables = {}

tables.points = osm2pgsql.define_node_table(prefix .. 'points', {
    { column = 'tags', type = 'hstore' },
    { column = 'names', type = 'hstore' },
    { column = 'geom', type = 'point', projection = srid },
})

tables.lines = osm2pgsql.define_way_table(prefix .. 'lines', {
    { column = 'tags', type = 'hstore' },
    { column = 'names', type = 'hstore' },
    { column = 'geom', type = 'linestring', projection = srid },
})

tables.boundaries = osm2pgsql.define_way_table(prefix .. 'boundaries', {
    { column = 'admin_level', type = 'int', not_null = true },
    { column = 'maritime', type = 'text' },
    { column = 'geom', type = 'linestring', projection = srid },
})

tables.polygons = osm2pgsql.define_area_table(prefix .. 'polygons', {
    { column = 'tags', type = 'hstore' },
    { column = 'names', type = 'hstore' },
    { column = 'label_node', type = 'int8' },
    { column = 'geom', type = 'geometry', projection = srid },
    { column = 'area', type = 'area' },
})

tables.routes = osm2pgsql.define_relation_table(prefix .. 'routes', {
    { column = 'type', type = 'text' },
    { column = 'tags', type = 'hstore' },
    { column = 'geom', type = 'multilinestring', projection = srid },
})

local way2boundary = {}

local delete_keys = {
    -- cleaned to save DB space (addr:housenumber specially treated)
    'addr:*',

    -- everything else here is from flex examples, deleted to save space
}

local clean_tags = osm2pgsql.make_clean_tags_func(delete_keys)

function has_area_tags(tags)
    -- exactly as in flex examples, deleted to save space
end

function osm2pgsql.process_node(object)
    local addr_housenumber = object.tags['addr:housenumber']

    if clean_tags(object.tags) and not addr_housenumber then
        return
    end

    object.tags['addr:housenumber'] = addr_housenumber
    object.tags.layer = layer(object.tags.layer)
    local names = names(object.tags)

    tables.points:add_row({
        tags = object.tags,
        names = names
    })
end

function osm2pgsql.process_way(object)
    local boundaries = way2boundary[object.id]
    if boundaries or object.tags.boundary == 'administrative' then
        local admin_level = tonumber(object:grab_tag('admin_level')) or 12
        local maritime = object:grab_tag('maritime')

        if boundaries then
            for _, boundary in pairs(boundaries) do
                if boundary.admin_level < admin_level then
                    admin_level = boundary.admin_level
                end
                if boundary.maritime and not maritime then
                    maritime = boundary.maritime
                end
            end
        end

        if admin_level < 5 then
            tables.boundaries:add_row({
                admin_level = admin_level,
                maritime = maritime,
                geom = { create = 'line' }
            })
        end
    end

    local addr_housenumber = object.tags['addr:housenumber']
    local addr_interpolation = object.tags['addr:interpolation']

    if clean_tags(object.tags) and not addr_housenumber and not addr_interpolation then
        return
    end

    object.tags['addr:housenumber'] = addr_housenumber
    object.tags['addr:interpolation'] = addr_interpolation
    object.tags.layer = layer(object.tags.layer)
    local names = names(object.tags)

    if object.is_closed and has_area_tags(object.tags) then
        tables.polygons:add_row({
            tags = object.tags,
            names = names,
            geom = { create = 'area' }
        })
    else
        tables.lines:add_row({
            tags = object.tags,
            names = names
        })
    end
end

function osm2pgsql.select_relation_members(relation)
    if (relation.tags.type == 'boundary' or (relation.tags.type == 'multipolygon' and relation.tags.boundary)) and relation.tags.boundary == 'administrative' and relation.tags.admin_level then
        local admin_level = tonumber(relation.tags.admin_level) or 12
        if admin_level < 5 then
            return { ways = osm2pgsql.way_member_ids(relation) }
        end
    end
end

function osm2pgsql.process_relation(object)
    local addr_housenumber = object.tags['addr:housenumber']
    local addr_interpolation = object.tags['addr:interpolation']

    if clean_tags(object.tags) and not addr_housenumber and not addr_interpolation then
        return
    end

    object.tags['addr:housenumber'] = addr_housenumber
    object.tags['addr:interpolation'] = addr_interpolation
    object.tags.layer = layer(object.tags.layer)
    local names = names(object.tags)

    local type = object:grab_tag('type')

    if type == 'route' then
        tables.routes:add_row({
            type = object:grab_tag('route'),
            tags = object.tags,
            geom = { create = 'line' }
        })
        return
    end

    if type == 'boundary' or (type == 'multipolygon' and object.tags.boundary) then
        if object.tags.boundary == 'administrative' then
            local admin_level = tonumber(object.tags.admin_level) or 12
            if admin_level < 5 then
                local boundary = {
                    admin_level = admin_level,
                    maritime = object.tags.maritime
                }

                -- Go through all the members and store relation ids and refs so they
                -- can be found by the way id.
                for _, member in ipairs(object.members) do
                    if member.type == 'w' then
                        if not way2boundary[member.ref] then
                            way2boundary[member.ref] = {}
                        end
                        way2boundary[member.ref][object.id] = boundary
                    end
                end
            end
            if not object.tags.place then
                return
            end
            object.tags.boundary = nil
        end

        tables.polygons:add_row({
            tags = object.tags,
            names = names,
            label_node = relation_label(object.members, object.tags.boundary == 'administrative'),
            geom = { create = 'area' }
        })
        return
    end

    if type == 'multipolygon' then
        tables.polygons:add_row({
            tags = object.tags,
            names = names,
            label_node = relation_label(object.members, false),
            geom = { create = 'area' }
        })
    end
end

--- Normalizes layer tags
--- @param v string The layer tag value
--- @return number An integer for the layer tag
function layer(v)
    return v and string.find(v, "^-?%d+$") and tonumber(v) < 100 and tonumber(v) > -100 and v or nil
end

--- Put all name:* tags in their own substructure
--- @param tags table Object tags
--- @return table Extracted names
function names(tags)
    local object_names = {}
    for k, v in pairs(tags) do
        if k == 'name' then
            object_names[''] = v
            tags.name = nil
        elseif osm2pgsql.has_prefix(k, "name:") then
            -- extract language
            local lang = k:sub(6, -1)
            tags[k] = nil
            if lang == 'en' or lang == 'de' or lang == 'ru' then
                object_names[lang] = v
            end
        end
    end
    return object_names
end

--- Get label node reference for relation
--- @param members table Relation members
--- @param is_admin boolean Relation is administrative boundary
--- @return number node id or nil
function relation_label(members, is_admin)
    local label_ref
    for _, member in ipairs(members) do
        if member.type == 'n' then
            if member.role == 'label' then
                label_ref = member.ref
            end
            if is_admin and member.role == 'admin_centre' and not label_ref then
                label_ref = member.ref
            end
        end
    end
    return label_ref
end
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/openstreetmap/osm2pgsql/issues/1436#issuecomment-807104717
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstreetmap.org/pipermail/tile-serving/attachments/20210325/55670504/attachment-0001.htm>


More information about the Tile-serving mailing list