Skip to content

Commit 152bafc

Browse files
authored
Merge pull request #1745 from joto/geom-wrap-in-multi
Wrap geometries in multi if needed and check geom type compatibility
2 parents 65d0d27 + 34c9cef commit 152bafc

File tree

2 files changed

+106
-2
lines changed

2 files changed

+106
-2
lines changed

src/output-flex.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,32 @@ static void write_json(json_writer_type *writer, lua_State *lua_state,
494494
}
495495
}
496496

497+
static bool is_compatible(geom::geometry_t const &geom,
498+
table_column_type type) noexcept
499+
{
500+
switch (type) {
501+
case table_column_type::geometry:
502+
return true;
503+
case table_column_type::point:
504+
return geom.is_point();
505+
case table_column_type::linestring:
506+
return geom.is_linestring();
507+
case table_column_type::polygon:
508+
return geom.is_polygon();
509+
case table_column_type::multipoint:
510+
return geom.is_point() || geom.is_multipoint();
511+
case table_column_type::multilinestring:
512+
return geom.is_linestring() || geom.is_multilinestring();
513+
case table_column_type::multipolygon:
514+
return geom.is_polygon() || geom.is_multipolygon();
515+
case table_column_type::geometrycollection:
516+
return geom.is_collection();
517+
default:
518+
break;
519+
}
520+
return false;
521+
}
522+
497523
void output_flex_t::write_column(
498524
db_copy_mgr_t<db_deleter_by_type_and_id_t> *copy_mgr,
499525
flex_table_column_t const &column)
@@ -672,19 +698,30 @@ void output_flex_t::write_column(
672698
if (ltype == LUA_TUSERDATA) {
673699
auto const *const geom = unpack_geometry(lua_state(), -1);
674700
if (geom && !geom->is_null()) {
701+
auto const type = column.type();
702+
if (!is_compatible(*geom, type)) {
703+
throw std::runtime_error{
704+
"Geometry data for geometry column '{}'"
705+
" has the wrong type ({})."_format(
706+
column.name(), geometry_type(*geom))};
707+
}
708+
bool const wrap_multi =
709+
(type == table_column_type::multipoint ||
710+
type == table_column_type::multilinestring ||
711+
type == table_column_type::multipolygon);
675712
if (geom->srid() == column.srid()) {
676713
// OSM id not available here, so use dummy 0, it is used
677714
// for debug messages only anyway.
678715
m_expire.from_geometry(*geom, 0);
679-
copy_mgr->add_hex_geom(geom_to_ewkb(*geom));
716+
copy_mgr->add_hex_geom(geom_to_ewkb(*geom, wrap_multi));
680717
} else {
681718
auto const proj =
682719
reprojection::create_projection(column.srid());
683720
auto const tgeom = geom::transform(*geom, *proj);
684721
// OSM id not available here, so use dummy 0, it is used
685722
// for debug messages only anyway.
686723
m_expire.from_geometry(tgeom, 0);
687-
copy_mgr->add_hex_geom(geom_to_ewkb(tgeom));
724+
copy_mgr->add_hex_geom(geom_to_ewkb(tgeom, wrap_multi));
688725
}
689726
} else {
690727
write_null(copy_mgr, column);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
Feature: Creating linestring features from way
2+
3+
Scenario:
4+
Given the grid
5+
| 1 | 2 | |
6+
| 4 | | 3 |
7+
| | 5 | |
8+
And the OSM data
9+
"""
10+
w20 Thighway=motorway Nn1,n2,n3
11+
w21 Thighway=motorway Nn4,n5
12+
"""
13+
And the lua style
14+
"""
15+
local lines = osm2pgsql.define_way_table('osm2pgsql_test_lines', {
16+
{ column = 'sgeom', type = 'linestring', projection = 4326 },
17+
{ column = 'mgeom', type = 'multilinestring', projection = 4326 },
18+
{ column = 'xgeom', type = 'multilinestring', projection = 4326 },
19+
})
20+
21+
function osm2pgsql.process_way(object)
22+
if object.tags.highway == 'motorway' then
23+
lines:insert({
24+
sgeom = object:as_linestring(),
25+
mgeom = object:as_multilinestring(),
26+
xgeom = object:as_linestring()
27+
})
28+
end
29+
end
30+
31+
"""
32+
When running osm2pgsql flex
33+
34+
Then table osm2pgsql_test_lines contains exactly
35+
| way_id | ST_AsText(sgeom) | ST_AsText(ST_GeometryN(mgeom, 1)) | ST_AsText(ST_GeometryN(xgeom, 1)) |
36+
| 20 | 1, 2, 3 | 1, 2, 3 | 1, 2, 3 |
37+
| 21 | 4, 5 | 4, 5 | 4, 5 |
38+
39+
Scenario:
40+
Given the grid
41+
| 1 | 2 |
42+
And the OSM data
43+
"""
44+
w20 Thighway=motorway Nn1,n2
45+
"""
46+
And the lua style
47+
"""
48+
local lines = osm2pgsql.define_way_table('osm2pgsql_test_lines', {
49+
{ column = 'geom', type = 'polygon', projection = 4326 },
50+
})
51+
52+
function osm2pgsql.process_way(object)
53+
if object.tags.highway == 'motorway' then
54+
lines:insert({
55+
geom = object:as_linestring(),
56+
})
57+
end
58+
end
59+
60+
"""
61+
Then running osm2pgsql flex fails
62+
63+
And the error output contains
64+
"""
65+
Geometry data for geometry column 'geom' has the wrong type (LINESTRING).
66+
"""
67+

0 commit comments

Comments
 (0)