#include "pugixml.hpp" #include #include // Returns true and increments count if `tag_node`'s first two attributes // are (value) "highway" then "crossing", matching the original's // position-based (not name-based) attribute check. inline bool is_highway_crossing(pugi::xml_node tag_node) { pugi::xml_attribute k = tag_node.first_attribute(); if (!k) return false; pugi::xml_attribute v = k.next_attribute(); if (!v) return false; return std::strcmp(k.value(), "highway") == 0 && std::strcmp(v.value(), "crossing") == 0; } size_t count_highway_crossings (char* buffer, size_t len) { pugi::xml_document doc; pugi::xml_parse_result result = doc.load_buffer_inplace(buffer, len, pugi::parse_minimal); if (!result) return 0; //if (!result) { // fprintf(stderr, "pugixml error: %s at offset %td\n", result.description(), result.offset); //} size_t count = 0; for (pugi::xml_node node : doc.child("osm").children("node")) { for (pugi::xml_node tag : node.children("tag")) { if (is_highway_crossing(tag)) ++count; } } return count; } size_t count_highway_crossings_cheat_and_early_out (char* buffer, size_t len) { pugi::xml_document doc; pugi::xml_parse_result result = doc.load_buffer_inplace(buffer, len, pugi::parse_minimal); if (!result) return 0; size_t count = 0; for (pugi::xml_node top : doc.child("osm").children()) { if (std::strcmp(top.name(), "way") == 0) break; for (pugi::xml_node tag : top.children("tag")) { if (is_highway_crossing(tag)) ++count; } } return count; }