diff --git a/flex-config/compatible.lua b/flex-config/compatible.lua index c12912608..d83d32add 100644 --- a/flex-config/compatible.lua +++ b/flex-config/compatible.lua @@ -14,8 +14,8 @@ local keep_coastlines = false -- Set this to the table name prefix (what used to be option -p|--prefix). local prefix = 'planet_osm' --- Set this to true if multipolygons should be written as polygons into db --- (what used to be option -G|--multi-geometry). +-- Set this to true if multipolygons should be written as multipolygons into +-- db (what used to be option -G|--multi-geometry). local multi_geometry = false -- Set this to true if you want an hstore column (what used to be option @@ -724,7 +724,10 @@ function osm2pgsql.process_relation(object) end if make_boundary or make_polygon then - output.way = { create = 'area', multi = multi_geometry } + output.way = { create = 'area' } + if not multi_geometry then + output.way.split_at = 'multi' + end tables.polygon:add_row(output) end end diff --git a/src/geom-transform.cpp b/src/geom-transform.cpp index 59439cf99..5242678b9 100644 --- a/src/geom-transform.cpp +++ b/src/geom-transform.cpp @@ -16,6 +16,7 @@ bool geom_transform_point_t::is_compatible_with( geom::osmium_builder_t::wkbs_t geom_transform_point_t::run(geom::osmium_builder_t *builder, + table_column_type /*target_geom_type*/, osmium::Node const &node) const { assert(builder); @@ -49,6 +50,7 @@ bool geom_transform_line_t::is_compatible_with( geom::osmium_builder_t::wkbs_t geom_transform_line_t::run(geom::osmium_builder_t *builder, + table_column_type /*target_geom_type*/, osmium::Way *way) const { assert(builder); @@ -59,6 +61,7 @@ geom_transform_line_t::run(geom::osmium_builder_t *builder, geom::osmium_builder_t::wkbs_t geom_transform_line_t::run(geom::osmium_builder_t *builder, + table_column_type /*target_geom_type*/, osmium::Relation const & /*relation*/, osmium::memory::Buffer const &buffer) const { @@ -69,48 +72,61 @@ geom_transform_line_t::run(geom::osmium_builder_t *builder, bool geom_transform_area_t::set_param(char const *name, lua_State *lua_state) { - if (std::strcmp(name, "multi") != 0) { + if (std::strcmp(name, "multi") == 0) { + throw std::runtime_error{ + "The 'multi' field in the geometry transformation has been" + " removed. See docs on how to use 'split_at' instead."}; + } + + if (std::strcmp(name, "split_at") != 0) { return false; } - if (lua_type(lua_state, -1) != LUA_TBOOLEAN) { + auto const val = lua_tostring(lua_state, -1); + + if (!val) { throw std::runtime_error{ - "The 'multi' field in a geometry transformation " - "description must be a boolean."}; + "The 'split_at' field in a geometry transformation " + "description must be a string."}; } - m_multi = lua_toboolean(lua_state, -1); - return true; + if (std::strcmp(val, "multi") == 0) { + m_multi = false; + return true; + } + + throw std::runtime_error{"Unknown value for 'split_at' field in a geometry" + " transformation: '{}'"_format(val)}; } bool geom_transform_area_t::is_compatible_with( table_column_type geom_type) const noexcept { - if (m_multi) { - return geom_type == table_column_type::multipolygon || - geom_type == table_column_type::geometry; - } - return geom_type == table_column_type::polygon || + geom_type == table_column_type::multipolygon || geom_type == table_column_type::geometry; } geom::osmium_builder_t::wkbs_t geom_transform_area_t::run(geom::osmium_builder_t *builder, + table_column_type target_geom_type, osmium::Way *way) const { assert(builder); assert(way); + geom::osmium_builder_t::wkbs_t result; + if (!way->is_closed()) { - return {}; + return result; } - geom::osmium_builder_t::wkbs_t result; result.push_back(builder->get_wkb_polygon(*way)); if (result.front().empty()) { result.clear(); + } else if (target_geom_type == table_column_type::multipolygon) { + builder->wrap_in_multipolygon(&result); } return result; @@ -118,12 +134,15 @@ geom_transform_area_t::run(geom::osmium_builder_t *builder, geom::osmium_builder_t::wkbs_t geom_transform_area_t::run(geom::osmium_builder_t *builder, + table_column_type target_geom_type, osmium::Relation const &relation, osmium::memory::Buffer const &buffer) const { assert(builder); - return builder->get_wkb_multipolygon(relation, buffer, m_multi); + bool const wrap_multi = target_geom_type == table_column_type::multipolygon; + + return builder->get_wkb_multipolygon(relation, buffer, m_multi, wrap_multi); } std::unique_ptr create_geom_transform(char const *type) diff --git a/src/geom-transform.hpp b/src/geom-transform.hpp index 1e84f266b..bad82900a 100644 --- a/src/geom-transform.hpp +++ b/src/geom-transform.hpp @@ -32,19 +32,22 @@ class geom_transform_t virtual geom::osmium_builder_t::wkbs_t run(geom::osmium_builder_t * /*builder*/, + table_column_type /*target_geom_type*/, osmium::Node const & /*node*/) const { return {}; } virtual geom::osmium_builder_t::wkbs_t - run(geom::osmium_builder_t * /*builder*/, osmium::Way * /*way*/) const + run(geom::osmium_builder_t * /*builder*/, + table_column_type /*target_geom_type*/, osmium::Way * /*way*/) const { return {}; } virtual geom::osmium_builder_t::wkbs_t run(geom::osmium_builder_t * /*builder*/, + table_column_type /*target_geom_type*/, osmium::Relation const & /*relation*/, osmium::memory::Buffer const & /*buffer*/) const { @@ -60,6 +63,7 @@ class geom_transform_point_t : public geom_transform_t noexcept override; geom::osmium_builder_t::wkbs_t run(geom::osmium_builder_t *builder, + table_column_type target_geom_type, osmium::Node const &node) const override; }; // class geom_transform_point_t @@ -73,10 +77,12 @@ class geom_transform_line_t : public geom_transform_t noexcept override; geom::osmium_builder_t::wkbs_t run(geom::osmium_builder_t *builder, + table_column_type target_geom_type, osmium::Way *way) const override; geom::osmium_builder_t::wkbs_t - run(geom::osmium_builder_t *builder, osmium::Relation const &relation, + run(geom::osmium_builder_t *builder, table_column_type target_geom_type, + osmium::Relation const &relation, osmium::memory::Buffer const &buffer) const override; private: @@ -93,14 +99,16 @@ class geom_transform_area_t : public geom_transform_t noexcept override; geom::osmium_builder_t::wkbs_t run(geom::osmium_builder_t *builder, + table_column_type target_geom_type, osmium::Way *way) const override; geom::osmium_builder_t::wkbs_t - run(geom::osmium_builder_t *builder, osmium::Relation const &relation, + run(geom::osmium_builder_t *builder, table_column_type target_geom_type, + osmium::Relation const &relation, osmium::memory::Buffer const &buffer) const override; private: - bool m_multi = false; + bool m_multi = true; }; // class geom_transform_area_t diff --git a/src/osmium-builder.cpp b/src/osmium-builder.cpp index b329a999a..da58fd76f 100644 --- a/src/osmium-builder.cpp +++ b/src/osmium-builder.cpp @@ -47,6 +47,26 @@ void add_nodes_to_builder(osmium::builder::WayNodeListBuilder &builder, namespace geom { +void osmium_builder_t::wrap_in_multipolygon( + osmium_builder_t::wkbs_t *geometries) +{ + assert(!geometries->empty()); + + m_writer.multipolygon_start(); + for (auto const &p : *geometries) { + m_writer.add_sub_geometry(p); + } + (*geometries)[0] = m_writer.multipolygon_finish(geometries->size()); + geometries->resize(1); +} + +void osmium_builder_t::wrap_in_multipolygon(osmium_builder_t::wkb_t *geometry) +{ + m_writer.multipolygon_start(); + m_writer.add_sub_geometry(*geometry); + *geometry = m_writer.multipolygon_finish(1); +} + osmium_builder_t::wkb_t osmium_builder_t::get_wkb_node(osmium::Location const &loc) const { @@ -145,28 +165,41 @@ osmium_builder_t::get_wkb_polygon(osmium::Way const &way) auto const wkbs = create_polygons(m_buffer.get(0)); - return wkbs.empty() ? wkb_t() : wkbs[0]; + return wkbs.empty() ? wkb_t{} : wkbs[0]; } osmium_builder_t::wkbs_t osmium_builder_t::get_wkb_multipolygon(osmium::Relation const &rel, osmium::memory::Buffer const &ways, - bool build_multigeoms) + bool build_multigeoms, bool wrap_multi) { - wkbs_t ret; osmium::area::AssemblerConfig area_config; area_config.ignore_invalid_locations = true; osmium::area::GeomAssembler assembler{area_config}; m_buffer.clear(); + + wkbs_t ret; if (assembler(rel, ways, m_buffer)) { + auto const &area = m_buffer.get(0); + + // This returns a vector of one or more polygons + ret = create_polygons(area); + assert(!ret.empty()); + if (build_multigeoms) { - ret.push_back(create_multipolygon(m_buffer.get(0))); + if (ret.size() > 1 || wrap_multi) { + wrap_in_multipolygon(&ret); + } } else { - ret = create_polygons(m_buffer.get(0)); + if (wrap_multi) { + for (auto &wkb : ret) { + // wrap each polygon into its own multipolygon + wrap_in_multipolygon(&wkb); + } + } } } - return ret; } @@ -345,31 +378,6 @@ size_t osmium_builder_t::add_mp_points(osmium::NodeRefList const &nodes) return num_points; } -osmium_builder_t::wkb_t -osmium_builder_t::create_multipolygon(osmium::Area const &area) -{ - wkb_t ret; - - auto const polys = create_polygons(area); - - switch (polys.size()) { - case 0: - break; //nothing - case 1: - ret = polys[0]; - break; - default: - m_writer.multipolygon_start(); - for (auto const &p : polys) { - m_writer.add_sub_geometry(p); - } - ret = m_writer.multipolygon_finish(polys.size()); - break; - } - - return ret; -} - osmium_builder_t::wkbs_t osmium_builder_t::create_polygons(osmium::Area const &area) { diff --git a/src/osmium-builder.hpp b/src/osmium-builder.hpp index a1f667a46..75bfac29f 100644 --- a/src/osmium-builder.hpp +++ b/src/osmium-builder.hpp @@ -30,13 +30,24 @@ class osmium_builder_t wkbs_t get_wkb_multipolygon(osmium::Relation const &rel, osmium::memory::Buffer const &ways, - bool build_multigeoms); + bool build_multigeoms, bool wrap_multi = false); wkbs_t get_wkb_multiline(osmium::memory::Buffer const &ways, double split_at); + /** + * Wrap the geometries (must be one or more polygons) in the parameter + * into a single multipolygon which is returned in-place in geometries. + */ + void wrap_in_multipolygon(wkbs_t *geometries); + + /** + * Wrap the polygon geometry in the parameter into a multipolygon which + * is returned in-place in geometry. + */ + void wrap_in_multipolygon(wkb_t *geometry); + private: - wkb_t create_multipolygon(osmium::Area const &area); wkbs_t create_polygons(osmium::Area const &area); size_t add_mp_points(osmium::NodeRefList const &nodes); diff --git a/src/output-flex.cpp b/src/output-flex.cpp index 146a46750..596c241f7 100644 --- a/src/output-flex.cpp +++ b/src/output-flex.cpp @@ -967,25 +967,28 @@ get_default_transform(flex_table_column_t const &column, geom::osmium_builder_t::wkbs_t output_flex_t::run_transform(geom::osmium_builder_t *builder, geom_transform_t const *transform, + table_column_type target_geom_type, osmium::Node const &node) { - return transform->run(builder, node); + return transform->run(builder, target_geom_type, node); } geom::osmium_builder_t::wkbs_t output_flex_t::run_transform(geom::osmium_builder_t *builder, geom_transform_t const *transform, + table_column_type target_geom_type, osmium::Way const & /*way*/) { if (get_way_nodes() <= 1U) { return {}; } - return transform->run(builder, m_context_way); + return transform->run(builder, target_geom_type, m_context_way); } geom::osmium_builder_t::wkbs_t output_flex_t::run_transform(geom::osmium_builder_t *builder, geom_transform_t const *transform, + table_column_type target_geom_type, osmium::Relation const &relation) { m_buffer.clear(); @@ -1000,7 +1003,7 @@ output_flex_t::run_transform(geom::osmium_builder_t *builder, m_mid->nodes_get_list(&(way.nodes())); } - return transform->run(builder, relation, m_buffer); + return transform->run(builder, target_geom_type, relation, m_buffer); } template @@ -1035,7 +1038,8 @@ void output_flex_t::add_row(table_connection_t *table_connection, } auto *builder = table_connection->get_builder(); - auto const wkbs = run_transform(builder, transform, object); + auto const wkbs = + run_transform(builder, transform, table.geom_column().type(), object); for (auto const &wkb : wkbs) { m_expire.from_wkb(wkb.c_str(), id); write_row(table_connection, object.type(), id, wkb, diff --git a/src/output-flex.hpp b/src/output-flex.hpp index b38836aac..2929d7f6a 100644 --- a/src/output-flex.hpp +++ b/src/output-flex.hpp @@ -181,16 +181,17 @@ class output_flex_t : public output_t geom::osmium_builder_t::wkbs_t run_transform(geom::osmium_builder_t *builder, - geom_transform_t const *transform, osmium::Node const &node); - - geom::osmium_builder_t::wkbs_t - run_transform(geom::osmium_builder_t *builder, - geom_transform_t const *transform, osmium::Way const &way); + geom_transform_t const *transform, + table_column_type target_geom_type, osmium::Node const &node); geom::osmium_builder_t::wkbs_t run_transform(geom::osmium_builder_t *builder, geom_transform_t const *transform, - osmium::Relation const &relation); + table_column_type target_geom_type, osmium::Way const &way); + + geom::osmium_builder_t::wkbs_t run_transform( + geom::osmium_builder_t *builder, geom_transform_t const *transform, + table_column_type target_geom_type, osmium::Relation const &relation); template void add_row(table_connection_t *table_connection, OBJECT const &object); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 422e1dcad..6c40f8ef9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -80,6 +80,7 @@ if (HAVE_LUA) set_test(test-output-flex-invalid-geom) set_test(test-output-flex-line) set_test(test-output-flex-lua-fail) + set_test(test-output-flex-multigeom) set_test(test-output-flex-nodes) set_test(test-output-flex-nogeom) set_test(test-output-flex-uni) diff --git a/tests/data/test_output_flex.lua b/tests/data/test_output_flex.lua index a3c792ff5..e28e87df5 100644 --- a/tests/data/test_output_flex.lua +++ b/tests/data/test_output_flex.lua @@ -117,7 +117,7 @@ function osm2pgsql.process_relation(object) tables.polygon:add_row({ tags = object.tags, name = object.tags.name, - geom = { create = 'area', multi = false } + geom = { create = 'area', split_at = 'multi' } }) return end diff --git a/tests/data/test_output_flex_area.lua b/tests/data/test_output_flex_area.lua index 8a188a7d1..662868c43 100644 --- a/tests/data/test_output_flex_area.lua +++ b/tests/data/test_output_flex_area.lua @@ -27,7 +27,7 @@ end function osm2pgsql.process_relation(object) polygons:add_row({ name = object.tags.name, - geom = { create = 'area', multi = false } + geom = { create = 'area', split_at = 'multi' } }) end diff --git a/tests/data/test_output_flex_invalid_geom.lua b/tests/data/test_output_flex_invalid_geom.lua index e2ff152d6..feaf25acb 100644 --- a/tests/data/test_output_flex_invalid_geom.lua +++ b/tests/data/test_output_flex_invalid_geom.lua @@ -39,7 +39,7 @@ end function osm2pgsql.process_relation(object) tables.polygon:add_row({ tags = object.tags, - geom = { create = 'area', multi = false } + geom = { create = 'area', split_at = 'multi' } }) end diff --git a/tests/data/test_output_flex_multigeom.lua b/tests/data/test_output_flex_multigeom.lua new file mode 100644 index 000000000..96094e56c --- /dev/null +++ b/tests/data/test_output_flex_multigeom.lua @@ -0,0 +1,32 @@ + +local polygons = osm2pgsql.define_table{ + name = 'osm2pgsql_test_polygon', + ids = { type = 'area', id_column = 'osm_id' }, + columns = { + { column = 'name', type = 'text' }, + { column = 'geom', type = test.type } + } +} + +function is_empty(some_table) + return next(some_table) == nil +end + +function osm2pgsql.process_way(object) + if is_empty(object.tags) then + return + end + + polygons:add_row({ + name = object.tags.name, + geom = { create = 'area' } + }) +end + +function osm2pgsql.process_relation(object) + polygons:add_row({ + name = object.tags.name, + geom = { create = 'area', split_at = test.split_at } + }) +end + diff --git a/tests/data/test_output_flex_multigeom.osm b/tests/data/test_output_flex_multigeom.osm new file mode 100644 index 000000000..51d37ebbf --- /dev/null +++ b/tests/data/test_output_flex_multigeom.osm @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test_output_flex_multigeom_geometry.lua b/tests/data/test_output_flex_multigeom_geometry.lua new file mode 100644 index 000000000..d3b82e460 --- /dev/null +++ b/tests/data/test_output_flex_multigeom_geometry.lua @@ -0,0 +1,5 @@ + +test = { type = 'geometry' } + +dofile(os.getenv('SRCPATH') .. '/data/test_output_flex_multigeom.lua') + diff --git a/tests/data/test_output_flex_multigeom_geometry_split.lua b/tests/data/test_output_flex_multigeom_geometry_split.lua new file mode 100644 index 000000000..79ca67904 --- /dev/null +++ b/tests/data/test_output_flex_multigeom_geometry_split.lua @@ -0,0 +1,5 @@ + +test = { type = 'geometry', split_at = 'multi' } + +dofile(os.getenv('SRCPATH') .. '/data/test_output_flex_multigeom.lua') + diff --git a/tests/data/test_output_flex_multigeom_multipolygon.lua b/tests/data/test_output_flex_multigeom_multipolygon.lua new file mode 100644 index 000000000..baaaa02e7 --- /dev/null +++ b/tests/data/test_output_flex_multigeom_multipolygon.lua @@ -0,0 +1,5 @@ + +test = { type = 'multipolygon' } + +dofile(os.getenv('SRCPATH') .. '/data/test_output_flex_multigeom.lua') + diff --git a/tests/data/test_output_flex_multigeom_multipolygon_split.lua b/tests/data/test_output_flex_multigeom_multipolygon_split.lua new file mode 100644 index 000000000..fa39ba3db --- /dev/null +++ b/tests/data/test_output_flex_multigeom_multipolygon_split.lua @@ -0,0 +1,5 @@ + +test = { type = 'multipolygon', split_at = 'multi' } + +dofile(os.getenv('SRCPATH') .. '/data/test_output_flex_multigeom.lua') + diff --git a/tests/data/test_output_flex_multigeom_polygon.lua b/tests/data/test_output_flex_multigeom_polygon.lua new file mode 100644 index 000000000..f1d7a863a --- /dev/null +++ b/tests/data/test_output_flex_multigeom_polygon.lua @@ -0,0 +1,5 @@ + +test = { type = 'polygon', split_at = 'multi' } + +dofile(os.getenv('SRCPATH') .. '/data/test_output_flex_multigeom.lua') + diff --git a/tests/data/test_output_flex_uni.lua b/tests/data/test_output_flex_uni.lua index 655e9b83d..1115ae65f 100644 --- a/tests/data/test_output_flex_uni.lua +++ b/tests/data/test_output_flex_uni.lua @@ -73,11 +73,11 @@ function osm2pgsql.process_relation(object) table1idcol:add_row({ orig_id = object.id, tags = object.tags, - geom = { create = 'area', multi = false } + geom = { create = 'area', split_at = 'multi' } }) table2idcol:add_row({ tags = object.tags, - geom = { create = 'area', multi = false } + geom = { create = 'area', split_at = 'multi' } }) return end diff --git a/tests/data/test_output_flex_validgeom.lua b/tests/data/test_output_flex_validgeom.lua index 40e7b1701..2815f858a 100644 --- a/tests/data/test_output_flex_validgeom.lua +++ b/tests/data/test_output_flex_validgeom.lua @@ -23,7 +23,7 @@ end function osm2pgsql.process_relation(object) polygons:add_row({ - geom = { create = 'area', multi = false } + geom = { create = 'area', split_at='multi' } }) end diff --git a/tests/test-output-flex-multigeom.cpp b/tests/test-output-flex-multigeom.cpp new file mode 100644 index 000000000..cef645e8a --- /dev/null +++ b/tests/test-output-flex-multigeom.cpp @@ -0,0 +1,104 @@ +#include + +#include "common-import.hpp" +#include "common-options.hpp" + +static testing::db::import_t db; + +static char const *const conf_file_geometry = + "test_output_flex_multigeom_geometry.lua"; +static char const *const conf_file_geometry_split = + "test_output_flex_multigeom_geometry_split.lua"; +static char const *const conf_file_polygon = + "test_output_flex_multigeom_polygon.lua"; +static char const *const conf_file_multipolygon = + "test_output_flex_multigeom_multipolygon.lua"; +static char const *const conf_file_multipolygon_split = + "test_output_flex_multigeom_multipolygon_split.lua"; +static char const *const data_file = "test_output_flex_multigeom.osm"; + +TEST_CASE("Use 'geometry' column for area (not splitting multipolygons)") +{ + options_t const options = testing::opt_t().flex(conf_file_geometry); + REQUIRE_NOTHROW(db.run_file(options, data_file)); + + auto conn = db.db().connect(); + + CHECK(3 == conn.get_count("osm2pgsql_test_polygon")); + CHECK(2 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_Polygon'")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_MultiPolygon'")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = 20")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -30")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -31")); +} + +TEST_CASE("Use 'geometry' column for area (splitting multipolygons)") +{ + options_t const options = testing::opt_t().flex(conf_file_geometry_split); + REQUIRE_NOTHROW(db.run_file(options, data_file)); + + auto conn = db.db().connect(); + + CHECK(4 == conn.get_count("osm2pgsql_test_polygon")); + CHECK(4 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_Polygon'")); + CHECK(0 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_MultiPolygon'")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = 20")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -30")); + CHECK(2 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -31")); +} + +TEST_CASE("Use 'polygon' column for area (splitting multipolygons)") +{ + options_t const options = testing::opt_t().flex(conf_file_polygon); + REQUIRE_NOTHROW(db.run_file(options, data_file)); + + auto conn = db.db().connect(); + + CHECK(4 == conn.get_count("osm2pgsql_test_polygon")); + CHECK(4 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_Polygon'")); + CHECK(0 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_MultiPolygon'")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = 20")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -30")); + CHECK(2 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -31")); +} + +TEST_CASE("Use 'multipolygon' column for area (not splitting multipolygons)") +{ + options_t const options = testing::opt_t().flex(conf_file_multipolygon); + REQUIRE_NOTHROW(db.run_file(options, data_file)); + + auto conn = db.db().connect(); + + CHECK(3 == conn.get_count("osm2pgsql_test_polygon")); + CHECK(0 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_Polygon'")); + CHECK(3 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_MultiPolygon'")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = 20")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -30")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -31")); +} + +TEST_CASE("Use 'multipolygon' column for area (splitting multipolygons)") +{ + options_t const options = + testing::opt_t().flex(conf_file_multipolygon_split); + REQUIRE_NOTHROW(db.run_file(options, data_file)); + + auto conn = db.db().connect(); + + CHECK(4 == conn.get_count("osm2pgsql_test_polygon")); + CHECK(0 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_Polygon'")); + CHECK(4 == conn.get_count("osm2pgsql_test_polygon", + "ST_GeometryType(geom) = 'ST_MultiPolygon'")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = 20")); + CHECK(1 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -30")); + CHECK(2 == conn.get_count("osm2pgsql_test_polygon", "osm_id = -31")); +}