realtimeequipmentmodel.cpp 4.47 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
    SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#include "realtimeequipmentmodel.h"

#include <KPublicTransport/Equipment>
#include <KPublicTransport/Location>
#include <KPublicTransport/LocationQueryModel>

#include <QAbstractItemModel>

using namespace KOSMIndoorMap;

RealtimeEquipmentModel::RealtimeEquipmentModel(QObject *parent)
    : EquipmentModel(parent)
{
}

RealtimeEquipmentModel::~RealtimeEquipmentModel() = default;

QObject* RealtimeEquipmentModel::realtimeModel() const
{
    return m_realtimeModel;
}

void RealtimeEquipmentModel::setRealtimeModel(QObject *model)
{
    if (m_realtimeModel == model) {
        return;
    }

    m_realtimeModel = qobject_cast<QAbstractItemModel*>(model);
    emit realtimeModelChanged();

    if (m_realtimeModel) {
        connect(m_realtimeModel, &QAbstractItemModel::modelReset, this, &RealtimeEquipmentModel::updateRealtimeState);
40
41
42
43
44
45
46
47
48
49
50
51
52
53
        connect(m_realtimeModel, &QAbstractItemModel::rowsInserted, this, [this](const auto &parent, auto first, auto last) {
            if (parent.isValid() || m_pendingRealtimeUpdate) {
                return;
            }
            for (auto i = first; i <= last; ++i) {
                const auto idx = m_realtimeModel->index(i, 0);
                const auto loc = idx.data(KPublicTransport::LocationQueryModel::LocationRole).template value<KPublicTransport::Location>();
                if (loc.type() == KPublicTransport::Location::Equipment) {
                    m_pendingRealtimeUpdate = true;
                    QMetaObject::invokeMethod(this, &RealtimeEquipmentModel::updateRealtimeState, Qt::QueuedConnection);
                    return;
                }
            }
        });
54
        connect(m_realtimeModel, &QAbstractItemModel::rowsRemoved, this, &RealtimeEquipmentModel::updateRealtimeState);
55
56
57
58
59
60
61
62
63
64
65
66
67
68
        connect(m_realtimeModel, &QAbstractItemModel::dataChanged, this, [this](const auto &fromIdx, const auto &toIdx) {
            if (m_pendingRealtimeUpdate) {
                return;
            }
            for (auto i = fromIdx.row(); i <= toIdx.row(); ++i) {
                const auto idx = m_realtimeModel->index(i, 0);
                const auto loc = idx.data(KPublicTransport::LocationQueryModel::LocationRole).template value<KPublicTransport::Location>();
                if (loc.type() == KPublicTransport::Location::Equipment) {
                    m_pendingRealtimeUpdate = true;
                    QMetaObject::invokeMethod(this, &RealtimeEquipmentModel::updateRealtimeState, Qt::QueuedConnection);
                    return;
                }
            }
        });
69
70
71
72
73
74
75
76
77

        if (m_realtimeModel->rowCount() > 0) {
            updateRealtimeState();
        }
    }
}

void RealtimeEquipmentModel::updateRealtimeState()
{
78
    m_pendingRealtimeUpdate = false;
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    if (!m_realtimeModel) {
        return;
    }

    for (auto i = 0; i < m_realtimeModel->rowCount(); ++i) {
        const auto idx = m_realtimeModel->index(i, 0);
        const auto loc = idx.data(KPublicTransport::LocationQueryModel::LocationRole).value<KPublicTransport::Location>();
        if (loc.type() != KPublicTransport::Location::Equipment) {
            continue;
        }

        const auto rtEq = loc.equipment();
        qDebug() << "trying to match equipment" << loc.name() << rtEq.type() << rtEq.disruptionEffect();
        auto eqIdx = std::numeric_limits<std::size_t>::max();
        for (std::size_t j = 0; j < m_equipment.size(); ++j) {
            const auto &eq = m_equipment[j];
            if (eq.distanceTo(m_data.dataSet(), loc.latitude(), loc.longitude()) < 2.0) {
                if (eqIdx < m_equipment.size()) {
                    qDebug() << "  multiple hits for equipment!" << loc.name();
                    eqIdx = std::numeric_limits<std::size_t>::max();
                    break;
                } else {
                    eqIdx = j;
                }
            }
        }

        if (eqIdx < m_equipment.size()) {
            qDebug() << "  found equipment!" << loc.name();
            auto &eq = m_equipment[eqIdx];
            if (!eq.syntheticElement) {
                eq.syntheticElement = OSM::copy_element(eq.sourceElements[0]);
                eq.syntheticElement.setTagValue(m_tagKeys.mxoid, QByteArray::number((qlonglong)eq.sourceElements[0].id()));
            }

            eq.syntheticElement.setTagValue(m_tagKeys.realtimeStatus, rtEq.disruptionEffect() == KPublicTransport::Disruption::NoService ? "0" : "1");
        }
    }

    emit update();
}