diff --git a/generator/generator_tests/road_access_test.cpp b/generator/generator_tests/road_access_test.cpp index 5a92c4718c1..690bd170eac 100644 --- a/generator/generator_tests/road_access_test.cpp +++ b/generator/generator_tests/road_access_test.cpp @@ -353,14 +353,52 @@ UNIT_TEST(RoadAccessWriter_ConditionalMerge) "Private 10:00-20:00\n" "Car 1 1\n" "No Mo-Su\n"; - if (buffer.str() != correctAnswer) - { - cout << "Result:" << endl - << buffer.str() << endl - << "Correct result:" << endl - << correctAnswer << endl; - TEST(false, ()); - } + TEST_EQUAL(buffer.str(), correctAnswer, ()); +} + +UNIT_TEST(RoadAccessWriter_Conditional_WinterRoads) +{ + classificator::Load(); + auto const filename = generator_tests::GetFileName(); + SCOPE_GUARD(_, bind(Platform::RemoveFileIfExists, cref(filename))); + + auto const w1 = MakeOsmElementWithNodes( + 1 /* id */, {{"highway", "primary"}, {"ice_road", "yes"}} /* tags */, + OsmElement::EntityType::Way, {10, 11, 12, 13}); + + auto const w2 = MakeOsmElementWithNodes( + 2 /* id */, + {{"highway", "service"}, {"winter_road", "yes"}} /* tags */, + OsmElement::EntityType::Way, {20, 21, 22, 23}); + + auto c1 = make_shared(filename); + + c1->CollectFeature(MakeFbForTest(w1), w1); + c1->CollectFeature(MakeFbForTest(w2), w2); + + c1->Finish(); + c1->Save(); + + ifstream stream; + stream.exceptions(fstream::failbit | fstream::badbit); + stream.open(filename + ROAD_ACCESS_CONDITIONAL_EXT); + stringstream buffer; + buffer << stream.rdbuf(); + + string const correctAnswer = "Pedestrian 2 1\n" + "No Feb - Dec\n" + "Pedestrian 1 1\n" + "No Feb - Dec\n" + "Bicycle 2 1\n" + "No Feb - Dec\n" + "Bicycle 1 1\n" + "No Feb - Dec\n" + "Car 2 1\n" + "No Feb - Dec\n" + "Car 1 1\n" + "No Feb - Dec\n"; + + TEST_EQUAL(buffer.str(), correctAnswer, ()); } } // namespace diff --git a/generator/road_access_generator.cpp b/generator/road_access_generator.cpp index d179a9e3135..374d96d9675 100644 --- a/generator/road_access_generator.cpp +++ b/generator/road_access_generator.cpp @@ -63,6 +63,14 @@ vector const kBycicleAccessConditionalTags = { }; // @} +// Some tags assume access:conditional in fact, but doesn't have it. +// For example if road is tagged as "winter_road = yes", +// for routing it is like: "access:conditional = no @ (Feb - Dec)" +map kTagToAccessConditional = { + {OsmElement::Tag("winter_road", "yes"), "no @ (Mar - Nov)"}, + {OsmElement::Tag("ice_road", "yes"), "no @ (Mar - Nov)"} +}; + TagMapping const kMotorCarTagMapping = { {OsmElement::Tag("motorcar", "yes"), RoadAccess::Type::Yes}, {OsmElement::Tag("motorcar", "designated"), RoadAccess::Type::Yes}, @@ -343,6 +351,19 @@ optional> GetTagValueConditionalAccess( if (elem.HasTag(tag)) return make_pair(tag, elem.GetTag(tag)); } + + if (tagsList.empty()) + return nullopt; + + for (auto const & [tag, access] : kTagToAccessConditional) + { + if (elem.HasTag(tag.m_key, tag.m_value)) + { + CHECK(!tagsList.empty() && !tagsList.back().empty(), ()); + auto const anyAccessConditionalTag = tagsList.back().back(); + return make_pair(anyAccessConditionalTag, access); + } + } return nullopt; } diff --git a/routing/routing_tests/opening_hours_serdes_tests.cpp b/routing/routing_tests/opening_hours_serdes_tests.cpp index 45914a2aa67..c0d71677a69 100644 --- a/routing/routing_tests/opening_hours_serdes_tests.cpp +++ b/routing/routing_tests/opening_hours_serdes_tests.cpp @@ -857,4 +857,21 @@ UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_MonthHours_Usage) TEST(oh.IsClosed(GetUnixtimeByDate(2020, Month::May, 6, 01 /* hh */, 00 /* mm */)), ()); TEST(oh.IsOpen(GetUnixtimeByDate(2020, Month::May, 6, 01 /* hh */, 32 /* mm */)), ()); } + +UNIT_CLASS_TEST(BitReaderWriter, OpeningHoursSerDes_InverseMonths_Usage) +{ + EnableAll(); + + TEST(Serialize("Mar - Nov"), ()); + Flush(); + + auto const oh = Deserialize(); + + TEST(oh.IsOpen(GetUnixtimeByDate(2019, Month::Mar, 20, 20 /* hh */, 00 /* mm */)), ()); + TEST(oh.IsOpen(GetUnixtimeByDate(2019, Month::May, 20, 20 /* hh */, 00 /* mm */)), ()); + TEST(oh.IsOpen(GetUnixtimeByDate(2019, Month::Nov, 20, 20 /* hh */, 00 /* mm */)), ()); + TEST(!oh.IsOpen(GetUnixtimeByDate(2019, Month::Dec, 20, 20 /* hh */, 00 /* mm */)), ()); + TEST(!oh.IsOpen(GetUnixtimeByDate(2019, Month::Jan, 20, 20 /* hh */, 00 /* mm */)), ()); + TEST(!oh.IsOpen(GetUnixtimeByDate(2020, Month::Feb, 20, 20 /* hh */, 00 /* mm */)), ()); +} } // namespace