diff --git a/generator/generator_tests/maxspeeds_tests.cpp b/generator/generator_tests/maxspeeds_tests.cpp index f4f1d2aa26..17716c1917 100644 --- a/generator/generator_tests/maxspeeds_tests.cpp +++ b/generator/generator_tests/maxspeeds_tests.cpp @@ -90,7 +90,7 @@ void TestMaxspeedsSection(Features const & roads, string const & maxspeedsCsvCon // Creating maxspeed section in test.mwm. string const testMwmFullPath = base::JoinPath(testDirFullPath, testMwm); - BuildMaxspeedsSection(testMwmFullPath, featureIdToOsmId, base::JoinPath(testDirFullPath, kCsv)); + BuildMaxspeedsSection(nullptr, testMwmFullPath, featureIdToOsmId, base::JoinPath(testDirFullPath, kCsv)); // Loading maxspeed section. FrozenDataSource dataSource; diff --git a/generator/generator_tests/restriction_collector_test.cpp b/generator/generator_tests/restriction_collector_test.cpp index aadb350d50..2687a4b7cb 100644 --- a/generator/generator_tests/restriction_collector_test.cpp +++ b/generator/generator_tests/restriction_collector_test.cpp @@ -133,7 +133,8 @@ public: void ValidCase() { - RestrictionCollector restrictionCollector(m_osmIdsToFeatureIdFullPath, BuildTwoCubeGraph()); + auto graph = BuildTwoCubeGraph(); + RestrictionCollector restrictionCollector(m_osmIdsToFeatureIdFullPath, *graph); // Adding restrictions. TEST(restrictionCollector.AddRestriction( @@ -166,7 +167,8 @@ public: void InvalidCase_NoSuchFeature() { - RestrictionCollector restrictionCollector(m_osmIdsToFeatureIdFullPath, BuildTwoCubeGraph()); + auto graph = BuildTwoCubeGraph(); + RestrictionCollector restrictionCollector(m_osmIdsToFeatureIdFullPath, *graph); // No such feature - 2809 TEST(!restrictionCollector.AddRestriction({2.0, 1.0}, Restriction::Type::No, @@ -177,7 +179,8 @@ public: void InvalidCase_FeaturesNotIntersecting() { - RestrictionCollector restrictionCollector(m_osmIdsToFeatureIdFullPath, BuildTwoCubeGraph()); + auto graph = BuildTwoCubeGraph(); + RestrictionCollector restrictionCollector(m_osmIdsToFeatureIdFullPath, *graph); // Fetures with id 1 and 2 do not intersect in {2.0, 1.0} TEST(!restrictionCollector.AddRestriction({2.0, 1.0}, Restriction::Type::No, diff --git a/generator/generator_tests/restriction_test.cpp b/generator/generator_tests/restriction_test.cpp index 443439155d..112a10f3e7 100644 --- a/generator/generator_tests/restriction_test.cpp +++ b/generator/generator_tests/restriction_test.cpp @@ -168,8 +168,7 @@ void TestRestrictionBuilding(string const & restrictionPath, string const & mwmFullPath = scopedMwm.GetFullPath(); // Prepare data to collector. - auto restrictionCollector = - make_unique(osmIdsToFeatureIdFullPath, move(graph)); + auto restrictionCollector = make_unique(osmIdsToFeatureIdFullPath, *graph); TEST(restrictionCollector->Process(restrictionFullPath), ("Bad restrictions were given.")); diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp index 2f62c4ecd7..2575239763 100644 --- a/generator/generator_tool/generator_tool.cpp +++ b/generator/generator_tool/generator_tool.cpp @@ -504,9 +504,22 @@ MAIN_WITH_ERROR_HANDLING([](int argc, char ** argv) string const roadAccessFilename = genInfo.GetIntermediateFileName(ROAD_ACCESS_FILENAME); routing::BuildRoutingIndex(dataFile, country, *countryParentGetter); - routing::BuildRoadRestrictions(path, dataFile, country, restrictionsFilename, - osmToFeatureFilename, *countryParentGetter); - routing::BuildRoadAccessInfo(dataFile, roadAccessFilename, osmToFeatureFilename); + auto routingGraph = routing::CreateIndexGraph(path, dataFile, country, *countryParentGetter); + CHECK(routingGraph, ()); + + /// @todo CHECK return result doesn't work now for some small countries like Somalie. + if (!routing::BuildRoadRestrictions(*routingGraph, dataFile, restrictionsFilename, osmToFeatureFilename) || + !routing::BuildRoadAccessInfo(dataFile, roadAccessFilename, osmToFeatureFilename)) + { + LOG(LERROR, ("Routing build failed for", dataFile)); + } + + if (FLAGS_generate_maxspeed) + { + string const maxspeedsFilename = genInfo.GetIntermediateFileName(MAXSPEEDS_FILENAME); + LOG(LINFO, ("Generating maxspeeds section for", dataFile, "using", maxspeedsFilename)); + routing::BuildMaxspeedsSection(routingGraph.get(), dataFile, osmToFeatureFilename, maxspeedsFilename); + } } if (FLAGS_make_city_roads) @@ -519,13 +532,6 @@ MAIN_WITH_ERROR_HANDLING([](int argc, char ** argv) LOG(LCRITICAL, ("Generating city roads error.")); } - if (FLAGS_generate_maxspeed) - { - LOG(LINFO, ("Generating maxspeeds section for", dataFile)); - string const maxspeedsFilename = genInfo.GetIntermediateFileName(MAXSPEEDS_FILENAME); - routing::BuildMaxspeedsSection(dataFile, osmToFeatureFilename, maxspeedsFilename); - } - if (FLAGS_make_cross_mwm || FLAGS_make_transit_cross_mwm || FLAGS_make_transit_cross_mwm_experimental) { diff --git a/generator/maxspeeds_builder.cpp b/generator/maxspeeds_builder.cpp index 3cdc406787..5ef78d02c6 100644 --- a/generator/maxspeeds_builder.cpp +++ b/generator/maxspeeds_builder.cpp @@ -3,6 +3,7 @@ #include "generator/maxspeeds_parser.hpp" #include "generator/routing_helpers.hpp" +#include "routing/index_graph.hpp" #include "routing/maxspeeds_serialization.hpp" #include "routing/routing_helpers.hpp" @@ -37,7 +38,7 @@ namespace { char const kDelim[] = ", \t\r\n"; -bool ParseOneSpeedValue(strings::SimpleTokenizer & iter, uint16_t & value) +bool ParseOneSpeedValue(strings::SimpleTokenizer & iter, MaxspeedType & value) { if (!iter) return false; @@ -45,9 +46,9 @@ bool ParseOneSpeedValue(strings::SimpleTokenizer & iter, uint16_t & value) uint64_t parsedSpeed = 0; if (!strings::to_uint64(*iter, parsedSpeed)) return false; - if (parsedSpeed > numeric_limits::max()) + if (parsedSpeed > routing::kInvalidSpeed) return false; - value = static_cast(parsedSpeed); + value = static_cast(parsedSpeed); ++iter; return true; } @@ -61,47 +62,138 @@ FeatureMaxspeed ToFeatureMaxspeed(uint32_t featureId, Maxspeed const & maxspeed) /// \brief Collects all maxspeed tag values of specified mwm based on maxspeeds.csv file. class MaxspeedsMwmCollector { -public: - MaxspeedsMwmCollector(string const & dataPath, - map const & featureIdToOsmId, - string const & maxspeedCsvPath); - - vector && StealMaxspeeds(); - -private: vector m_maxspeeds; + +public: + MaxspeedsMwmCollector(IndexGraph * graph, string const & dataPath, + map const & featureIdToOsmId, + string const & maxspeedCsvPath) + { + OsmIdToMaxspeed osmIdToMaxspeed; + CHECK(ParseMaxspeeds(maxspeedCsvPath, osmIdToMaxspeed), (maxspeedCsvPath)); + + auto const GetOsmID = [&](uint32_t fid) -> base::GeoObjectId + { + auto const osmIdIt = featureIdToOsmId.find(fid); + if (osmIdIt == featureIdToOsmId.cend()) + return base::GeoObjectId(); + return osmIdIt->second; + }; + auto const GetSpeed = [&](uint32_t fid) -> Maxspeed * + { + auto osmid = GetOsmID(fid); + if (osmid.GetType() == base::GeoObjectId::Type::Invalid) + return nullptr; + + auto const maxspeedIt = osmIdToMaxspeed.find(osmid); + if (maxspeedIt == osmIdToMaxspeed.cend()) + return nullptr; + + return &maxspeedIt->second; + }; + auto const GetRoad = [&](uint32_t fid) -> routing::RoadGeometry const & + { + return graph->GetGeometry().GetRoad(fid); + }; + auto const GetLastIndex = [&](uint32_t fid) + { + return GetRoad(fid).GetPointsCount() - 2; + }; + auto const GetOpposite = [&](Segment const & seg) + { + // Assume that links are connected with main roads in first or last point, always. + uint32_t const fid = seg.GetFeatureId(); + return Segment(0, fid, seg.GetSegmentIdx() > 0 ? 0 : GetLastIndex(fid), seg.IsForward()); + }; + + ForEachFeature(dataPath, [&](FeatureType & ft, uint32_t fid) + { + if (!routing::IsCarRoad(TypesHolder(ft))) + return; + + Maxspeed * maxSpeed = GetSpeed(fid); + if (!maxSpeed) + return; + + auto const osmid = GetOsmID(fid).GetSerialId(); + + // Recalculate link speed accordint to the ingoing highway. + // See MaxspeedsCollector::CollectFeature. + if (maxSpeed->GetForward() == routing::kCommonMaxSpeedValue) + { + // Check if we are in unit tests. + if (graph == nullptr) + return; + + // 0 - not updated, 1 - goto next iteration, 2 - updated + int status; + + // Check ingoing first, then - outgoing. + for (bool direction : { false, true }) + { + Segment seg(0, fid, 0, true); + if (direction) + seg = GetOpposite(seg); + + std::unordered_set reviewed; + do + { + status = 0; + reviewed.insert(seg.GetFeatureId()); + + IndexGraph::SegmentEdgeListT edges; + graph->GetEdgeList(seg, direction, true /* useRoutingOptions */, edges); + for (auto const & e : edges) + { + Segment const target = e.GetTarget(); + Maxspeed * s = GetSpeed(target.GetFeatureId()); + if (s) + { + if (s->GetForward() != routing::kCommonMaxSpeedValue) + { + status = 2; + maxSpeed->SetForward(s->GetForward()); + + // In theory, we should iterate on forward and backward segments/speeds separately, + // but I don't see any reason for this complication. + if (!GetRoad(fid).IsOneWay()) + maxSpeed->SetBackward(s->GetForward()); + + LOG(LINFO, ("Updated link speed for way", osmid, "with", *maxSpeed)); + break; + } + else if (reviewed.find(target.GetFeatureId()) == reviewed.end()) + { + // Found another input link. Save it for the next iteration. + status = 1; + seg = GetOpposite(target); + } + } + } + } while (status == 1); + + if (status == 2) + break; + } + + if (status == 0) + { + LOG(LWARNING, ("Didn't find connected edge with speed for way", osmid)); + return; + } + } + + m_maxspeeds.push_back(ToFeatureMaxspeed(fid, *maxSpeed)); + }); + } + + vector const & GetMaxspeeds() + { + CHECK(is_sorted(m_maxspeeds.cbegin(), m_maxspeeds.cend(), IsFeatureIdLess), ()); + return m_maxspeeds; + } }; -MaxspeedsMwmCollector::MaxspeedsMwmCollector( - string const & dataPath, map const & featureIdToOsmId, - string const & maxspeedCsvPath) -{ - OsmIdToMaxspeed osmIdToMaxspeed; - CHECK(ParseMaxspeeds(maxspeedCsvPath, osmIdToMaxspeed), (maxspeedCsvPath)); - - ForEachFeature(dataPath, [&](FeatureType & ft, uint32_t fid) { - if (!routing::IsCarRoad(TypesHolder(ft))) - return; - - auto const osmIdIt = featureIdToOsmId.find(fid); - if (osmIdIt == featureIdToOsmId.cend()) - return; - - // @TODO Consider adding check here. |fid| should be in |featureIdToOsmId| anyway. - auto const maxspeedIt = osmIdToMaxspeed.find(osmIdIt->second); - if (maxspeedIt == osmIdToMaxspeed.cend()) - return; - - auto const & maxspeed = maxspeedIt->second; - m_maxspeeds.push_back(ToFeatureMaxspeed(fid, maxspeed)); - }); -} - -vector && MaxspeedsMwmCollector::StealMaxspeeds() -{ - CHECK(is_sorted(m_maxspeeds.cbegin(), m_maxspeeds.cend(), IsFeatureIdLess), ()); - return move(m_maxspeeds); -} } // namespace namespace routing @@ -134,7 +226,7 @@ bool ParseMaxspeeds(string const & maxspeedsFilename, OsmIdToMaxspeed & osmIdToM speed.SetUnits(StringToUnits(*iter)); ++iter; - uint16_t forward = 0; + MaxspeedType forward = 0; if (!ParseOneSpeedValue(iter, forward)) return false; @@ -143,7 +235,7 @@ bool ParseMaxspeeds(string const & maxspeedsFilename, OsmIdToMaxspeed & osmIdToM if (iter) { // There's backward maxspeed limit. - uint16_t backward = 0; + MaxspeedType backward = 0; if (!ParseOneSpeedValue(iter, backward)) return false; @@ -160,7 +252,7 @@ bool ParseMaxspeeds(string const & maxspeedsFilename, OsmIdToMaxspeed & osmIdToM return true; } -void SerializeMaxspeeds(string const & dataPath, vector && speeds) +void SerializeMaxspeeds(string const & dataPath, vector const & speeds) { if (speeds.empty()) return; @@ -172,21 +264,19 @@ void SerializeMaxspeeds(string const & dataPath, vector && spee LOG(LINFO, ("SerializeMaxspeeds(", dataPath, ", ...) serialized:", speeds.size(), "maxspeed tags.")); } -void BuildMaxspeedsSection(string const & dataPath, +void BuildMaxspeedsSection(IndexGraph * graph, string const & dataPath, map const & featureIdToOsmId, string const & maxspeedsFilename) { - MaxspeedsMwmCollector collector(dataPath, featureIdToOsmId, maxspeedsFilename); - SerializeMaxspeeds(dataPath, collector.StealMaxspeeds()); + MaxspeedsMwmCollector collector(graph, dataPath, featureIdToOsmId, maxspeedsFilename); + SerializeMaxspeeds(dataPath, collector.GetMaxspeeds()); } -void BuildMaxspeedsSection(string const & dataPath, string const & osmToFeaturePath, - string const & maxspeedsFilename) +void BuildMaxspeedsSection(IndexGraph * graph, string const & dataPath, + string const & osmToFeaturePath, string const & maxspeedsFilename) { - LOG(LINFO, ("BuildMaxspeedsSection(", dataPath, ",", osmToFeaturePath, ",", maxspeedsFilename, ")")); - map featureIdToOsmId; CHECK(ParseWaysFeatureIdToOsmIdMapping(osmToFeaturePath, featureIdToOsmId), ()); - BuildMaxspeedsSection(dataPath, featureIdToOsmId, maxspeedsFilename); + BuildMaxspeedsSection(graph, dataPath, featureIdToOsmId, maxspeedsFilename); } } // namespace routing diff --git a/generator/maxspeeds_builder.hpp b/generator/maxspeeds_builder.hpp index 33b6d91d17..65705c3ad9 100644 --- a/generator/maxspeeds_builder.hpp +++ b/generator/maxspeeds_builder.hpp @@ -13,6 +13,7 @@ namespace routing { +class IndexGraph; using OsmIdToMaxspeed = std::map; /// \brief Parses csv file with path |maxspeedsFilename| and stores the result in |osmIdToMaxspeed|. @@ -20,9 +21,9 @@ using OsmIdToMaxspeed = std::map; bool ParseMaxspeeds(std::string const & maxspeedsFilename, OsmIdToMaxspeed & osmIdToMaxspeed); /// \brief Writes |speeds| to maxspeeds section to mwm with |dataPath|. -void SerializeMaxspeeds(std::string const & dataPath, std::vector && speeds); +void SerializeMaxspeeds(std::string const & dataPath, std::vector const & speeds); -void BuildMaxspeedsSection(std::string const & dataPath, +void BuildMaxspeedsSection(IndexGraph * graph, std::string const & dataPath, std::map const & featureIdToOsmId, std::string const & maxspeedsFilename); @@ -34,6 +35,6 @@ void BuildMaxspeedsSection(std::string const & dataPath, // to a csv file. /// 2. Calls GenerateFeatures() /// 3. Generates geometry. -void BuildMaxspeedsSection(std::string const & dataPath, std::string const & osmToFeaturePath, - std::string const & maxspeedsFilename); +void BuildMaxspeedsSection(IndexGraph * graph, std::string const & dataPath, + std::string const & osmToFeaturePath, std::string const & maxspeedsFilename); } // namespace routing diff --git a/generator/maxspeeds_collector.cpp b/generator/maxspeeds_collector.cpp index 47cd405f14..482c76014e 100644 --- a/generator/maxspeeds_collector.cpp +++ b/generator/maxspeeds_collector.cpp @@ -102,15 +102,18 @@ void MaxspeedsCollector::CollectFeature(FeatureBuilder const & ft, OsmElement co ss << "," << strings::to_string(maxspeedBackward.GetSpeed()); } } - else if (ftypes::IsLinkChecker::Instance()(ft.GetTypes()) && - ParseMaxspeedAndWriteToStream(maxspeedAdvisoryStr, maxspeed, ss)) + else if (ftypes::IsLinkChecker::Instance()(ft.GetTypes())) { // Assign maxspeed:advisory for highway:xxx_link types to avoid situation when // not defined link speed is predicted bigger than defined parent ingoing highway speed. // https://www.openstreetmap.org/way/5511439#map=18/45.55465/-122.67787 - - /// @todo Best solution is to correct not defined link speed according to the defined parent highway speed - /// in graph building process, but it needs much more efforts. + if (!ParseMaxspeedAndWriteToStream(maxspeedAdvisoryStr, maxspeed, ss)) + { + // Write indicator that it's a link and the speed should be recalculated. + // Idea is to set the link speed equal to the ingoing highway speed (now it's "default" and can be bigger). + // https://www.openstreetmap.org/way/842536050#map=19/45.43449/-122.56678 + ss << UnitsToString(measurement_utils::Units::Metric) << "," << strings::to_string(routing::kCommonMaxSpeedValue); + } } else return; diff --git a/generator/restriction_collector.cpp b/generator/restriction_collector.cpp index d02c02b4ba..64cbd98f32 100644 --- a/generator/restriction_collector.cpp +++ b/generator/restriction_collector.cpp @@ -49,8 +49,8 @@ namespace routing m2::PointD constexpr RestrictionCollector::kNoCoords; RestrictionCollector::RestrictionCollector(std::string const & osmIdsToFeatureIdPath, - std::unique_ptr && graph) - : m_indexGraph(std::move(graph)) + IndexGraph & graph) + : m_indexGraph(graph) { CHECK(ParseWaysOsmIdToFeatureIdMapping(osmIdsToFeatureIdPath, m_osmIdToFeatureIds), ("An error happened while parsing feature id to " @@ -59,8 +59,6 @@ RestrictionCollector::RestrictionCollector(std::string const & osmIdsToFeatureId bool RestrictionCollector::Process(std::string const & restrictionPath) { - CHECK(m_indexGraph, ()); - SCOPE_GUARD(clean, [this]() { m_osmIdToFeatureIds.clear(); m_restrictions.clear(); @@ -129,11 +127,11 @@ bool RestrictionCollector::ParseRestrictions(std::string const & path) Joint::Id RestrictionCollector::GetFirstCommonJoint(uint32_t firstFeatureId, uint32_t secondFeatureId) const { - uint32_t const firstLen = m_indexGraph->GetGeometry().GetRoad(firstFeatureId).GetPointsCount(); - uint32_t const secondLen = m_indexGraph->GetGeometry().GetRoad(secondFeatureId).GetPointsCount(); + uint32_t const firstLen = m_indexGraph.GetGeometry().GetRoad(firstFeatureId).GetPointsCount(); + uint32_t const secondLen = m_indexGraph.GetGeometry().GetRoad(secondFeatureId).GetPointsCount(); - auto const firstRoad = m_indexGraph->GetRoad(firstFeatureId); - auto const secondRoad = m_indexGraph->GetRoad(secondFeatureId); + auto const firstRoad = m_indexGraph.GetRoad(firstFeatureId); + auto const secondRoad = m_indexGraph.GetRoad(secondFeatureId); std::unordered_set used; for (uint32_t i = 0; i < firstLen; ++i) @@ -154,8 +152,7 @@ Joint::Id RestrictionCollector::GetFirstCommonJoint(uint32_t firstFeatureId, bool RestrictionCollector::FeatureHasPointWithCoords(uint32_t featureId, m2::PointD const & coords) const { - CHECK(m_indexGraph, ()); - auto const & roadGeometry = m_indexGraph->GetGeometry().GetRoad(featureId); + auto const & roadGeometry = m_indexGraph.GetGeometry().GetRoad(featureId); uint32_t const pointsCount = roadGeometry.GetPointsCount(); for (uint32_t i = 0; i < pointsCount; ++i) { @@ -245,7 +242,7 @@ bool RestrictionCollector::CheckAndProcessUTurn(Restriction::Type & restrictionT uint32_t & featureId = featureIds.back(); - auto const & road = m_indexGraph->GetGeometry().GetRoad(featureId); + auto const & road = m_indexGraph.GetGeometry().GetRoad(featureId); // Can not do UTurn from feature to the same feature if it is one way. if (road.IsOneWay()) return false; @@ -282,14 +279,14 @@ bool RestrictionCollector::IsRestrictionValid(Restriction::Type & restrictionTyp m2::PointD const & coords, std::vector & featureIds) const { - if (featureIds.empty() || !m_indexGraph->IsRoad(featureIds[0])) + if (featureIds.empty() || !m_indexGraph.IsRoad(featureIds[0])) return false; for (size_t i = 1; i < featureIds.size(); ++i) { auto prev = featureIds[i - 1]; auto cur = featureIds[i]; - if (!m_indexGraph->IsRoad(cur)) + if (!m_indexGraph.IsRoad(cur)) return false; if (!FeaturesAreCross(coords, prev, cur)) diff --git a/generator/restriction_collector.hpp b/generator/restriction_collector.hpp index 36f40eb3db..bd5f5fa8b2 100644 --- a/generator/restriction_collector.hpp +++ b/generator/restriction_collector.hpp @@ -30,8 +30,7 @@ public: static m2::PointD constexpr kNoCoords = m2::PointD(std::numeric_limits::max(), std::numeric_limits::max()); - RestrictionCollector(std::string const & osmIdsToFeatureIdPath, - std::unique_ptr && graph); + RestrictionCollector(std::string const & osmIdsToFeatureIdPath, IndexGraph & graph); bool Process(std::string const & restrictionPath); @@ -94,7 +93,7 @@ private: std::vector m_restrictions; OsmIdToFeatureIds m_osmIdToFeatureIds; - std::unique_ptr m_indexGraph; + IndexGraph & m_indexGraph; std::string m_restrictionPath; }; diff --git a/generator/restriction_generator.cpp b/generator/restriction_generator.cpp index ddab386971..a0244508a5 100644 --- a/generator/restriction_generator.cpp +++ b/generator/restriction_generator.cpp @@ -26,9 +26,8 @@ #include #include -namespace +namespace routing { -using namespace routing; std::unique_ptr CreateIndexGraph(std::string const & targetPath, @@ -51,37 +50,6 @@ CreateIndexGraph(std::string const & targetPath, return graph; } -} // namespace - -namespace routing -{ -std::unique_ptr -CreateRestrictionCollectorAndParse( - std::string const & targetPath, std::string const & mwmPath, std::string const & country, - std::string const & restrictionPath, std::string const & osmIdsToFeatureIdsPath, - CountryParentNameGetterFn const & countryParentNameGetterFn) -{ - LOG(LDEBUG, ("BuildRoadRestrictions(", targetPath, ", ", restrictionPath, ", ", - osmIdsToFeatureIdsPath, ");")); - - std::unique_ptr graph = - CreateIndexGraph(targetPath, mwmPath, country, countryParentNameGetterFn); - - auto restrictionCollector = - std::make_unique(osmIdsToFeatureIdsPath, std::move(graph)); - - if (!restrictionCollector->Process(restrictionPath)) - return {}; - - if (!restrictionCollector->HasRestrictions()) - { - LOG(LINFO, ("No restrictions for", targetPath, "It's necessary to check that", - restrictionPath, "and", osmIdsToFeatureIdsPath, "are available.")); - return {}; - } - - return restrictionCollector; -} void SerializeRestrictions(RestrictionCollector & restrictionCollector, std::string const & mwmPath) @@ -125,21 +93,25 @@ void SerializeRestrictions(RestrictionCollector & restrictionCollector, RestrictionSerializer::Serialize(header, restrictions.begin(), restrictions.end(), *w); } -bool BuildRoadRestrictions(std::string const & targetPath, +bool BuildRoadRestrictions(IndexGraph & graph, std::string const & mwmPath, - std::string const & country, std::string const & restrictionPath, - std::string const & osmIdsToFeatureIdsPath, - CountryParentNameGetterFn const & countryParentNameGetterFn) + std::string const & osmIdsToFeatureIdsPath) { - auto collector = - CreateRestrictionCollectorAndParse(targetPath, mwmPath, country, restrictionPath, - osmIdsToFeatureIdsPath, countryParentNameGetterFn); + LOG(LINFO, ("BuildRoadRestrictions(", restrictionPath, ", ", osmIdsToFeatureIdsPath, ");")); - if (!collector) + auto collector = std::make_unique(osmIdsToFeatureIdsPath, graph); + if (!collector->Process(restrictionPath)) return false; + if (!collector->HasRestrictions()) + { + LOG(LWARNING, ("No restrictions created. Check that", restrictionPath, "and", osmIdsToFeatureIdsPath, "are available.")); + return false; + } + SerializeRestrictions(*collector, mwmPath); return true; } + } // namespace routing diff --git a/generator/restriction_generator.hpp b/generator/restriction_generator.hpp index 9263247c37..0eca775040 100644 --- a/generator/restriction_generator.hpp +++ b/generator/restriction_generator.hpp @@ -8,11 +8,11 @@ namespace routing { -std::unique_ptr -CreateRestrictionCollectorAndParse( - std::string const & targetPath, std::string const & mwmPath, std::string const & country, - std::string const & restrictionPath, std::string const & osmIdsToFeatureIdsPath, - CountryParentNameGetterFn const & countryParentNameGetterFn); +std::unique_ptr +CreateIndexGraph(std::string const & targetPath, + std::string const & mwmPath, + std::string const & country, + CountryParentNameGetterFn const & countryParentNameGetterFn); void SerializeRestrictions(RestrictionCollector & restrictionCollector, std::string const & mwmPath); @@ -41,10 +41,8 @@ void SerializeRestrictions(RestrictionCollector & restrictionCollector, /// \param osmIdsToFeatureIdsPath a binary file with mapping form osm ids to feature ids. /// One osm id is mapped to one feature id. The file should be saved with the help of /// OsmID2FeatureID class or using a similar way. -bool BuildRoadRestrictions(std::string const & targetPath, +bool BuildRoadRestrictions(IndexGraph & graph, std::string const & mwmPath, - std::string const & country, std::string const & restrictionPath, - std::string const & osmIdsToFeatureIdsPath, - CountryParentNameGetterFn const & countryParentNameGetterFn); + std::string const & osmIdsToFeatureIdsPath); } // namespace routing diff --git a/generator/road_access_generator.cpp b/generator/road_access_generator.cpp index 70715caa9f..6df6ad22f4 100644 --- a/generator/road_access_generator.cpp +++ b/generator/road_access_generator.cpp @@ -822,7 +822,7 @@ string AccessConditionalTagParser::TrimAndDropAroundParentheses(string input) co } // Functions ------------------------------------------------------------------ -void BuildRoadAccessInfo(string const & dataFilePath, string const & roadAccessPath, +bool BuildRoadAccessInfo(string const & dataFilePath, string const & roadAccessPath, string const & osmIdsToFeatureIdsPath) { LOG(LINFO, ("Generating road access info for", dataFilePath)); @@ -832,12 +832,13 @@ void BuildRoadAccessInfo(string const & dataFilePath, string const & roadAccessP if (!collector.IsValid()) { LOG(LWARNING, ("Unable to parse road access in osm terms")); - return; + return false; } FilesContainerW cont(dataFilePath, FileWriter::OP_WRITE_EXISTING); auto writer = cont.GetWriter(ROAD_ACCESS_FILE_TAG); RoadAccessSerializer::Serialize(*writer, collector.GetRoadAccessAllTypes()); + return true; } } // namespace routing diff --git a/generator/road_access_generator.hpp b/generator/road_access_generator.hpp index 5d4fea9079..96eed2627d 100644 --- a/generator/road_access_generator.hpp +++ b/generator/road_access_generator.hpp @@ -161,6 +161,6 @@ private: // The generator tool's interface to writing the section with // road accessibility information for one mwm file. -void BuildRoadAccessInfo(std::string const & dataFilePath, std::string const & roadAccessPath, +bool BuildRoadAccessInfo(std::string const & dataFilePath, std::string const & roadAccessPath, std::string const & osmIdsToFeatureIdsPath); } // namespace routing