diff --git a/indexer/altitude_loader.cpp b/indexer/altitude_loader.cpp index e56bcf3c86..c25fef6346 100644 --- a/indexer/altitude_loader.cpp +++ b/indexer/altitude_loader.cpp @@ -60,6 +60,11 @@ AltitudeLoader::AltitudeLoader(MwmValue const * mwmValue) } } +bool AltitudeLoader::IsAvailable() const +{ + return m_header.minAltitude != kInvalidAltitude && m_header.altitudeInfoOffset != 0; +} + TAltitudes AltitudeLoader::GetAltitude(uint32_t featureId, size_t pointCount) const { if (m_header.altitudeInfoOffset == 0) diff --git a/indexer/altitude_loader.hpp b/indexer/altitude_loader.hpp index adf01cff6b..cd2d1efbb4 100644 --- a/indexer/altitude_loader.hpp +++ b/indexer/altitude_loader.hpp @@ -15,6 +15,7 @@ public: explicit AltitudeLoader(MwmValue const * mwmValue); TAltitudes GetAltitude(uint32_t featureId, size_t pointCount) const; + bool IsAvailable() const; private: vector m_altitudeAvailabilitBuf; diff --git a/indexer/feature_altitude.hpp b/indexer/feature_altitude.hpp index b11c922ef5..52f1032f53 100644 --- a/indexer/feature_altitude.hpp +++ b/indexer/feature_altitude.hpp @@ -3,6 +3,7 @@ #include "base/logging.hpp" +#include "std/cstdint.hpp" #include "std/limits.hpp" #include "std/vector.hpp" @@ -64,51 +65,54 @@ class Altitude { public: Altitude() = default; - explicit Altitude(TAltitudes const & altitudes) : m_pointAlt(altitudes) {} + explicit Altitude(TAltitudes const & altitudes) : m_altitudes(altitudes) {} template void Serialize(TAltitude minAltitude, TSink & sink) const { - CHECK(!m_pointAlt.empty(), ()); + CHECK(!m_altitudes.empty(), ()); - TAltitude prevPntAltitude = minAltitude; - for (size_t i = 0; i < m_pointAlt.size(); ++i) - { - WriteVarInt(sink, static_cast(static_cast(m_pointAlt[i] - prevPntAltitude))); - prevPntAltitude = m_pointAlt[i]; - } + WriteVarInt(sink, static_cast(m_altitudes[0] - static_cast(minAltitude))); + for (size_t i = 1; i < m_altitudes.size(); ++i) + WriteVarInt(sink, static_cast(m_altitudes[i]) - static_cast(m_altitudes[i - 1])); } template void Deserialize(TAltitude minAltitude, size_t pointCount, TSource & src) { - m_pointAlt.clear(); + m_altitudes.clear(); if (pointCount == 0) { ASSERT(false, ()); return; } - m_pointAlt.resize(pointCount); + m_altitudes.resize(pointCount); TAltitude prevPntAltitude = minAltitude; for (size_t i = 0; i < pointCount; ++i) { - m_pointAlt[i] = static_cast(ReadVarInt(src) + prevPntAltitude); - prevPntAltitude = m_pointAlt[i]; + m_altitudes[i] = static_cast(ReadVarInt(src) + prevPntAltitude); + if (m_altitudes[i] < minAltitude) + { + ASSERT(false, ()); + m_altitudes.clear(); + return; + } + prevPntAltitude = m_altitudes[i]; } } TAltitudes GetAltitudes() const { - return m_pointAlt; + return m_altitudes; } private: - /// \note |m_pointAlt| is a vector of feature point altitudes. There's two posibilities: - /// * |m_pointAlt| is empty. It means no altitude information defines. - /// * size of |m_pointAlt| is equal to feature point number. In that case every item of - /// |m_pointAlt| defines altitude in meters for every feature point. If altitude is not defined + /// \note |m_altitudes| is a vector of feature point altitudes. There's two posibilities: + /// * |m_altitudes| is empty. It means no altitude information defines. + /// * size of |m_altitudes| is equal to feature point number. In that case every item of + /// |m_altitudes| defines altitude in meters for every feature point. If altitude is not defined /// for some feature point corresponding vector items are equel to |kInvalidAltitude| - TAltitudes m_pointAlt; + TAltitudes m_altitudes; }; } // namespace feature diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index 0c4ed59023..e425508393 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -258,12 +258,17 @@ void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType double speedKMPH, RoadInfo & ri) const { Value const & value = LockFeatureMwm(featureId); + if (!value.IsAlive()) + { + ASSERT(false, ()); + return; + } ri.m_bidirectional = !IsOneWay(ft); ri.m_speedKMPH = speedKMPH; ft.ParseGeometry(FeatureType::BEST_GEOMETRY); - feature::TAltitudes altitudes = value.altitudeLoader.GetAltitude(featureId.m_index, ft.GetPointsCount()); + feature::TAltitudes altitudes = value.altitudeLoader->GetAltitude(featureId.m_index, ft.GetPointsCount()); size_t const pointsCount = ft.GetPointsCount(); if (altitudes.size() != pointsCount) @@ -329,14 +334,6 @@ FeaturesRoadGraph::Value const & FeaturesRoadGraph::LockFeatureMwm(FeatureID con if (itr != m_mwmLocks.end()) return itr->second; - MwmSet::MwmHandle mwmHandle = m_index.GetMwmHandleById(mwmId); - ASSERT(mwmHandle.IsAlive(), ()); - - MwmValue * mwmValue = nullptr; - if (mwmHandle.IsAlive()) - mwmValue = mwmHandle.GetValue(); - - Value value(move(mwmHandle), mwmValue); - return m_mwmLocks.insert(make_pair(move(mwmId), move(value))).first->second; + return m_mwmLocks.insert(make_pair(move(mwmId), Value(m_index.GetMwmHandleById(mwmId)))).first->second; } } // namespace routing diff --git a/routing/features_road_graph.hpp b/routing/features_road_graph.hpp index 753955718a..819f01ace0 100644 --- a/routing/features_road_graph.hpp +++ b/routing/features_road_graph.hpp @@ -81,13 +81,25 @@ private: struct Value { - Value(MwmSet::MwmHandle && handle, MwmValue const * mwmValue) - : mwmHandle(move(handle)), altitudeLoader(mwmValue) + Value() = default; + Value(MwmSet::MwmHandle && handle) + : mwmHandle(move(handle)) { + if (!mwmHandle.IsAlive()) + { + ASSERT(false, ()); + return; + } + altitudeLoader = make_unique(mwmHandle.GetValue()); + } + + bool IsAlive() const + { + return mwmHandle.IsAlive() && altitudeLoader && altitudeLoader->IsAvailable(); } MwmSet::MwmHandle mwmHandle; - feature::AltitudeLoader altitudeLoader; + unique_ptr altitudeLoader; }; bool IsRoad(FeatureType const & ft) const; diff --git a/routing/routing_helpers.hpp b/routing/routing_helpers.hpp index ef6c9d5e40..49acc0417a 100644 --- a/routing/routing_helpers.hpp +++ b/routing/routing_helpers.hpp @@ -7,8 +7,8 @@ namespace routing { /// \returns true when there exists a routing mode where the feature with |types| can be used. -template -bool IsRoad(TList const & types) +template +bool IsRoad(TTypes const & types) { return CarModel::Instance().HasRoadType(types) || PedestrianModel::DefaultInstance().HasRoadType(types) || diff --git a/routing/routing_integration_tests/bicycle_turn_test.cpp b/routing/routing_integration_tests/bicycle_turn_test.cpp index 350a29b0e4..88fa24532d 100644 --- a/routing/routing_integration_tests/bicycle_turn_test.cpp +++ b/routing/routing_integration_tests/bicycle_turn_test.cpp @@ -59,9 +59,6 @@ UNIT_TEST(RussiaMoscowSevTushinoParkBicycleOnePointTurnTest) TRouteResult const routeResult = integration::CalculateRoute(integration::GetBicycleComponents(), point, {0.0, 0.0}, point); - Route const & route = *routeResult.first; - UNUSED_VALUE(route); - IRouter::ResultCode const result = routeResult.second; TEST_EQUAL(result, IRouter::IRouter::RouteNotFound, ()); }