File indexing completed on 2024-12-22 04:27:02

0001 /*
0002     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "openinghourscache_p.h"
0008 #include "logging.h"
0009 
0010 #include <KOpeningHours/Interval>
0011 #include <KOpeningHours/OpeningHours>
0012 
0013 #include <QTimeZone>
0014 
0015 using namespace KOSMIndoorMap;
0016 
0017 OpeningHoursCache::OpeningHoursCache()
0018 {
0019     setTimeRange({}, {});
0020 }
0021 
0022 OpeningHoursCache::~OpeningHoursCache() = default;
0023 
0024 void OpeningHoursCache::setMapData(const MapData &mapData)
0025 {
0026     if (m_mapData == mapData) {
0027         return;
0028     }
0029     m_mapData = mapData;
0030     m_cacheEntries.clear();
0031 }
0032 
0033 void OpeningHoursCache::setTimeRange(const QDateTime &begin, const QDateTime &end)
0034 {
0035     const auto actualBegin = begin.isValid() ? begin : QDateTime::currentDateTime();
0036     const auto actualEnd = (end.isValid() && end > m_begin) ? end : actualBegin.addYears(1);
0037 
0038     if (actualBegin == m_begin && actualEnd == m_end) {
0039         return;
0040     }
0041 
0042     m_begin = actualBegin;
0043     m_end = actualEnd;
0044     m_cacheEntries.clear();
0045 }
0046 
0047 bool OpeningHoursCache::isClosed(OSM::Element elem, const QByteArray &oh)
0048 {
0049     const auto key = elem.id();
0050     const auto it = std::lower_bound(m_cacheEntries.begin(), m_cacheEntries.end(), key, [](auto lhs, auto rhs) {
0051         return lhs.key < rhs;
0052     });
0053     if (it != m_cacheEntries.end() && (*it).key == key) {
0054         return (*it).closed;
0055     }
0056 
0057     bool closed = false;
0058 
0059     KOpeningHours::OpeningHours expr(oh, KOpeningHours::OpeningHours::IntervalMode);
0060     expr.setLocation(elem.center().latF(), elem.center().lonF());
0061     expr.setRegion(m_mapData.regionCode());
0062     expr.setTimeZone(m_mapData.timeZone());
0063 
0064     if (expr.error() != KOpeningHours::OpeningHours::NoError) {
0065         qCDebug(Log) << "opening hours expression error:" << expr.error() << oh << elem.url();
0066     } else {
0067         auto i = expr.interval(m_begin);
0068         while (i.state() == KOpeningHours::Interval::Closed && !i.hasOpenEnd() && (i.end() < m_end || !m_end.isValid())) {
0069             i = expr.nextInterval(i);
0070         }
0071         if (expr.error() != KOpeningHours::OpeningHours::NoError) {
0072             qCDebug(Log) << "opening hours expression runtime error:" << expr.error() << oh << i << elem.url();
0073         }
0074         closed = i.state() == KOpeningHours::Interval::Closed;
0075     }
0076     m_cacheEntries.insert(it, {key, closed});
0077     return closed;
0078 }