Skip to content

Commit 1cbbf2b

Browse files
committed
Add function for comparing two TagLists
1 parent ead7db5 commit 1cbbf2b

2 files changed

Lines changed: 145 additions & 0 deletions

File tree

include/osmium/tags/tags_filter.hpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,49 @@ namespace osmium {
154154

155155
using TagsFilter = TagsFilterBase<bool>;
156156

157+
/**
158+
* Compare two lists of tags ignoring tags matching the filter.
159+
* Tag lists must be ordered in a consistent way.
160+
* The filter must return "false" for all tags that should be ignored.
161+
*/
162+
[[nodiscard]] inline bool compare_tags(osmium::TagList const &tags1,
163+
osmium::TagList const &tags2,
164+
TagsFilter const &filter)
165+
{
166+
auto const end1 = tags1.cend();
167+
auto const end2 = tags2.cend();
168+
169+
auto it1 = tags1.cbegin();
170+
auto it2 = tags2.cbegin();
171+
172+
while (it1 != end1 && it2 != end2) {
173+
if (!filter(*it1)) {
174+
++it1;
175+
continue;
176+
}
177+
if (!filter(*it2)) {
178+
++it2;
179+
continue;
180+
}
181+
if (*it1 == *it2) {
182+
++it1;
183+
++it2;
184+
continue;
185+
}
186+
return false;
187+
}
188+
189+
while (it1 != end1 && !filter(*it1)) {
190+
++it1;
191+
}
192+
193+
while (it2 != end2 && !filter(*it2)) {
194+
++it2;
195+
}
196+
197+
return it1 == end1 && it2 == end2;
198+
}
199+
157200
} // namespace osmium
158201

159202

test/t/tags/test_tags_filter.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,105 @@ TEST_CASE("TagsFilterBase") {
178178

179179
}
180180

181+
TEST_CASE("compare_tags") {
182+
osmium::memory::Buffer buffer{10240};
183+
184+
const auto pos1 = osmium::builder::add_tag_list(buffer,
185+
osmium::builder::attr::_tags({
186+
{ "highway", "primary" },
187+
{ "name", "Main Street" },
188+
{ "source", "GPS" }
189+
}));
190+
const auto pos2 = osmium::builder::add_tag_list(buffer,
191+
osmium::builder::attr::_tags({
192+
{ "highway", "primary" },
193+
{ "name", "Main Street" },
194+
}));
195+
const auto pos3 = osmium::builder::add_tag_list(buffer,
196+
osmium::builder::attr::_tags({
197+
{ "attribution", "something" },
198+
{ "highway", "primary" },
199+
{ "name", "Main Street" },
200+
}));
201+
const auto pos4 = osmium::builder::add_tag_list(buffer,
202+
osmium::builder::attr::_tags({
203+
{ "highway", "primary" },
204+
{ "junk", "foo" },
205+
{ "name", "Main Street" },
206+
}));
207+
const auto pos5 = osmium::builder::add_tag_list(buffer,
208+
osmium::builder::attr::_tags({
209+
{ "amenity", "restaurant" },
210+
{ "name", "The Golden Goose" }
211+
}));
212+
213+
const osmium::TagList& tag_list1 = buffer.get<osmium::TagList>(pos1);
214+
const osmium::TagList& tag_list2 = buffer.get<osmium::TagList>(pos2);
215+
const osmium::TagList& tag_list3 = buffer.get<osmium::TagList>(pos3);
216+
const osmium::TagList& tag_list4 = buffer.get<osmium::TagList>(pos4);
217+
const osmium::TagList& tag_list5 = buffer.get<osmium::TagList>(pos5);
218+
219+
const osmium::TagsFilter filter_empty{true};
220+
221+
REQUIRE(compare_tags(tag_list1, tag_list1, filter_empty));
222+
REQUIRE(compare_tags(tag_list2, tag_list2, filter_empty));
223+
REQUIRE(compare_tags(tag_list3, tag_list3, filter_empty));
224+
REQUIRE(compare_tags(tag_list4, tag_list4, filter_empty));
225+
REQUIRE(compare_tags(tag_list5, tag_list5, filter_empty));
226+
227+
REQUIRE_FALSE(compare_tags(tag_list1, tag_list2, filter_empty));
228+
REQUIRE_FALSE(compare_tags(tag_list1, tag_list3, filter_empty));
229+
REQUIRE_FALSE(compare_tags(tag_list1, tag_list4, filter_empty));
230+
REQUIRE_FALSE(compare_tags(tag_list1, tag_list5, filter_empty));
231+
REQUIRE_FALSE(compare_tags(tag_list2, tag_list3, filter_empty));
232+
REQUIRE_FALSE(compare_tags(tag_list2, tag_list4, filter_empty));
233+
REQUIRE_FALSE(compare_tags(tag_list2, tag_list5, filter_empty));
234+
REQUIRE_FALSE(compare_tags(tag_list3, tag_list4, filter_empty));
235+
REQUIRE_FALSE(compare_tags(tag_list3, tag_list5, filter_empty));
236+
REQUIRE_FALSE(compare_tags(tag_list4, tag_list5, filter_empty));
237+
238+
REQUIRE_FALSE(compare_tags(tag_list2, tag_list1, filter_empty));
239+
REQUIRE_FALSE(compare_tags(tag_list3, tag_list1, filter_empty));
240+
REQUIRE_FALSE(compare_tags(tag_list4, tag_list1, filter_empty));
241+
REQUIRE_FALSE(compare_tags(tag_list5, tag_list1, filter_empty));
242+
REQUIRE_FALSE(compare_tags(tag_list3, tag_list2, filter_empty));
243+
REQUIRE_FALSE(compare_tags(tag_list4, tag_list2, filter_empty));
244+
REQUIRE_FALSE(compare_tags(tag_list5, tag_list2, filter_empty));
245+
REQUIRE_FALSE(compare_tags(tag_list4, tag_list3, filter_empty));
246+
REQUIRE_FALSE(compare_tags(tag_list5, tag_list3, filter_empty));
247+
REQUIRE_FALSE(compare_tags(tag_list5, tag_list4, filter_empty));
248+
249+
osmium::TagsFilter filter{true};
250+
filter.add_rule(false, "attribution");
251+
filter.add_rule(false, "source");
252+
filter.add_rule(false, "junk");
253+
254+
REQUIRE(compare_tags(tag_list1, tag_list1, filter));
255+
REQUIRE(compare_tags(tag_list2, tag_list2, filter));
256+
REQUIRE(compare_tags(tag_list3, tag_list3, filter));
257+
REQUIRE(compare_tags(tag_list4, tag_list4, filter));
258+
REQUIRE(compare_tags(tag_list5, tag_list5, filter));
259+
260+
REQUIRE(compare_tags(tag_list1, tag_list2, filter));
261+
REQUIRE(compare_tags(tag_list1, tag_list3, filter));
262+
REQUIRE(compare_tags(tag_list1, tag_list4, filter));
263+
REQUIRE_FALSE(compare_tags(tag_list1, tag_list5, filter));
264+
REQUIRE(compare_tags(tag_list2, tag_list3, filter));
265+
REQUIRE(compare_tags(tag_list2, tag_list4, filter));
266+
REQUIRE_FALSE(compare_tags(tag_list2, tag_list5, filter));
267+
REQUIRE(compare_tags(tag_list3, tag_list4, filter));
268+
REQUIRE_FALSE(compare_tags(tag_list3, tag_list5, filter));
269+
REQUIRE_FALSE(compare_tags(tag_list4, tag_list5, filter));
270+
271+
REQUIRE(compare_tags(tag_list2, tag_list1, filter));
272+
REQUIRE(compare_tags(tag_list3, tag_list1, filter));
273+
REQUIRE(compare_tags(tag_list4, tag_list1, filter));
274+
REQUIRE_FALSE(compare_tags(tag_list5, tag_list1, filter));
275+
REQUIRE(compare_tags(tag_list3, tag_list2, filter));
276+
REQUIRE(compare_tags(tag_list4, tag_list2, filter));
277+
REQUIRE_FALSE(compare_tags(tag_list5, tag_list2, filter));
278+
REQUIRE(compare_tags(tag_list4, tag_list3, filter));
279+
REQUIRE_FALSE(compare_tags(tag_list5, tag_list3, filter));
280+
REQUIRE_FALSE(compare_tags(tag_list5, tag_list4, filter));
281+
}
282+

0 commit comments

Comments
 (0)