diff --git a/src/output-gazetteer.cpp b/src/output-gazetteer.cpp index b42cb30e9..a6f367ee1 100644 --- a/src/output-gazetteer.cpp +++ b/src/output-gazetteer.cpp @@ -15,15 +15,20 @@ void output_gazetteer_t::delete_unused_classes(char osm_type, osmid_t osm_id) { - if (!m_options.append) { - return; - } + if (m_options.append) { + m_copy.prepare(); + + assert(m_style.has_data()); - if (m_style.has_data()) { std::string cls = m_style.class_list(); m_copy.delete_object(osm_type, osm_id, cls); - } else { - /* unconditional delete of all places */ + } +} + +void output_gazetteer_t::delete_unused_full(char osm_type, osmid_t osm_id) +{ + if (m_options.append) { + m_copy.prepare(); m_copy.delete_object(osm_type, osm_id); } } @@ -69,58 +74,101 @@ void output_gazetteer_t::start() void output_gazetteer_t::commit() { m_copy.sync(); } -void output_gazetteer_t::process_node(osmium::Node const &node) +void output_gazetteer_t::node_add(osmium::Node const &node) +{ + if (!process_node(node)) { + delete_unused_full('N', node.id()); + } +} + +void output_gazetteer_t::node_modify(osmium::Node const &node) +{ + if (!process_node(node)) { + delete_unused_full('N', node.id()); + } +} + +bool output_gazetteer_t::process_node(osmium::Node const &node) { - m_copy.prepare(); m_style.process_tags(node); - delete_unused_classes('N', node.id()); /* Are we interested in this item? */ - if (m_style.has_data()) { - auto wkb = m_builder.get_wkb_node(node.location()); - m_style.copy_out(node, wkb, m_copy); + if (!m_style.has_data()) { + return false; + } + + auto wkb = m_builder.get_wkb_node(node.location()); + delete_unused_classes('N', node.id()); + m_style.copy_out(node, wkb, m_copy); + + return true; +} + +void output_gazetteer_t::way_add(osmium::Way *way) +{ + if (!process_way(way)) { + delete_unused_full('W', way->id()); + } +} + +void output_gazetteer_t::way_modify(osmium::Way *way) +{ + if (!process_way(way)) { + delete_unused_full('W', way->id()); } } -void output_gazetteer_t::process_way(osmium::Way *way) +bool output_gazetteer_t::process_way(osmium::Way *way) { - m_copy.prepare(); m_style.process_tags(*way); - delete_unused_classes('W', way->id()); - /* Are we interested in this item? */ - if (m_style.has_data()) { - /* Fetch the node details */ - m_mid->nodes_get_list(&(way->nodes())); - - /* Get the geometry of the object */ - geom::osmium_builder_t::wkb_t geom; - if (way->is_closed()) { - geom = m_builder.get_wkb_polygon(*way); - } - if (geom.empty()) { - auto wkbs = m_builder.get_wkb_line(way->nodes(), 0.0); - if (wkbs.empty()) { - delete_unused_full('W', way->id()); - return; - } - - geom = wkbs[0]; + if (!m_style.has_data()) { + return false; + } + + // Fetch the node details. + m_mid->nodes_get_list(&(way->nodes())); + + // Get the geometry of the object. + geom::osmium_builder_t::wkb_t geom; + if (way->is_closed()) { + geom = m_builder.get_wkb_polygon(*way); + } + if (geom.empty()) { + auto wkbs = m_builder.get_wkb_line(way->nodes(), 0.0); + if (wkbs.empty()) { + return false; } - m_style.copy_out(*way, geom, m_copy); + geom = wkbs[0]; + } + + delete_unused_classes('W', way->id()); + m_style.copy_out(*way, geom, m_copy); + + return true; +} + +void output_gazetteer_t::relation_add(osmium::Relation const &rel) +{ + if (!process_relation(rel)) { + delete_unused_full('R', rel.id()); } } -void output_gazetteer_t::process_relation(osmium::Relation const &rel) +void output_gazetteer_t::relation_modify(osmium::Relation const &rel) { - m_copy.prepare(); + if (!process_relation(rel)) { + delete_unused_full('R', rel.id()); + } +} +bool output_gazetteer_t::process_relation(osmium::Relation const &rel) +{ auto const &tags = rel.tags(); char const *type = tags["type"]; if (!type) { - delete_unused_full('R', rel.id()); - return; + return false; } bool is_waterway = strcmp(type, "waterway") == 0; @@ -128,16 +176,14 @@ void output_gazetteer_t::process_relation(osmium::Relation const &rel) if (strcmp(type, "associatedStreet") == 0 || !(strcmp(type, "boundary") == 0 || strcmp(type, "multipolygon") == 0 || is_waterway)) { - delete_unused_full('R', rel.id()); - return; + return false; } m_style.process_tags(rel); - delete_unused_classes('R', rel.id()); /* Are we interested in this item? */ if (!m_style.has_data()) { - return; + return false; } /* get the boundary path (ways) */ @@ -145,8 +191,7 @@ void output_gazetteer_t::process_relation(osmium::Relation const &rel) auto num_ways = m_mid->rel_way_members_get(rel, nullptr, osmium_buffer); if (num_ways == 0) { - delete_unused_full('R', rel.id()); - return; + return false; } for (auto &w : osmium_buffer.select()) { @@ -158,8 +203,11 @@ void output_gazetteer_t::process_relation(osmium::Relation const &rel) : m_builder.get_wkb_multipolygon(rel, osmium_buffer); if (geoms.empty()) { - delete_unused_full('R', rel.id()); - } else { - m_style.copy_out(rel, geoms[0], m_copy); + return false; } + + delete_unused_classes('R', rel.id()); + m_style.copy_out(rel, geoms[0], m_copy); + + return true; } diff --git a/src/output-gazetteer.hpp b/src/output-gazetteer.hpp index 55bdbeae2..e466ed97d 100644 --- a/src/output-gazetteer.hpp +++ b/src/output-gazetteer.hpp @@ -54,29 +54,17 @@ class output_gazetteer_t : public output_t {} void pending_relation(osmid_t, int) override {} - void node_add(osmium::Node const &node) override { process_node(node); } + void node_add(osmium::Node const &node) override; + void way_add(osmium::Way *way) override; + void relation_add(osmium::Relation const &rel) override; - void way_add(osmium::Way *way) override { process_way(way); } + void node_modify(osmium::Node const &node) override; + void way_modify(osmium::Way *way) override; + void relation_modify(osmium::Relation const &rel) override; - void relation_add(osmium::Relation const &rel) override - { - process_relation(rel); - } - - void node_modify(osmium::Node const &node) override { process_node(node); } - - void way_modify(osmium::Way *way) override { process_way(way); } - - void relation_modify(osmium::Relation const &rel) override - { - process_relation(rel); - } - - void node_delete(osmid_t id) override { m_copy.delete_object('N', id); } - - void way_delete(osmid_t id) override { m_copy.delete_object('W', id); } - - void relation_delete(osmid_t id) override { m_copy.delete_object('R', id); } + void node_delete(osmid_t id) override { delete_unused_full('N', id); } + void way_delete(osmid_t id) override { delete_unused_full('W', id); } + void relation_delete(osmid_t id) override { delete_unused_full('R', id); } private: enum @@ -86,16 +74,11 @@ class output_gazetteer_t : public output_t /// Delete all places that are not covered by the current style results. void delete_unused_classes(char osm_type, osmid_t osm_id); - void process_node(osmium::Node const &node); - void process_way(osmium::Way *way); - void process_relation(osmium::Relation const &rel); - - void delete_unused_full(char osm_type, osmid_t osm_id) - { - if (m_options.append) { - m_copy.delete_object(osm_type, osm_id); - } - } + /// Delete all places for the given OSM object. + void delete_unused_full(char osm_type, osmid_t osm_id); + bool process_node(osmium::Node const &node); + bool process_way(osmium::Way *way); + bool process_relation(osmium::Relation const &rel); gazetteer_copy_mgr_t m_copy; gazetteer_style_t m_style; diff --git a/tests/test-output-gazetteer.cpp b/tests/test-output-gazetteer.cpp index 35c907bbb..0a0fe845f 100644 --- a/tests/test-output-gazetteer.cpp +++ b/tests/test-output-gazetteer.cpp @@ -44,20 +44,24 @@ TEST_CASE("Import main tags as fallback") TEST_CASE("Main tag deleted") { import("n1 Tamenity=restaurant x12.3 y3\n" - "n2 Thighway=bus_stop,railway=stop,name=X x56.4 y-4\n"); + "n2 Thighway=bus_stop,railway=stop,name=X x56.4 y-4\n" + "n3 Tamenity=prison x3 y5\n"); auto conn = db.connect(); CHECK(1 == node_count(conn, 1, "amenity")); CHECK(1 == node_count(conn, 2, "highway")); CHECK(1 == node_count(conn, 2, "railway")); + CHECK(1 == node_count(conn, 3, "amenity")); - update("n1 Tnot_a=restaurant x12.3 y3\n" + update("n3 v2 dD\n" + "n1 Tnot_a=restaurant x12.3 y3\n" "n2 Thighway=bus_stop,name=X x56.4 y-4\n"); CHECK(0 == node_count(conn, 1, "amenity")); CHECK(2 == node_count(conn, 2, "highway")); CHECK(0 == node_count(conn, 2, "railway")); + CHECK(0 == node_count(conn, 3, "amenity")); } TEST_CASE("Main tag added") @@ -70,13 +74,16 @@ TEST_CASE("Main tag added") CHECK(0 == node_count(conn, 1, "amenity")); CHECK(1 == node_count(conn, 2, "highway")); CHECK(0 == node_count(conn, 2, "railway")); + CHECK(0 == node_count(conn, 3, "amenity")); update("n1 Tamenity=restaurant x12.3 y3\n" - "n2 Thighway=bus_stop,railway=stop,name=X x56.4 y-4\n"); + "n2 Thighway=bus_stop,railway=stop,name=X x56.4 y-4\n" + "n3 Tamenity=prison x3 y5\n"); CHECK(1 == node_count(conn, 1, "amenity")); CHECK(2 == node_count(conn, 2, "highway")); CHECK(1 == node_count(conn, 2, "railway")); + CHECK(1 == node_count(conn, 3, "amenity")); } TEST_CASE("Main tag modified")