[Tile-serving] [openstreetmap/osm2pgsql] Flex - Error with LineString and MultiLineString data (#1386)

Ryan Lambert notifications at github.com
Fri Jan 1 16:56:54 UTC 2021


I am running into an error attempting to combine `linestring` and `multilinestring` data with the Flex output.
Additional links to the specific commits where I encountered this are [tracked here](https://github.com/rustprooflabs/pgosm-flex/issues/2). 

The previous version of the Lua script below did not handle relations, it worked fine.  I added the relation handling for the polygons without issue (apparently dealing with polygon/multipolygon w/out problem).  The error happens when I attempt adding the line processing into the relations.  The original table definition had the `place_line` table set as `linestring`.  Updating the table definition to `multilinestring` to allow relations to be added causes the error: 

```
ERROR: DB copy thread failed: Ending COPY mode for 'place_line' failed: ERROR:  Geometry type (LineString) does not match column type (MultiLineString)
CONTEXT:  COPY place_line, line 1, column geom: "0102000020110F00000A0000000DAF04630C5A60C11BD8F1715AFF5141233BA5E3125A60C1D8D2A9BA48FF514146B4A0C713..."
```

Based on the [osm2pgsql docs](https://osm2pgsql.org/doc/manual.html#geometry-transformations) and how the polygon data has worked I expect the LineString data to automatically be converted to MultiLineString.


#### Version 

```
osm2pgsql version 1.4.0 (1.4.0-72-gc3eb0fb6)
Compiled using the following library versions:
Libosmium 2.15.6
Proj [API 4] Rel. 7.1.0, August 1st, 2020
Lua 5.3.3
```

#### `place.lua` 

```lua

-- Change SRID if desired
local srid = 3857

local tables = {}


tables.place_point = osm2pgsql.define_table({
    name = 'place_point',
    schema = 'osm',
    ids = { type = 'node', id_column = 'osm_id' },
    columns = {
        { column = 'osm_type',     type = 'text', not_null = true },
        { column = 'name',     type = 'text' },
        { column = 'geom',     type = 'point' , projection = srid},
    }
})

tables.place_line = osm2pgsql.define_table({
    name = 'place_line',
    schema = 'osm',
    ids = { type = 'way', id_column = 'osm_id' },
    columns = {
        { column = 'osm_type',     type = 'text', not_null = true },
        { column = 'name',     type = 'text' },
        { column = 'geom',     type = 'multilinestring' , projection = srid},
    }
})


tables.place_polygon = osm2pgsql.define_table({
    name = 'place_polygon',
    schema = 'osm',
    ids = { type = 'area', id_column = 'osm_id' },
    columns = {
        { column = 'osm_type',     type = 'text', not_null = true },
        { column = 'name',     type = 'text' },
        { column = 'geom',     type = 'multipolygon' , projection = srid},
    }
})


function place_process_node(object)
    if not object.tags.place then
        return
    end

    -- Using grab_tag() removes from remaining key/value saved to Pg
    local osm_type = object:grab_tag('place')
    local name = object:grab_tag('name')

    tables.place_point:add_row({
        osm_type = osm_type,
        name = name,
        geom = { create = 'point' }
    })

end

-- Change function name here
function place_process_way(object)
    if not object.tags.place then
        return
    end

    local osm_type = object:grab_tag('place')
    local name = object:grab_tag('name')

    if object.is_closed then
        tables.place_polygon:add_row({
            osm_type = osm_type,
            name = name,
            geom = { create = 'area' }
        })
    else
        tables.place_line:add_row({
            osm_type = osm_type,
            name = name,
            geom = { create = 'line' }
        })
    end
    
end


function place_process_relation(object)
    if not object.tags.place then
        return
    end

    local osm_type = object:grab_tag('place')
    local name = object:grab_tag('name')

    if object.tags.type == 'multipolygon' or object.tags.type == 'boundary' then
        tables.place_polygon:add_row({
            osm_type = osm_type,
            name = name,
            geom = { create = 'area' }
        })
    else
        tables.place_line:add_row({
            osm_type = osm_type,
            name = name,
            geom = { create = 'line' }
         })
    end
end



-- deep_copy based on copy2: https://gist.github.com/tylerneylon/81333721109155b2d244
function deep_copy(obj)
    if type(obj) ~= 'table' then return obj end
    local res = setmetatable({}, getmetatable(obj))
    for k, v in pairs(obj) do res[deep_copy(k)] = deep_copy(v) end
    return res
end


if osm2pgsql.process_node == nil then
    -- Change function name here
    osm2pgsql.process_node = place_process_node
else
    local nested = osm2pgsql.process_node
    osm2pgsql.process_node = function(object)
        local object_copy = deep_copy(object)
        nested(object)
        -- Change function name here
        place_process_node(object_copy)
    end
end



if osm2pgsql.process_way == nil then
    -- Change function name here
    osm2pgsql.process_way = place_process_way
else
    local nested = osm2pgsql.process_way
    osm2pgsql.process_way = function(object)
        local object_copy = deep_copy(object)
        nested(object)
        -- Change function name here
        place_process_way(object_copy)
    end
end


if osm2pgsql.process_relation == nil then
    -- Change function name here
    osm2pgsql.process_relation = place_process_relation
else
    local nested = osm2pgsql.process_relation
    osm2pgsql.process_relation = function(object)
        local object_copy = deep_copy(object)
        nested(object)
        -- Change function name here
        place_process_relation(object_copy)
    end
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/1386
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstreetmap.org/pipermail/tile-serving/attachments/20210101/c2b77c1d/attachment.htm>


More information about the Tile-serving mailing list