| 90 | } |
| 91 | |
| 92 | void ForEachWayInRelation(pugi::xml_document const & osmResponse, pugi::xml_node const & relation, |
| 93 | ForEachWayFn const & fn) |
| 94 | { |
| 95 | auto const nodesSet = relation.select_nodes("member[@type='way']/@ref"); |
| 96 | for (auto const & xNodeRef : nodesSet) |
| 97 | { |
| 98 | std::string const wayRef = xNodeRef.attribute().value(); |
| 99 | auto const xpath = "osm/way[@id='" + wayRef + "']"; |
| 100 | auto const way = osmResponse.select_node(xpath.c_str()).node(); |
| 101 | |
| 102 | auto const rolePath = "member[@ref='" + wayRef + "']/@role"; |
| 103 | pugi::xpath_node roleNode = relation.select_node(rolePath.c_str()); |
| 104 | |
| 105 | // It is possible to have a wayRef that refers to a way not included in a given relation. |
| 106 | // We can skip such ways. |
| 107 | if (!way) |
| 108 | continue; |
| 109 | |
| 110 | // If more than one way is given and there is one with no role specified, |
| 111 | // it's an error. We skip this particular way but try to use others anyway. |
| 112 | if (!roleNode && nodesSet.size() != 1) |
| 113 | continue; |
| 114 | |
| 115 | std::string const role = roleNode ? roleNode.attribute().value() : "outer"; |
| 116 | fn(way, role); |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | template <typename Geometry> |
| 121 | void AppendWay(pugi::xml_document const & osmResponse, pugi::xml_node const & way, Geometry & dest) |
no test coverage detected