From ec73bce900be6b5379b49200781d2b1f7c4e4411 Mon Sep 17 00:00:00 2001 From: Vladimir Byko-Ianko Date: Wed, 29 Jun 2016 18:43:32 +0300 Subject: [PATCH] Implementing AltitudeLoader instead of using FeatureType for parsing. --- indexer/altitude_loader.cpp | 49 ++++++++++++++++++++++++++++++ indexer/altitude_loader.hpp | 25 +++++++++++++++ indexer/feature.cpp | 12 +------- indexer/feature.hpp | 8 ----- indexer/feature_altitude.hpp | 4 +-- indexer/feature_loader.cpp | 41 ------------------------- indexer/feature_loader.hpp | 1 - indexer/feature_loader_base.hpp | 1 - indexer/indexer.pro | 2 ++ indexer/old/feature_loader_101.hpp | 1 - routing/features_road_graph.cpp | 30 +++++++++++------- routing/features_road_graph.hpp | 11 +++++-- 12 files changed, 107 insertions(+), 78 deletions(-) create mode 100644 indexer/altitude_loader.cpp create mode 100644 indexer/altitude_loader.hpp diff --git a/indexer/altitude_loader.cpp b/indexer/altitude_loader.cpp new file mode 100644 index 0000000000..66fa124bf8 --- /dev/null +++ b/indexer/altitude_loader.cpp @@ -0,0 +1,49 @@ +#include "indexer/altitude_loader.hpp" + +#include "base/logging.hpp" +#include "base/stl_helpers.hpp" + +#include "defines.hpp" + +namespace feature +{ +AltitudeLoader::AltitudeLoader(MwmValue const * mwmValue) +{ + if (!mwmValue || mwmValue->GetHeader().GetFormat() < version::Format::v8 ) + return; + + try + { + m_idx = make_unique> + (mwmValue->m_cont.GetReader(ALTITUDE_FILE_TAG)); + } + catch (Reader::OpenException const &) + { + LOG(LINFO, ("MWM does not contain", ALTITUDE_FILE_TAG, "section.")); + } +} + +Altitudes AltitudeLoader::GetAltitudes(uint32_t featureId) const +{ + if (!m_idx || m_idx->size() == 0) + return Altitudes(); + + auto it = lower_bound(m_idx->begin(), m_idx->end(), + TAltitudeIndexEntry{static_cast(featureId), 0, 0}, + my::LessBy(&TAltitudeIndexEntry::featureId)); + + if (it == m_idx->end()) + return Altitudes(); + + if (featureId != it->featureId) + { + ASSERT(false, ()); + return Altitudes(); + } + + if (it->beginAlt == kInvalidAltitude || it->endAlt == kInvalidAltitude) + return Altitudes(); + + return Altitudes(it->beginAlt, it->endAlt); +} +} // namespace feature diff --git a/indexer/altitude_loader.hpp b/indexer/altitude_loader.hpp new file mode 100644 index 0000000000..d792b28467 --- /dev/null +++ b/indexer/altitude_loader.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "indexer/feature_altitude.hpp" +#include "indexer/index.hpp" + +#include "coding/dd_vector.hpp" + +namespace feature +{ +class AltitudeLoader +{ +public: + AltitudeLoader(MwmValue const * mwmValue); + Altitudes GetAltitudes(uint32_t featureId) const; + +private: + struct TAltitudeIndexEntry + { + uint32_t featureId; + feature::TAltitude beginAlt; + feature::TAltitude endAlt; + }; + + unique_ptr> m_idx; +}; +} // namespace feature diff --git a/indexer/feature.cpp b/indexer/feature.cpp index b9cd39253f..b05151515a 100644 --- a/indexer/feature.cpp +++ b/indexer/feature.cpp @@ -302,8 +302,7 @@ void FeatureType::Deserialize(feature::LoaderBase * pLoader, TBuffer buffer) m_pLoader->InitFeature(this); - m_header2Parsed = m_pointsParsed = m_trianglesParsed = m_metadataParsed = m_altitudeParsed = - false; + m_header2Parsed = m_pointsParsed = m_trianglesParsed = m_metadataParsed = false; m_innerStats.MakeZero(); } @@ -376,15 +375,6 @@ void FeatureType::ParseMetadata() const m_metadataParsed = true; } -void FeatureType::ParseAltitude() const -{ - if (m_altitudeParsed) - return; - - m_pLoader->ParseAltitude(); - m_altitudeParsed = true; -} - StringUtf8Multilang const & FeatureType::GetNames() const { return m_params.name; diff --git a/indexer/feature.hpp b/indexer/feature.hpp index 458528b3c1..fe5f30c206 100644 --- a/indexer/feature.hpp +++ b/indexer/feature.hpp @@ -202,7 +202,6 @@ public: uint32_t ParseTriangles(int scale) const; void ParseMetadata() const; - void ParseAltitude() const; //@} /// @name Geometry. @@ -245,12 +244,6 @@ public: return m_points[i]; } - inline feature::Altitudes const & GetAltitudes() const - { - ASSERT(m_altitudeParsed, ()); - return m_altitudes; - } - template void ForEachTriangle(TFunctor && f, int scale) const { @@ -377,7 +370,6 @@ private: mutable bool m_pointsParsed = false; mutable bool m_trianglesParsed = false; mutable bool m_metadataParsed = false; - mutable bool m_altitudeParsed = false; mutable inner_geom_stat_t m_innerStats; diff --git a/indexer/feature_altitude.hpp b/indexer/feature_altitude.hpp index d744499ab9..4d59135342 100644 --- a/indexer/feature_altitude.hpp +++ b/indexer/feature_altitude.hpp @@ -16,8 +16,8 @@ struct Altitudes Altitudes() = default; Altitudes(TAltitude b, TAltitude e) : begin(b), end(e) {} - TAltitude begin = 0; - TAltitude end = 0; + TAltitude begin = kInvalidAltitude; + TAltitude end = kInvalidAltitude; }; class Altitude diff --git a/indexer/feature_loader.cpp b/indexer/feature_loader.cpp index 4c6609272e..37093182e8 100644 --- a/indexer/feature_loader.cpp +++ b/indexer/feature_loader.cpp @@ -292,47 +292,6 @@ void LoaderCurrent::ParseMetadata() } } -void LoaderCurrent::ParseAltitude() -{ - // @TODO Index and should be used here before merging to master. - - if (m_Info.GetMWMFormat() < version::Format::v8) - return; - - struct TAltitudeIndexEntry - { - uint32_t featureId; - feature::TAltitude beginAlt; - feature::TAltitude endAlt; - }; - - try - { - DDVector idx(m_Info.GetAltitudeReader()); - auto it = lower_bound(idx.begin(), idx.end(), - TAltitudeIndexEntry{static_cast(m_pF->m_id.m_index), 0, 0}, - [](TAltitudeIndexEntry const & v1, TAltitudeIndexEntry const & v2) - { - return v1.featureId < v2.featureId; - }); - if (it == idx.end()) - return; - - if (m_pF->m_id.m_index != it->featureId) - return; - - if (it->beginAlt == kInvalidAltitude || it->endAlt == kInvalidAltitude) - return; - - m_pF->m_altitudes.begin = it->beginAlt; - m_pF->m_altitudes.end = it->endAlt; - } - catch (Reader::OpenException const &) - { - // Now ignore exception because not all mwm have needed sections. - } -} - int LoaderCurrent::GetScaleIndex(int scale) const { int const count = m_Info.GetScalesCount(); diff --git a/indexer/feature_loader.hpp b/indexer/feature_loader.hpp index 513ca984c3..7788d05446 100644 --- a/indexer/feature_loader.hpp +++ b/indexer/feature_loader.hpp @@ -29,6 +29,5 @@ namespace feature uint32_t ParseGeometry(int scale) override; uint32_t ParseTriangles(int scale) override; void ParseMetadata() override; - void ParseAltitude() override; }; } diff --git a/indexer/feature_loader_base.hpp b/indexer/feature_loader_base.hpp index 2a2b2ff617..78a5179281 100644 --- a/indexer/feature_loader_base.hpp +++ b/indexer/feature_loader_base.hpp @@ -79,7 +79,6 @@ namespace feature virtual uint32_t ParseGeometry(int scale) = 0; virtual uint32_t ParseTriangles(int scale) = 0; virtual void ParseMetadata() = 0; - virtual void ParseAltitude() = 0; inline uint32_t GetTypesSize() const { return m_CommonOffset - m_TypesOffset; } diff --git a/indexer/indexer.pro b/indexer/indexer.pro index 6602f18ddf..f5b6d8e255 100644 --- a/indexer/indexer.pro +++ b/indexer/indexer.pro @@ -10,6 +10,7 @@ ROOT_DIR = .. include($$ROOT_DIR/common.pri) SOURCES += \ + altitude_loader.cpp \ categories_holder.cpp \ categories_holder_loader.cpp \ categories_index.cpp \ @@ -61,6 +62,7 @@ SOURCES += \ types_mapping.cpp \ HEADERS += \ + altitude_loader.hpp \ categories_holder.hpp \ categories_index.hpp \ cell_coverer.hpp \ diff --git a/indexer/old/feature_loader_101.hpp b/indexer/old/feature_loader_101.hpp index 83f74b8853..00f857d2ce 100644 --- a/indexer/old/feature_loader_101.hpp +++ b/indexer/old/feature_loader_101.hpp @@ -37,7 +37,6 @@ namespace old_101 { namespace feature uint32_t ParseGeometry(int scale) override; uint32_t ParseTriangles(int scale) override; void ParseMetadata() override {} /// not supported in this version - void ParseAltitude() override {} /// not supported in this version }; } } diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index 90546fd332..7458a9142d 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -257,18 +257,23 @@ double FeaturesRoadGraph::GetSpeedKMPHFromFt(FeatureType const & ft) const void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType const & ft, double speedKMPH, RoadInfo & ri) const { + Value const & value = LockFeatureMwm(featureId); + ri.m_bidirectional = !IsOneWay(ft); ri.m_speedKMPH = speedKMPH; ft.ParseGeometry(FeatureType::BEST_GEOMETRY); - ft.ParseAltitude(); + feature::Altitudes altitudes = value.altitudeLoader.GetAltitudes(featureId.m_index); + LOG(LINFO, ("Feature idx =", featureId.m_index, "altitudes.begin =", altitudes.begin, + "altitudes.end =", altitudes.end)); + // @TODO It's a temprarery solution until a vector of feature altitudes is saved in mwm. - bool const isAltidudeValid = ft.GetAltitudes().begin != feature::kInvalidAltitude && - ft.GetAltitudes().end != feature::kInvalidAltitude; - feature::TAltitude pointAlt = ft.GetAltitudes().begin; + bool const isAltidudeValid = altitudes.begin != feature::kInvalidAltitude && + altitudes.end != feature::kInvalidAltitude; + feature::TAltitude pointAlt = altitudes.begin; size_t const pointsCount = ft.GetPointsCount(); feature::TAltitude const diffAlt = - isAltidudeValid ? (ft.GetAltitudes().end - ft.GetAltitudes().begin) / pointsCount : 0; + isAltidudeValid ? (altitudes.end - altitudes.begin) / pointsCount : 0; ri.m_junctions.clear(); ri.m_junctions.resize(pointsCount); @@ -283,8 +288,6 @@ void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType ri.m_junctions[i] = Junction(ft.GetPoint(i), pointAlt); pointAlt += diffAlt; } - - LockFeatureMwm(featureId); } IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID const & featureId) const @@ -324,19 +327,24 @@ IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID cons return ri; } -void FeaturesRoadGraph::LockFeatureMwm(FeatureID const & featureId) const +FeaturesRoadGraph::Value const & FeaturesRoadGraph::LockFeatureMwm(FeatureID const & featureId) const { MwmSet::MwmId mwmId = featureId.m_mwmId; ASSERT(mwmId.IsAlive(), ()); auto const itr = m_mwmLocks.find(mwmId); if (itr != m_mwmLocks.end()) - return; + return itr->second; MwmSet::MwmHandle mwmHandle = m_index.GetMwmHandleById(mwmId); ASSERT(mwmHandle.IsAlive(), ()); - m_mwmLocks.insert(make_pair(move(mwmId), move(mwmHandle))); -} + MwmValue * mwmValue = nullptr; + if (mwmHandle.IsAlive()) + mwmValue = mwmHandle.GetValue(); + Value value = {move(mwmHandle), feature::AltitudeLoader(mwmValue)}; + + return m_mwmLocks.insert(make_pair(move(mwmId), move(value))).first->second; +} } // namespace routing diff --git a/routing/features_road_graph.hpp b/routing/features_road_graph.hpp index 1ca7957ecc..1503023f40 100644 --- a/routing/features_road_graph.hpp +++ b/routing/features_road_graph.hpp @@ -2,6 +2,7 @@ #include "routing/road_graph.hpp" #include "routing/vehicle_model.hpp" +#include "indexer/altitude_loader.hpp" #include "indexer/feature_data.hpp" #include "indexer/mwm_set.hpp" @@ -78,6 +79,12 @@ public: private: friend class CrossFeaturesLoader; + struct Value + { + MwmSet::MwmHandle mwmHandle; + feature::AltitudeLoader altitudeLoader; + }; + bool IsRoad(FeatureType const & ft) const; bool IsOneWay(FeatureType const & ft) const; double GetSpeedKMPHFromFt(FeatureType const & ft) const; @@ -92,13 +99,13 @@ private: void ExtractRoadInfo(FeatureID const & featureId, FeatureType const & ft, double speedKMPH, RoadInfo & ri) const; - void LockFeatureMwm(FeatureID const & featureId) const; + Value const & LockFeatureMwm(FeatureID const & featureId) const; Index const & m_index; IRoadGraph::Mode const m_mode; mutable RoadInfoCache m_cache; mutable CrossCountryVehicleModel m_vehicleModel; - mutable map m_mwmLocks; + mutable map m_mwmLocks; }; } // namespace routing