| 166 | } |
| 167 | |
| 168 | std::optional<m2::PointD> HierarchyEntryEnricher::GetFeatureCenter(CompositeId const & id) const |
| 169 | { |
| 170 | auto const optIds = m_osm2FtIds.GetFeatureIds(id); |
| 171 | if (optIds.empty()) |
| 172 | return {}; |
| 173 | |
| 174 | // A CompositeId id may correspond to several feature ids. These features can be represented by |
| 175 | // three types of geometry. Logically, their centers coincide, but in practice they don’t, |
| 176 | // because the centers are calculated differently. For example, for an object with a type area, |
| 177 | // the area will be computed using the triangles geometry, but for an object with a type line, |
| 178 | // the area will be computed using the outer geometry of a polygon. |
| 179 | ankerl::unordered_dense::map<std::underlying_type_t<feature::GeomType>, m2::PointD> m; |
| 180 | for (auto optId : optIds) |
| 181 | { |
| 182 | auto const ftPtr = m_featureGetter.GetFeatureByIndex(optId); |
| 183 | if (!ftPtr) |
| 184 | continue; |
| 185 | |
| 186 | CHECK(m.emplace(base::Underlying(ftPtr->GetGeomType()), feature::GetCenter(*ftPtr)).second, (id, optIds)); |
| 187 | } |
| 188 | |
| 189 | for (auto type : {base::Underlying(feature::GeomType::Point), base::Underlying(feature::GeomType::Area), |
| 190 | base::Underlying(feature::GeomType::Line)}) |
| 191 | { |
| 192 | if (m.count(type) != 0) |
| 193 | return m[type]; |
| 194 | } |
| 195 | |
| 196 | return {}; |
| 197 | } |
| 198 | |
| 199 | HierarchyLinesBuilder::HierarchyLinesBuilder(HierarchyLinker::Node::Ptrs && trees) : m_trees(std::move(trees)) {} |
| 200 |
no test coverage detected