diff --git a/generator/generator_tests/restriction_test.cpp b/generator/generator_tests/restriction_test.cpp index c4e7b7957a..efed713a51 100644 --- a/generator/generator_tests/restriction_test.cpp +++ b/generator/generator_tests/restriction_test.cpp @@ -9,9 +9,7 @@ #include "routing/restriction_loader.hpp" -#include "indexer/index.hpp" -#include "indexer/mwm_set.hpp" - +#include "coding/file_container.hpp" #include "coding/file_name_utils.hpp" #include "platform/platform_tests_support/scoped_dir.hpp" @@ -44,14 +42,15 @@ void BuildEmptyMwm(LocalCountryFile & country) generator::tests_support::TestMwmBuilder builder(country, feature::DataHeader::country); } -void LoadRestrictions(MwmValue const & mwmValue, RestrictionVec & restrictions) +void LoadRestrictions(string const & mwmFilePath, RestrictionVec & restrictions) { - if (!mwmValue.m_cont.IsExist(RESTRICTIONS_FILE_TAG)) + FilesContainerR const cont(mwmFilePath); + if (!cont.IsExist(RESTRICTIONS_FILE_TAG)) return; try { - FilesContainerR::TReader const reader = mwmValue.m_cont.GetReader(RESTRICTIONS_FILE_TAG); + FilesContainerR::TReader const reader = cont.GetReader(RESTRICTIONS_FILE_TAG); ReaderSource src(reader); RestrictionHeader header; header.Deserialize(src); @@ -76,37 +75,31 @@ void TestRestrictionBuilding(string const & restrictionContent, string const & m string const writableDir = platform.WritableDir(); // Building empty mwm. - LocalCountryFile country(my::JoinFoldersToPath(writableDir, kTestDir), CountryFile(kTestMwm), 1); + LocalCountryFile country(my::JoinPath(writableDir, kTestDir), CountryFile(kTestMwm), + 0 /* version */); ScopedDir const scopedDir(kTestDir); - string const mwmRelativePath = my::JoinFoldersToPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION); + string const mwmRelativePath = my::JoinPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION); ScopedFile const scopedMwm(mwmRelativePath); BuildEmptyMwm(country); // Creating a file with restrictions. - string const restrictionRelativePath = my::JoinFoldersToPath(kTestDir, kRestrictionFileName); + string const restrictionRelativePath = my::JoinPath(kTestDir, kRestrictionFileName); ScopedFile const restrictionScopedFile(restrictionRelativePath, restrictionContent); // Creating osm ids to feature ids mapping. - string const mappingRelativePath = my::JoinFoldersToPath(kTestDir, kOsmIdsToFeatureIdsName); + string const mappingRelativePath = my::JoinPath(kTestDir, kOsmIdsToFeatureIdsName); ScopedFile const mappingScopedFile(mappingRelativePath); - string const mappingFullPath = my::JoinFoldersToPath(writableDir, mappingRelativePath); + string const mappingFullPath = my::JoinPath(writableDir, mappingRelativePath); ReEncodeOsmIdsToFeatureIdsMapping(mappingContent, mappingFullPath); // Adding restriction section to mwm. - string const restrictionFullPath = my::JoinFoldersToPath(writableDir, restrictionRelativePath); - string const mwmFullPath = my::JoinFoldersToPath(writableDir, mwmRelativePath); + string const restrictionFullPath = my::JoinPath(writableDir, restrictionRelativePath); + string const mwmFullPath = my::JoinPath(writableDir, mwmRelativePath); BuildRoadRestrictions(mwmFullPath, restrictionFullPath, mappingFullPath); // Reading from mwm section and testing restrictions. - Index index; - auto const regResult = index.RegisterMap(country); - TEST_EQUAL(regResult.second, MwmSet::RegResult::Success, ()); - - MwmSet::MwmHandle mwmHandle = index.GetMwmHandleById(regResult.first); - TEST(mwmHandle.IsAlive(), ()); - RestrictionVec restrictionsFromMwm; - LoadRestrictions(*mwmHandle.GetValue(), restrictionsFromMwm); + LoadRestrictions(mwmFullPath, restrictionsFromMwm); RestrictionCollector const restrictionCollector(restrictionFullPath, mappingFullPath); TEST_EQUAL(restrictionsFromMwm, restrictionCollector.GetRestrictions(), ()); diff --git a/generator/generator_tests/road_access_test.cpp b/generator/generator_tests/road_access_test.cpp index 652f30e8cf..f09a2765f9 100644 --- a/generator/generator_tests/road_access_test.cpp +++ b/generator/generator_tests/road_access_test.cpp @@ -8,9 +8,7 @@ #include "routing/road_access_serialization.hpp" -#include "indexer/index.hpp" -#include "indexer/mwm_set.hpp" - +#include "coding/file_container.hpp" #include "coding/file_name_utils.hpp" #include "platform/platform_tests_support/scoped_dir.hpp" @@ -21,13 +19,14 @@ #include "base/logging.hpp" -#include "std/string.hpp" +#include using namespace feature; using namespace generator; using namespace platform::tests_support; using namespace platform; using namespace routing; +using std::string; namespace { @@ -41,13 +40,14 @@ void BuildEmptyMwm(LocalCountryFile & country) generator::tests_support::TestMwmBuilder builder(country, feature::DataHeader::country); } -void LoadRoadAccess(MwmValue const & mwmValue, RoadAccess & roadAccess) +void LoadRoadAccess(string const & mwmFilePath, RoadAccess & roadAccess) { - TEST(mwmValue.m_cont.IsExist(ROAD_ACCESS_FILE_TAG), ()); + FilesContainerR const cont(mwmFilePath); + TEST(cont.IsExist(ROAD_ACCESS_FILE_TAG), ()); try { - FilesContainerR::TReader const reader = mwmValue.m_cont.GetReader(ROAD_ACCESS_FILE_TAG); + FilesContainerR::TReader const reader = cont.GetReader(ROAD_ACCESS_FILE_TAG); ReaderSource src(reader); RoadAccessSerializer::Deserialize(src, roadAccess); @@ -65,37 +65,31 @@ void TestRoadAccess(string const & roadAccessContent, string const & mappingCont string const writableDir = platform.WritableDir(); // Building empty mwm. - LocalCountryFile country(my::JoinFoldersToPath(writableDir, kTestDir), CountryFile(kTestMwm), 1); + LocalCountryFile country(my::JoinPath(writableDir, kTestDir), CountryFile(kTestMwm), + 0 /* version */); ScopedDir const scopedDir(kTestDir); - string const mwmRelativePath = my::JoinFoldersToPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION); + string const mwmRelativePath = my::JoinPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION); ScopedFile const scopedMwm(mwmRelativePath); BuildEmptyMwm(country); // Creating a file with road access. - string const roadAccessRelativePath = my::JoinFoldersToPath(kTestDir, kRoadAccessFilename); + string const roadAccessRelativePath = my::JoinPath(kTestDir, kRoadAccessFilename); ScopedFile const roadAccessFile(roadAccessRelativePath, roadAccessContent); // Creating osm ids to feature ids mapping. - string const mappingRelativePath = my::JoinFoldersToPath(kTestDir, kOsmIdsToFeatureIdsName); + string const mappingRelativePath = my::JoinPath(kTestDir, kOsmIdsToFeatureIdsName); ScopedFile const mappingScopedFile(mappingRelativePath); - string const mappingFullPath = my::JoinFoldersToPath(writableDir, mappingRelativePath); + string const mappingFullPath = my::JoinPath(writableDir, mappingRelativePath); ReEncodeOsmIdsToFeatureIdsMapping(mappingContent, mappingFullPath); // Adding road access section to mwm. - string const roadAccessFullPath = my::JoinFoldersToPath(writableDir, roadAccessRelativePath); - string const mwmFullPath = my::JoinFoldersToPath(writableDir, mwmRelativePath); + string const roadAccessFullPath = my::JoinPath(writableDir, roadAccessRelativePath); + string const mwmFullPath = my::JoinPath(writableDir, mwmRelativePath); BuildRoadAccessInfo(mwmFullPath, roadAccessFullPath, mappingFullPath); // Reading from mwm section and testing road access. - Index index; - auto const regResult = index.RegisterMap(country); - TEST_EQUAL(regResult.second, MwmSet::RegResult::Success, ()); - - MwmSet::MwmHandle mwmHandle = index.GetMwmHandleById(regResult.first); - TEST(mwmHandle.IsAlive(), ()); - RoadAccess roadAccessFromMwm; - LoadRoadAccess(*mwmHandle.GetValue(), roadAccessFromMwm); + LoadRoadAccess(mwmFullPath, roadAccessFromMwm); RoadAccessCollector const collector(roadAccessFullPath, mappingFullPath); TEST(collector.IsValid(), ()); TEST(roadAccessFromMwm == collector.GetRoadAccess(), ()); diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp index d5cc30cd09..fb96013b0b 100644 --- a/generator/generator_tool/generator_tool.cpp +++ b/generator/generator_tool/generator_tool.cpp @@ -252,8 +252,10 @@ int main(int argc, char ** argv) if (FLAGS_make_routing_index) { string const osmToFeatureFilename = genInfo.GetTargetFileName(country) + OSM2FEATURE_FILE_EXTENSION; - string const restrictionsFilename = genInfo.GetIntermediateFileName(RESTRICTIONS_FILENAME, ""); - string const roadAccessFilename = genInfo.GetIntermediateFileName(ROAD_ACCESS_FILENAME, ""); + string const restrictionsFilename = + genInfo.GetIntermediateFileName(RESTRICTIONS_FILENAME, "" /* extension */); + string const roadAccessFilename = + genInfo.GetIntermediateFileName(ROAD_ACCESS_FILENAME, "" /* extension */); routing::BuildRoadRestrictions(datFile, restrictionsFilename, osmToFeatureFilename); routing::BuildRoadAccessInfo(datFile, roadAccessFilename, osmToFeatureFilename); diff --git a/generator/osm_translator.hpp b/generator/osm_translator.hpp index 4e1c559285..737a0d87ce 100644 --- a/generator/osm_translator.hpp +++ b/generator/osm_translator.hpp @@ -13,6 +13,7 @@ #include "coding/file_writer.hpp" +#include "base/assert.hpp" #include "base/cache.hpp" #include "base/logging.hpp" #include "base/stl_add.hpp" @@ -291,7 +292,7 @@ class OsmToFeatureTranslator if (!params.IsValid()) return false; - m_routingTagsProcessor.m_roadAccessWriter.Process(p, params); + m_routingTagsProcessor.m_roadAccessWriter.Process(*p, params); return true; } @@ -368,6 +369,8 @@ public: { enum class FeatureState {Unknown, Ok, EmptyTags, HasNoTypes, BrokenRef, ShortGeom, InvalidType}; + CHECK(p, ("Tried to emit a null OsmElement")); + FeatureParams params; FeatureState state = FeatureState::Unknown; diff --git a/generator/restriction_generator.hpp b/generator/restriction_generator.hpp index 12c3286ccb..abb107ab5c 100644 --- a/generator/restriction_generator.hpp +++ b/generator/restriction_generator.hpp @@ -12,7 +12,7 @@ namespace routing // are known. // This results in the following pipeline: // -- OsmToFeatureTranslator uses RestrictionsWriter to prepare a .csv file -// with resctrictions in terms of OSM ids while parsing the OSM source. +// with restrictions in terms of OSM ids while parsing the OSM source. // -- OsmID2FeatureID saves the OSM id -> feature id mapping. // -- After all features have been created, RestrictionCollector reads the csv // and builds the mwm section with restrictions. The serialization/deserialization diff --git a/generator/restriction_writer.cpp b/generator/restriction_writer.cpp index 596754fa69..52d405f513 100644 --- a/generator/restriction_writer.cpp +++ b/generator/restriction_writer.cpp @@ -98,5 +98,5 @@ void RestrictionWriter::Write(RelationElement const & relationElement) m_stream << ToString(type) << "," << fromIt->first << ", " << toIt->first << '\n'; } -bool RestrictionWriter::IsOpened() { return m_stream.is_open() && !m_stream.fail(); } +bool RestrictionWriter::IsOpened() const { return m_stream.is_open() && !m_stream.fail(); } } // namespace routing diff --git a/generator/restriction_writer.hpp b/generator/restriction_writer.hpp index 6aabb16143..e2cbce31ab 100644 --- a/generator/restriction_writer.hpp +++ b/generator/restriction_writer.hpp @@ -20,7 +20,7 @@ public: void Write(RelationElement const & relationElement); private: - bool IsOpened(); + bool IsOpened() const; ofstream m_stream; }; diff --git a/generator/road_access_generator.cpp b/generator/road_access_generator.cpp index 0dbac01f72..48b6e66de1 100644 --- a/generator/road_access_generator.cpp +++ b/generator/road_access_generator.cpp @@ -13,7 +13,6 @@ #include "coding/file_writer.hpp" #include "base/logging.hpp" -#include "base/scope_guard.hpp" #include "base/string_utils.hpp" #include "std/initializer_list.hpp" @@ -32,12 +31,60 @@ namespace char const kAccessPrivate[] = "access=private"; char const kBarrierGate[] = "barrier=gate"; char const kDelim[] = " \t\r\n"; + +bool ParseRoadAccess(string const & roadAccessPath, + map const & osmIdToFeatureId, + routing::RoadAccess & roadAccess) +{ + ifstream stream(roadAccessPath); + if (!stream) + { + LOG(LWARNING, ("Could not open", roadAccessPath)); + return false; + } + + string line; + for (uint32_t lineNo = 0;; ++lineNo) + { + if (!getline(stream, line)) + break; + + strings::SimpleTokenizer iter(line, kDelim); + + if (!iter) + { + LOG(LWARNING, ("Error when parsing road access: empty line", lineNo)); + return false; + } + + string const s = *iter; + ++iter; + + uint64_t osmId; + if (!iter || !strings::to_uint64(*iter, osmId)) + { + LOG(LWARNING, ("Error when parsing road access: bad osm id at line", lineNo)); + return false; + } + + auto const it = osmIdToFeatureId.find(osmId); + if (it == osmIdToFeatureId.cend()) + { + LOG(LWARNING, ("Error when parsing road access: unknown osm id at line", lineNo)); + return false; + } + + uint32_t const featureId = it->second; + roadAccess.GetPrivateRoads().emplace_back(featureId); + } + + return true; +} } // namespace namespace routing { // RoadAccessWriter ------------------------------------------------------------ - void RoadAccessWriter::Open(string const & filePath) { LOG(LINFO, @@ -48,7 +95,7 @@ void RoadAccessWriter::Open(string const & filePath) LOG(LINFO, ("Cannot open file", filePath)); } -void RoadAccessWriter::Process(OsmElement * p, FeatureParams & params) +void RoadAccessWriter::Process(OsmElement const & elem, FeatureParams const & params) { if (!IsOpened()) { @@ -65,29 +112,22 @@ void RoadAccessWriter::Process(OsmElement * p, FeatureParams & params) for (auto const & f : forbiddenRoadTypes) { auto const t = c.GetTypeByPath(f); - if (params.IsTypeExist(t) && p->type == OsmElement::EntityType::Way) - m_stream << kAccessPrivate << " " << p->id << "\n"; + if (params.IsTypeExist(t) && elem.type == OsmElement::EntityType::Way) + m_stream << kAccessPrivate << " " << elem.id << "\n"; } auto t = c.GetTypeByPath({"barrier", "gate"}); if (params.IsTypeExist(t)) - m_stream << kBarrierGate << " " << p->id << "\n"; + m_stream << kBarrierGate << " " << elem.id << "\n"; } -bool RoadAccessWriter::IsOpened() { return m_stream.is_open() && !m_stream.fail(); } +bool RoadAccessWriter::IsOpened() const { return m_stream.is_open() && !m_stream.fail(); } // RoadAccessCollector ---------------------------------------------------------- - RoadAccessCollector::RoadAccessCollector(string const & roadAccessPath, string const & osmIdsToFeatureIdsPath) { - MY_SCOPE_GUARD(clean, [this]() { - m_osmIdToFeatureId.clear(); - m_roadAccess.Clear(); - }); - - m_valid = true; - - if (!ParseOsmIdToFeatureIdMapping(osmIdsToFeatureIdsPath, m_osmIdToFeatureId)) + map osmIdToFeatureId; + if (!ParseOsmIdToFeatureIdMapping(osmIdsToFeatureIdsPath, osmIdToFeatureId)) { LOG(LWARNING, ("An error happened while parsing feature id to osm ids mapping from file:", osmIdsToFeatureIdsPath)); @@ -95,51 +135,20 @@ RoadAccessCollector::RoadAccessCollector(string const & roadAccessPath, return; } - if (!ParseRoadAccess(roadAccessPath)) + RoadAccess roadAccess; + if (!ParseRoadAccess(roadAccessPath, osmIdToFeatureId, roadAccess)) { LOG(LWARNING, ("An error happened while parsing road access from file:", roadAccessPath)); m_valid = false; return; } - clean.release(); -} - -bool RoadAccessCollector::ParseRoadAccess(string const & roadAccessPath) -{ - ifstream stream(roadAccessPath); - if (stream.fail()) - return false; - - string line; - while (getline(stream, line)) - { - strings::SimpleTokenizer iter(line, kDelim); - - // Empty line. - if (!iter) - return false; - - string const s = *iter; - ++iter; - - uint64_t osmId; - if (!iter || !strings::to_uint64(*iter, osmId)) - return false; - - auto const it = m_osmIdToFeatureId.find(osmId); - if (it == m_osmIdToFeatureId.cend()) - return false; - - uint32_t const featureId = it->second; - m_roadAccess.GetPrivateRoads().emplace_back(featureId); - } - - return true; + m_valid = true; + m_osmIdToFeatureId.swap(osmIdToFeatureId); + m_roadAccess.Swap(roadAccess); } // Functions ------------------------------------------------------------------ - void BuildRoadAccessInfo(string const & dataFilePath, string const & roadAccessPath, string const & osmIdsToFeatureIdsPath) { @@ -156,7 +165,6 @@ void BuildRoadAccessInfo(string const & dataFilePath, string const & roadAccessP FilesContainerW cont(dataFilePath, FileWriter::OP_WRITE_EXISTING); FileWriter writer = cont.GetWriter(ROAD_ACCESS_FILE_TAG); - RoadAccessSerializer serializer; - serializer.Serialize(writer, collector.GetRoadAccess()); + RoadAccessSerializer::Serialize(writer, collector.GetRoadAccess()); } } // namespace routing diff --git a/generator/road_access_generator.hpp b/generator/road_access_generator.hpp index 109e1b9dd2..3961dfa131 100644 --- a/generator/road_access_generator.hpp +++ b/generator/road_access_generator.hpp @@ -6,6 +6,7 @@ #include #include +#include #include struct OsmElement; @@ -21,10 +22,10 @@ class RoadAccessWriter public: void Open(std::string const & filePath); - void Process(OsmElement * p, FeatureParams & params); + void Process(OsmElement const & elem, FeatureParams const & params); private: - bool IsOpened(); + bool IsOpened() const; std::ofstream m_stream; }; @@ -34,15 +35,12 @@ class RoadAccessCollector public: RoadAccessCollector(std::string const & roadAccessPath, std::string const & osmIdsToFeatureIdsPath); - RoadAccess & GetRoadAccess() { return m_roadAccess; } RoadAccess const & GetRoadAccess() const { return m_roadAccess; } bool IsValid() const { return m_valid; } private: - bool ParseRoadAccess(std::string const & roadAccessPath); - - map m_osmIdToFeatureId; + std::map m_osmIdToFeatureId; RoadAccess m_roadAccess; bool m_valid; }; diff --git a/generator/routing_helpers.cpp b/generator/routing_helpers.cpp index 75eac294f1..fa03c47676 100644 --- a/generator/routing_helpers.cpp +++ b/generator/routing_helpers.cpp @@ -7,6 +7,9 @@ #include "base/logging.hpp" +using std::map; +using std::string; + namespace routing { void AddFeatureId(map & osmIdToFeatureId, uint32_t featureId, uint64_t osmId) diff --git a/routing/road_access.hpp b/routing/road_access.hpp index 07f4e882ac..eff4d7fdc1 100644 --- a/routing/road_access.hpp +++ b/routing/road_access.hpp @@ -8,17 +8,19 @@ namespace routing // This class provides information about road access classes. // For now, only restrictive types (such as barrier=gate and access=private) // and only car routing are supported. -class RoadAccess +class RoadAccess final { public: - RoadAccess() = default; - std::vector & GetPrivateRoads() { return m_privateRoads; } std::vector const & GetPrivateRoads() const { return m_privateRoads; } + void StealPrivateRoads(std::vector && v) { m_privateRoads = std::move(v); } + void Clear() { m_privateRoads.clear(); } - bool operator==(RoadAccess const & rhs) { return m_privateRoads == rhs.m_privateRoads; } + void Swap(RoadAccess & rhs) { m_privateRoads.swap(rhs.m_privateRoads); } + + bool operator==(RoadAccess const & rhs) const { return m_privateRoads == rhs.m_privateRoads; } private: // Feature ids of blocked features in the corresponding mwm. diff --git a/routing/road_access_serialization.hpp b/routing/road_access_serialization.hpp index a7244238c4..babb58859d 100644 --- a/routing/road_access_serialization.hpp +++ b/routing/road_access_serialization.hpp @@ -14,10 +14,10 @@ namespace routing { -class RoadAccessSerializer +class RoadAccessSerializer final { public: - uint32_t static const kLatestVersion; + ~RoadAccessSerializer() = delete; template static void Serialize(Sink & sink, RoadAccess const & roadAccess) @@ -53,5 +53,8 @@ public: privateRoads[i] = privateRoads[i - 1] + delta; } } + +private: + uint32_t static const kLatestVersion; }; } // namespace routing