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
23 changes: 20 additions & 3 deletions src/geom-from-osm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,24 @@ void create_multipoint(geometry_t *geom, osmium::memory::Buffer const &buffer)
geom->reset();
}
} else {
auto &multiline = geom->set<multipoint_t>();
auto &multipoint = geom->set<multipoint_t>();
for (auto const &node : nodes) {
auto const location = node.location();
if (location.valid()) {
multiline.add_geometry(point_t{location});
multipoint.add_geometry(point_t{location});
}
}
if (multiline.num_geometries() == 0) {
if (multipoint.num_geometries() == 0) {
geom->reset();
}

// In the (unlikely) event that this multipoint geometry only contains
// a single point because locations for all others were not available
// turn it into a point geometry retroactively.
if (multipoint.num_geometries() == 1) {
auto const p = multipoint[0];
geom->set<point_t>() = p;
}
}
}

Expand Down Expand Up @@ -154,6 +162,15 @@ void create_multilinestring(geometry_t *geom,
if (multiline.num_geometries() == 0) {
geom->reset();
}

// In the (unlikely) event that this multilinestring geometry only
// contains a single linestring because ways or locations for all
// others were not available turn it into a linestring geometry
// retroactively.
if (multiline.num_geometries() == 1 && !force_multi) {
auto p = std::move(multiline[0]);
geom->set<linestring_t>() = std::move(p);
}
}
}

Expand Down
33 changes: 33 additions & 0 deletions tests/test-geom-multilinestrings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,39 @@ TEST_CASE("create_multilinestring with single line and no force_multi",
REQUIRE(l == expected);
}

TEST_CASE(
"create_multilinestring with multiple incomplete lines and no force_multi",
"[NoDB]")
{
geom::linestring_t const expected{{1, 1}, {2, 1}};

test_buffer_t buffer;

SECTION("with second invalid line")
{
buffer.add_way("w20 Nn10x1y1,n11x2y1");
buffer.add_way("w21 Nn12x2y2");
}

SECTION("with second line with missing location")
{
buffer.add_way("w20 Nn10x1y1,n11x2y1");
buffer.add_way("w21 Nn12x2y2,n13");
}

auto const geom =
geom::line_merge(geom::create_multilinestring(buffer.buffer(), false));

REQUIRE(geom.is_linestring());
REQUIRE(geometry_type(geom) == "LINESTRING");
REQUIRE(num_geometries(geom) == 1);
REQUIRE(area(geom) == Approx(0.0));
REQUIRE(length(geom) == Approx(1.0));
auto const &l = geom.get<geom::linestring_t>();
REQUIRE(l.num_geometries() == 1);
REQUIRE(l == expected);
}

TEST_CASE("create_multilinestring with single line forming a ring", "[NoDB]")
{
geom::linestring_t const expected{{1, 1}, {2, 1}, {2, 2}, {1, 1}};
Expand Down
26 changes: 26 additions & 0 deletions tests/test-geom-multipoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,29 @@ TEST_CASE("create_multipoint from OSM data", "[NoDB]")
REQUIRE(length(geom) == Approx(0.0));
REQUIRE(centroid(geom) == geom::geometry_t{geom::point_t{2, 1}});
}

TEST_CASE("create_multipoint from OSM data with only a single point", "[NoDB]")
{
test_buffer_t buffer;

SECTION("only single node in relation")
{
buffer.add_node("n10 x1 y0");
}

SECTION("two nodes in relation, but one with missing location")
{
buffer.add_node("n10 x1 y0");
buffer.add_node("n11");
}

auto const geom = geom::create_multipoint(buffer.buffer());

REQUIRE(geometry_type(geom) == "POINT");
REQUIRE(dimension(geom) == 0);
REQUIRE(num_geometries(geom) == 1);
REQUIRE(geom.get<geom::point_t>() == geom::point_t{1, 0});
REQUIRE(area(geom) == Approx(0.0));
REQUIRE(length(geom) == Approx(0.0));
REQUIRE(centroid(geom) == geom::geometry_t{geom::point_t{1, 0}});
}