Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions src/output-flex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,32 @@ static void write_json(json_writer_type *writer, lua_State *lua_state,
}
}

static bool is_compatible(geom::geometry_t const &geom,
table_column_type type) noexcept
{
switch (type) {
case table_column_type::geometry:
return true;
case table_column_type::point:
return geom.is_point();
case table_column_type::linestring:
return geom.is_linestring();
case table_column_type::polygon:
return geom.is_polygon();
case table_column_type::multipoint:
return geom.is_point() || geom.is_multipoint();
case table_column_type::multilinestring:
return geom.is_linestring() || geom.is_multilinestring();
case table_column_type::multipolygon:
return geom.is_polygon() || geom.is_multipolygon();
case table_column_type::geometrycollection:
return geom.is_collection();
default:
break;
}
return false;
}

void output_flex_t::write_column(
db_copy_mgr_t<db_deleter_by_type_and_id_t> *copy_mgr,
flex_table_column_t const &column)
Expand Down Expand Up @@ -672,19 +698,30 @@ void output_flex_t::write_column(
if (ltype == LUA_TUSERDATA) {
auto const *const geom = unpack_geometry(lua_state(), -1);
if (geom && !geom->is_null()) {
auto const type = column.type();
if (!is_compatible(*geom, type)) {
throw std::runtime_error{
"Geometry data for geometry column '{}'"
" has the wrong type ({})."_format(
column.name(), geometry_type(*geom))};
}
bool const wrap_multi =
(type == table_column_type::multipoint ||
type == table_column_type::multilinestring ||
type == table_column_type::multipolygon);
if (geom->srid() == column.srid()) {
// OSM id not available here, so use dummy 0, it is used
// for debug messages only anyway.
m_expire.from_geometry(*geom, 0);
copy_mgr->add_hex_geom(geom_to_ewkb(*geom));
copy_mgr->add_hex_geom(geom_to_ewkb(*geom, wrap_multi));
} else {
auto const proj =
reprojection::create_projection(column.srid());
auto const tgeom = geom::transform(*geom, *proj);
// OSM id not available here, so use dummy 0, it is used
// for debug messages only anyway.
m_expire.from_geometry(tgeom, 0);
copy_mgr->add_hex_geom(geom_to_ewkb(tgeom));
copy_mgr->add_hex_geom(geom_to_ewkb(tgeom, wrap_multi));
}
} else {
write_null(copy_mgr, column);
Expand Down
67 changes: 67 additions & 0 deletions tests/bdd/flex/geometry-linestring.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Feature: Creating linestring features from way

Scenario:
Given the grid
| 1 | 2 | |
| 4 | | 3 |
| | 5 | |
And the OSM data
"""
w20 Thighway=motorway Nn1,n2,n3
w21 Thighway=motorway Nn4,n5
"""
And the lua style
"""
local lines = osm2pgsql.define_way_table('osm2pgsql_test_lines', {
{ column = 'sgeom', type = 'linestring', projection = 4326 },
{ column = 'mgeom', type = 'multilinestring', projection = 4326 },
{ column = 'xgeom', type = 'multilinestring', projection = 4326 },
})

function osm2pgsql.process_way(object)
if object.tags.highway == 'motorway' then
lines:insert({
sgeom = object:as_linestring(),
mgeom = object:as_multilinestring(),
xgeom = object:as_linestring()
})
end
end

"""
When running osm2pgsql flex

Then table osm2pgsql_test_lines contains exactly
| way_id | ST_AsText(sgeom) | ST_AsText(ST_GeometryN(mgeom, 1)) | ST_AsText(ST_GeometryN(xgeom, 1)) |
| 20 | 1, 2, 3 | 1, 2, 3 | 1, 2, 3 |
| 21 | 4, 5 | 4, 5 | 4, 5 |

Scenario:
Given the grid
| 1 | 2 |
And the OSM data
"""
w20 Thighway=motorway Nn1,n2
"""
And the lua style
"""
local lines = osm2pgsql.define_way_table('osm2pgsql_test_lines', {
{ column = 'geom', type = 'polygon', projection = 4326 },
})

function osm2pgsql.process_way(object)
if object.tags.highway == 'motorway' then
lines:insert({
geom = object:as_linestring(),
})
end
end

"""
Then running osm2pgsql flex fails

And the error output contains
"""
Geometry data for geometry column 'geom' has the wrong type (LINESTRING).
"""