Skip to content

Commit

Permalink
Order deleted objects after visible ones in reverse id order
Browse files Browse the repository at this point in the history
osmium::object_order_type_id_reverse_version is used to order OSM
objects for merging or applying diffs. If the diffs are from extracts,
it can happen that there are multiple objects with the same type, id,
version, and timestamp but different deleted flag. In that case the
merged diff should contain the visible object, not the deleted one,
because the deleted one isn't really deleted, just outside the area of
the extract.

To achieve this, osmium::object_order_type_id_reverse_version must order
visible objects before deleted ones if all else stays the same.

See osmcode/osmium-tool#282
  • Loading branch information
joto committed Dec 14, 2024
1 parent a57fe6c commit cff8ff4
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
6 changes: 4 additions & 2 deletions include/osmium/osm/object_comparisons.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,11 @@ namespace osmium {

bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const noexcept {
return const_tie(lhs.type(), lhs.id() > 0, lhs.positive_id(), rhs.version(),
((lhs.timestamp().valid() && rhs.timestamp().valid()) ? rhs.timestamp() : osmium::Timestamp())) <
((lhs.timestamp().valid() && rhs.timestamp().valid()) ? rhs.timestamp() : osmium::Timestamp()),
rhs.visible()) <
const_tie(rhs.type(), rhs.id() > 0, rhs.positive_id(), lhs.version(),
((lhs.timestamp().valid() && rhs.timestamp().valid()) ? lhs.timestamp() : osmium::Timestamp()));
((lhs.timestamp().valid() && rhs.timestamp().valid()) ? lhs.timestamp() : osmium::Timestamp()),
lhs.visible());
}

/// @pre lhs and rhs must not be nullptr
Expand Down
6 changes: 6 additions & 0 deletions test/t/osm/test_object_comparisons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ TEST_CASE("Node comparisons") {
REQUIRE(std::is_sorted(nodes.cbegin(), nodes.cend(), osmium::object_order_type_id_reverse_version{}));
}

SECTION("reverse version ordering should order objects with deleted flag last") {
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 1), _version(2), _timestamp("2016-01-01T00:00:00Z"), _deleted(false))));
nodes.emplace_back(buffer.get<osmium::Node>(osmium::builder::add_node(buffer, _id( 1), _version(2), _timestamp("2016-01-01T00:00:00Z"), _deleted(true))));

REQUIRE(std::is_sorted(nodes.cbegin(), nodes.cend(), osmium::object_order_type_id_reverse_version{}));
}
}

TEST_CASE("Object comparisons: types are ordered nodes, then ways, then relations") {
Expand Down

0 comments on commit cff8ff4

Please sign in to comment.