forked from organicmaps/organicmaps
Implement from OpeningHours to TimeTableSet conversion.
This commit is contained in:
parent
db00bcfdee
commit
832abf1f54
8 changed files with 249 additions and 15 deletions
|
@ -26,7 +26,9 @@
|
|||
#include "rules_evaluation.hpp"
|
||||
#include "parse_opening_hours.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <ostream>
|
||||
|
@ -748,4 +750,28 @@ bool OpeningHours::IsValid() const
|
|||
{
|
||||
return m_valid;
|
||||
}
|
||||
bool OpeningHours::IsTwentyFourHours() const
|
||||
{
|
||||
return m_rule.size() == 1 && m_rule[0].IsTwentyFourHours();
|
||||
}
|
||||
|
||||
bool OpeningHours::HasWeekdaySelector() const
|
||||
{
|
||||
return std::any_of(begin(m_rule), end(m_rule), std::mem_fn(&osmoh::RuleSequence::HasWeekdays));
|
||||
}
|
||||
|
||||
bool OpeningHours::HasMonthSelector() const
|
||||
{
|
||||
return std::any_of(begin(m_rule), end(m_rule), std::mem_fn(&osmoh::RuleSequence::HasMonths));
|
||||
}
|
||||
|
||||
bool OpeningHours::HasWeekSelector() const
|
||||
{
|
||||
return std::any_of(begin(m_rule), end(m_rule), std::mem_fn(&osmoh::RuleSequence::HasWeeks));
|
||||
}
|
||||
|
||||
bool OpeningHours::HasYearSelector() const
|
||||
{
|
||||
return std::any_of(begin(m_rule), end(m_rule), std::mem_fn(&osmoh::RuleSequence::HasYears));
|
||||
}
|
||||
} // namespace osmoh
|
||||
|
|
|
@ -69,6 +69,16 @@ private:
|
|||
HourMinutes operator-(HourMinutes const & hm);
|
||||
std::ostream & operator<<(std::ostream & ost, HourMinutes const & hm);
|
||||
|
||||
inline bool operator<(HourMinutes const & a, HourMinutes const & b)
|
||||
{
|
||||
return a.GetDuration() < b.GetDuration();
|
||||
}
|
||||
|
||||
inline bool operator==(HourMinutes const & a, HourMinutes const & b)
|
||||
{
|
||||
return a.GetDuration() == b.GetDuration();
|
||||
}
|
||||
|
||||
class Time;
|
||||
|
||||
class TimeEvent
|
||||
|
@ -661,6 +671,13 @@ public:
|
|||
|
||||
bool IsValid() const;
|
||||
|
||||
bool IsTwentyFourHours() const;
|
||||
bool HasWeekdaySelector() const;
|
||||
bool HasMonthSelector() const;
|
||||
bool HasWeekSelector() const;
|
||||
bool HasYearSelector() const;
|
||||
|
||||
TRuleSequences const & GetRule() const { return m_rule; }
|
||||
private:
|
||||
TRuleSequences m_rule;
|
||||
bool const m_valid;
|
||||
|
|
|
@ -196,6 +196,8 @@ std::tm MakeTimetuple(time_t const timestamp)
|
|||
|
||||
namespace osmoh
|
||||
{
|
||||
using ::operator==;
|
||||
|
||||
bool IsActive(Timespan const & span, std::tm const & time)
|
||||
{
|
||||
// Timespan with e.h. should be split into parts with no e.h.
|
||||
|
|
|
@ -16,3 +16,4 @@ SOURCES += \
|
|||
$$ROOT_DIR/testing/testingmain.cpp \
|
||||
opening_hours_ui_test.cpp \
|
||||
xml_feature_test.cpp \
|
||||
ui2oh_test.cpp \
|
||||
|
|
113
editor/editor_tests/ui2oh_test.cpp
Normal file
113
editor/editor_tests/ui2oh_test.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "editor/ui2oh.hpp"
|
||||
|
||||
using namespace osmoh;
|
||||
using namespace editor;
|
||||
using namespace editor::ui;
|
||||
|
||||
UNIT_TEST(ConvertOpeningHours)
|
||||
{
|
||||
{
|
||||
OpeningHours oh("Mo-Fr 08:00-22:00");
|
||||
TEST(oh.IsValid(), ());
|
||||
|
||||
TimeTableSet tts;
|
||||
|
||||
TEST(ConvertOpeningHours(oh, tts), ());
|
||||
TEST_EQUAL(tts.Size(), 1, ());
|
||||
|
||||
auto const tt = tts.Front();
|
||||
TEST(!tt.IsTwentyFourHours(), ());
|
||||
TEST_EQUAL(tt.GetWorkingDays().size(), 5, ());
|
||||
TEST_EQUAL(tt.GetOpeningTime().GetStart().GetHourMinutes().GetHoursCount(), 8, ());
|
||||
TEST_EQUAL(tt.GetOpeningTime().GetEnd().GetHourMinutes().GetHoursCount(), 22, ());
|
||||
}
|
||||
{
|
||||
OpeningHours oh("Mo-Fr 08:00-12:00, 13:00-22:00");
|
||||
TEST(oh.IsValid(), ());
|
||||
|
||||
TimeTableSet tts;
|
||||
|
||||
TEST(ConvertOpeningHours(oh, tts), ());
|
||||
TEST_EQUAL(tts.Size(), 1, ());
|
||||
|
||||
auto const tt = tts.Front();
|
||||
TEST(!tt.IsTwentyFourHours(), ());
|
||||
TEST_EQUAL(tt.GetWorkingDays().size(), 5, ());
|
||||
TEST_EQUAL(tt.GetOpeningTime().GetStart().GetHourMinutes().GetHoursCount(), 8, ());
|
||||
TEST_EQUAL(tt.GetOpeningTime().GetEnd().GetHourMinutes().GetHoursCount(), 22, ());
|
||||
|
||||
TEST_EQUAL(tt.GetExcludeTime().size(), 1, ());
|
||||
TEST_EQUAL(tt.GetExcludeTime()[0].GetStart().GetHourMinutes().GetHoursCount(), 12, ());
|
||||
TEST_EQUAL(tt.GetExcludeTime()[0].GetEnd().GetHourMinutes().GetHoursCount(), 13, ());
|
||||
}
|
||||
{
|
||||
OpeningHours oh("Mo-Fr 08:00-10:00, 11:00-12:30, 13:00-22:00");
|
||||
TEST(oh.IsValid(), ());
|
||||
|
||||
TimeTableSet tts;
|
||||
|
||||
TEST(ConvertOpeningHours(oh, tts), ());
|
||||
TEST_EQUAL(tts.Size(), 1, ());
|
||||
|
||||
auto const tt = tts.Front();
|
||||
TEST(!tt.IsTwentyFourHours(), ());
|
||||
TEST_EQUAL(tt.GetWorkingDays().size(), 5, ());
|
||||
TEST_EQUAL(tt.GetOpeningTime().GetStart().GetHourMinutes().GetHoursCount(), 8, ());
|
||||
TEST_EQUAL(tt.GetOpeningTime().GetEnd().GetHourMinutes().GetHoursCount(), 22, ());
|
||||
|
||||
TEST_EQUAL(tt.GetExcludeTime().size(), 2, ());
|
||||
TEST_EQUAL(tt.GetExcludeTime()[0].GetStart().GetHourMinutes().GetHoursCount(), 10, ());
|
||||
TEST_EQUAL(tt.GetExcludeTime()[0].GetEnd().GetHourMinutes().GetHoursCount(), 11, ());
|
||||
TEST_EQUAL(tt.GetExcludeTime()[1].GetStart().GetHourMinutes().GetHoursCount(), 12, ());
|
||||
TEST_EQUAL(tt.GetExcludeTime()[1].GetEnd().GetHourMinutes().GetHoursCount(), 13, ());
|
||||
TEST_EQUAL(tt.GetExcludeTime()[1].GetStart().GetHourMinutes().GetMinutesCount(), 30, ());
|
||||
TEST_EQUAL(tt.GetExcludeTime()[1].GetEnd().GetHourMinutes().GetMinutesCount(), 0, ());
|
||||
}
|
||||
{
|
||||
OpeningHours oh("Mo-Fr 08:00-10:00; Su, Sa 13:00-22:00");
|
||||
TEST(oh.IsValid(), ());
|
||||
|
||||
TimeTableSet tts;
|
||||
|
||||
TEST(ConvertOpeningHours(oh, tts), ());
|
||||
TEST_EQUAL(tts.Size(), 2, ());
|
||||
|
||||
{
|
||||
auto const tt = tts.Get(0);
|
||||
TEST(!tt.IsTwentyFourHours(), ());
|
||||
TEST_EQUAL(tt.GetWorkingDays().size(), 5, ());
|
||||
}
|
||||
|
||||
{
|
||||
auto const tt = tts.Get(1);
|
||||
TEST(!tt.IsTwentyFourHours(), ());
|
||||
TEST_EQUAL(tt.GetWorkingDays().size(), 2, ());
|
||||
}
|
||||
}
|
||||
{
|
||||
OpeningHours oh("Jan Mo-Fr 08:00-10:00");
|
||||
TEST(oh.IsValid(), ());
|
||||
|
||||
TimeTableSet tts;
|
||||
|
||||
TEST(!ConvertOpeningHours(oh, tts), ());
|
||||
}
|
||||
{
|
||||
OpeningHours oh("2016 Mo-Fr 08:00-10:00");
|
||||
TEST(oh.IsValid(), ());
|
||||
|
||||
TimeTableSet tts;
|
||||
|
||||
TEST(!ConvertOpeningHours(oh, tts), ());
|
||||
}
|
||||
{
|
||||
OpeningHours oh("week 30 Mo-Fr 08:00-10:00");
|
||||
TEST(oh.IsValid(), ());
|
||||
|
||||
TimeTableSet tts;
|
||||
|
||||
TEST(!ConvertOpeningHours(oh, tts), ());
|
||||
}
|
||||
}
|
|
@ -48,18 +48,17 @@ bool FixTimeSpans(osmoh::Timespan openingTime, osmoh::TTimespans & spans)
|
|||
span.GetEnd().GetHourMinutes().AddDuration(24_h);
|
||||
}
|
||||
|
||||
sort(begin(spans), end(spans),
|
||||
[](osmoh::Timespan const & s1, osmoh::Timespan const s2)
|
||||
{
|
||||
auto const start1 = s1.GetStart().GetHourMinutes().GetDuration();
|
||||
auto const start2 = s2.GetStart().GetHourMinutes().GetDuration();
|
||||
sort(begin(spans), end(spans), [](osmoh::Timespan const & s1, osmoh::Timespan const s2)
|
||||
{
|
||||
auto const start1 = s1.GetStart().GetHourMinutes();
|
||||
auto const start2 = s2.GetStart().GetHourMinutes();
|
||||
|
||||
// If two spans start at the same point the longest span should be leftmost.
|
||||
if (start1 == start2)
|
||||
return SpanLength(s1) > SpanLength(s2);
|
||||
// If two spans start at the same point the longest span should be leftmost.
|
||||
if (start1 == start2)
|
||||
return SpanLength(s1) > SpanLength(s2);
|
||||
|
||||
return start1 < start2;
|
||||
});
|
||||
return start1 < start2;
|
||||
});
|
||||
|
||||
osmoh::TTimespans result{spans.front()};
|
||||
for (auto i = 1, j = 0; i < spans.size(); ++i)
|
||||
|
|
|
@ -1,19 +1,95 @@
|
|||
#include "editor/ui2oh.hpp"
|
||||
|
||||
#include "base/enumerate.hpp"
|
||||
|
||||
#include "std/algorithm.hpp"
|
||||
#include "std/array.hpp"
|
||||
#include "std/string.hpp"
|
||||
|
||||
#include "3party/opening_hours/opening_hours.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
void SetUpWeekdays(osmoh::Weekdays const & wds, editor::ui::TimeTable & tt)
|
||||
{
|
||||
set<osmoh::Weekday> workingDays;
|
||||
for (auto const & wd : wds.GetWeekdayRanges())
|
||||
{
|
||||
if (wd.HasSunday())
|
||||
workingDays.insert(osmoh::Weekday::Sunday);
|
||||
if (wd.HasMonday())
|
||||
workingDays.insert(osmoh::Weekday::Monday);
|
||||
if (wd.HasTuesday())
|
||||
workingDays.insert(osmoh::Weekday::Tuesday);
|
||||
if (wd.HasWednesday())
|
||||
workingDays.insert(osmoh::Weekday::Wednesday);
|
||||
if (wd.HasThursday())
|
||||
workingDays.insert(osmoh::Weekday::Thursday);
|
||||
if (wd.HasFriday())
|
||||
workingDays.insert(osmoh::Weekday::Friday);
|
||||
if (wd.HasSaturday())
|
||||
workingDays.insert(osmoh::Weekday::Saturday);
|
||||
}
|
||||
tt.SetWorkingDays(workingDays);
|
||||
}
|
||||
|
||||
void SetUpTimeTable(osmoh::TTimespans spans, editor::ui::TimeTable & tt)
|
||||
{
|
||||
using namespace osmoh;
|
||||
|
||||
sort(begin(spans), end(spans), [](Timespan const & a, Timespan const & b)
|
||||
{
|
||||
auto const start1 = a.GetStart().GetHourMinutes().GetDuration();
|
||||
auto const start2 = b.GetStart().GetHourMinutes().GetDuration();
|
||||
|
||||
return start1 < start2;
|
||||
});
|
||||
|
||||
// Take first start and last end as opening time span.
|
||||
tt.SetOpeningTime({spans.front().GetStart(), spans.back().GetEnd()});
|
||||
|
||||
// Add an end of a span of index i and start of following span
|
||||
// as exclude time.
|
||||
for (auto i = 0; i + 1 < spans.size(); ++i)
|
||||
tt.AddExcludeTime({spans[i].GetEnd(), spans[i + 1].GetStart()});
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace editor
|
||||
{
|
||||
osmoh::OpeningHours ConvertOpeningHours(ui::TimeTableSet const & tt)
|
||||
{
|
||||
return string(); // TODO(mgsergio): // Just a dummy.
|
||||
return string(); // TODO(mgsergio): Implement me.
|
||||
}
|
||||
|
||||
ui::TimeTableSet ConvertOpeningHours(osmoh::OpeningHours const & oh)
|
||||
bool ConvertOpeningHours(osmoh::OpeningHours const & oh, ui::TimeTableSet & tts)
|
||||
{
|
||||
return {};
|
||||
if (oh.HasYearSelector() || oh.HasWeekSelector() || oh.HasMonthSelector())
|
||||
return false;
|
||||
|
||||
tts = ui::TimeTableSet();
|
||||
if (oh.IsTwentyFourHours())
|
||||
return true;
|
||||
|
||||
for (auto const & p : my::enumerate(oh.GetRule()))
|
||||
{
|
||||
auto const & rulePart = p.item;
|
||||
ui::TimeTable tt;
|
||||
|
||||
if (rulePart.HasWeekdays())
|
||||
SetUpWeekdays(rulePart.GetWeekdays(), tt);
|
||||
|
||||
if (rulePart.HasTimes())
|
||||
{
|
||||
tt.SetTwentyFourHours(false);
|
||||
SetUpTimeTable(rulePart.GetTimes(), tt);
|
||||
}
|
||||
|
||||
bool const appended = p.index == 0 ? tts.Replace(tt, 0) : tts.Append(tt);
|
||||
if (!appended)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace editor
|
||||
|
|
|
@ -9,6 +9,6 @@ class OpeningHours;
|
|||
|
||||
namespace editor
|
||||
{
|
||||
osmoh::OpeningHours ConvertOpeningHours(ui::TimeTableSet const & tt);
|
||||
ui::TimeTableSet ConvertOpeningHours(osmoh::OpeningHours const & oh);
|
||||
osmoh::OpeningHours ConvertOpeningHours(ui::TimeTableSet const & tts);
|
||||
bool ConvertOpeningHours(osmoh::OpeningHours const & oh, ui::TimeTableSet & tts);
|
||||
} // namespace editor
|
||||
|
|
Loading…
Add table
Reference in a new issue