| 58 | } |
| 59 | |
| 60 | geometry::Altitudes AltitudeLoaderBase::GetAltitudes(uint32_t featureId, size_t pointCount) |
| 61 | { |
| 62 | if (!HasAltitudes()) |
| 63 | { |
| 64 | // There's no altitude section in mwm. |
| 65 | return geometry::Altitudes(pointCount, geometry::kDefaultAltitudeMeters); |
| 66 | } |
| 67 | |
| 68 | if (!m_altitudeAvailability[featureId]) |
| 69 | return geometry::Altitudes(pointCount, m_header.m_minAltitude); |
| 70 | |
| 71 | uint64_t const r = m_altitudeAvailability.rank(featureId); |
| 72 | CHECK_LESS(r, m_altitudeAvailability.size(), ("Feature Id", featureId, "of", m_countryFileName)); |
| 73 | uint64_t const offset = m_featureTable.select(r); |
| 74 | CHECK_LESS_OR_EQUAL(offset, m_featureTable.size(), ("Feature Id", featureId, "of", m_countryFileName)); |
| 75 | |
| 76 | uint64_t const altitudeInfoOffsetInSection = m_header.m_altitudesOffset + offset; |
| 77 | CHECK_LESS(altitudeInfoOffsetInSection, m_reader->Size(), ("Feature Id", featureId, "of", m_countryFileName)); |
| 78 | |
| 79 | try |
| 80 | { |
| 81 | Altitudes altitudes; |
| 82 | ReaderSource<FilesContainerR::TReader> src(*m_reader); |
| 83 | src.Skip(altitudeInfoOffsetInSection); |
| 84 | altitudes.Deserialize(m_header.m_minAltitude, pointCount, m_countryFileName, featureId, src); |
| 85 | |
| 86 | // It's filtered on generator stage. |
| 87 | ASSERT(none_of(altitudes.m_altitudes.begin(), altitudes.m_altitudes.end(), |
| 88 | [](geometry::Altitude a) { return a == geometry::kInvalidAltitude; }), |
| 89 | (featureId, m_countryFileName)); |
| 90 | |
| 91 | return std::move(altitudes.m_altitudes); |
| 92 | } |
| 93 | catch (Reader::OpenException const & e) |
| 94 | { |
| 95 | LOG(LERROR, ("Feature Id", featureId, "of", m_countryFileName, ". Error while getting altitude data:", e.Msg())); |
| 96 | return geometry::Altitudes(pointCount, m_header.m_minAltitude); |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | geometry::Altitudes const & AltitudeLoaderCached::GetAltitudes(uint32_t featureId, size_t pointCount) |
| 101 | { |