/*** * Check all waterpolygons in pass 4: Iterate over error map and search * the node in the polygon tree by bounding box. * If found do geos contains with the polygon to make sure, the node is * containing in the polygon. * If the poylgon contains the error node the error is detected as a false * possitive and is either a normal node or a river mouth. */ void check_area() { for (auto node : ds.error_map) { osmium::Location location; osmium::object_id_type node_id = node.first; const geos::geom::Point *point = nullptr; try { location = location_handler.get_node_location(node_id); point = geos_factory.create_point(location).release(); } catch (...) { cerr << "Error at node: " << node_id << " - not able to create point of location." << endl; continue; } vector<void *> results; ds.polygon_tree.query(point->getEnvelopeInternal(), results); if (results.size()) { for (auto result : results) { prepared_polygon_type *geos_polygon; geos_polygon = static_cast<prepared_polygon_type*> (result); if (geos_polygon->contains(point)) { ErrorSum *sum = node.second; delete_error_node(node_id, sum); break; } } } delete point; } }
/*** * Iterate through members. Create linestrings of each. First as GEOS * linestring to union them later. Then as ORG linestring to insert * them into table ways. */ void create_ways(const osmium::Relation &relation, const osmium::object_id_type relation_id, bool &contains_nowaterway_ways, vector<geos::geom::Geometry *> *linestrings) { for (auto& member : relation.members()) { if (member_is_valid(member)) { const osmium::Way& way = way_from(member); linestring_type *linestr = nullptr; try { linestr = osmium_geos_factory.create_linestring(way, osmium::geom::use_nodes::unique, osmium::geom::direction::forward).release(); } catch (osmium::geometry_error) { insert_way_error(way); continue; } catch (...) { cerr << "Error at way: " << way.id() << endl; cerr << " Unexpected error" << endl; continue; } if (linestr) { linestrings->push_back(linestr); } else { continue; } if (TagCheck::has_waterway_tag(way)) { contains_nowaterway_ways = true; } OGRGeometry *ogr_linestring = nullptr; ogr_linestring = geos2ogr(linestr); try { ds.insert_way_feature(ogr_linestring, way, relation_id); } catch (osmium::geometry_error&) { cerr << "Inserting to table failed for way: " << way.id() << endl; } catch (...) { cerr << "Inserting to table failed for way: " << way.id() << endl;; cerr << " Unexpected error" << endl; } OGRGeometryFactory::destroyGeometry(ogr_linestring); } } }
#include "catch.hpp" #include <osmium/builder/builder_helper.hpp> #include <osmium/geom/geos.hpp> #include <osmium/geom/wkb.hpp> #include "../basic/helper.hpp" #include "helper.hpp" TEST_CASE("WKB_Geometry_with_GEOS") { SECTION("point") { osmium::geom::WKBFactory<> wkb_factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex); osmium::geom::GEOSFactory<> geos_factory; std::string wkb {wkb_factory.create_point(osmium::Location(3.2, 4.2))}; std::unique_ptr<geos::geom::Point> geos_point = geos_factory.create_point(osmium::Location(3.2, 4.2)); REQUIRE(geos_to_wkb(geos_point.get()) == wkb); } SECTION("linestring") { osmium::geom::WKBFactory<> wkb_factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex); osmium::geom::GEOSFactory<> geos_factory; osmium::memory::Buffer buffer(10000); auto& wnl = osmium::builder::build_way_node_list(buffer, { {1, {3.2, 4.2}}, {3, {3.5, 4.7}}, {4, {3.5, 4.7}},