KOSMIndoorMap

gatemodel.cpp
1/*
2 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "gatemodel.h"
8
9#include <QCollator>
10#include <QDebug>
11#include <QPointF>
12
13using namespace KOSMIndoorMap;
14
15GateModel::GateModel(QObject *parent)
16 : QAbstractListModel(parent)
17{
18}
19
20GateModel::~GateModel() = default;
21
22MapData GateModel::mapData() const
23{
24 return m_data;
25}
26
27void GateModel::setMapData(const MapData &data)
28{
29 if (m_data == data) {
30 return;
31 }
32
34 m_gates.clear();
35 m_data = data;
36 if (!m_data.isEmpty()) {
37 m_tagKeys.mxArrival = m_data.dataSet().makeTagKey("mx:arrival");
38 m_tagKeys.mxDeparture = m_data.dataSet().makeTagKey("mx:departure");
39 populateModel();
40 }
42 Q_EMIT mapDataChanged();
43 matchGates();
44}
45
46bool GateModel::isEmpty() const
47{
48 return rowCount() == 0;
49}
50
51int GateModel::rowCount(const QModelIndex &parent) const
52{
53 if (parent.isValid()) {
54 return 0;
55 }
56
57 return m_gates.size();
58}
59
60QVariant GateModel::data(const QModelIndex &index, int role) const
61{
62 if (!index.isValid()) {
63 return {};
64 }
65
66 const auto &gate = m_gates[index.row()];
67 switch (role) {
68 case Qt::DisplayRole:
69 return gate.name;
70 case CoordinateRole:
71 return QPointF(gate.node.coordinate.lonF(), gate.node.coordinate.latF());
72 case ElementRole:
73 return QVariant::fromValue(OSM::Element(&gate.node));
74 case LevelRole:
75 return gate.level;
76 case ArrivalGateRole:
77 return index.row() == m_arrivalGateRow;
78 case DepartureGateRole:
79 return index.row() == m_departureGateRow;
80 case HiddenElementRole:
81 return QVariant::fromValue(gate.sourceElement);
82 }
83
84 return {};
85}
86
87QHash<int, QByteArray> GateModel::roleNames() const
88{
90 n.insert(CoordinateRole, "coordinate");
91 n.insert(ElementRole, "osmElement");
92 n.insert(LevelRole, "level");
93 n.insert(ArrivalGateRole, "isArrivalGate");
94 n.insert(DepartureGateRole, "isDepartureGate");
95 n.insert(HiddenElementRole, "hiddenElement");
96 return n;
97}
98
99void GateModel::populateModel()
100{
101 const auto aerowayKey = m_data.dataSet().tagKey("aeroway");
102 if (aerowayKey.isNull()) { // not looking at an airport at all here
103 return;
104 }
105
106 for (auto it = m_data.levelMap().begin(); it != m_data.levelMap().end(); ++it) {
107 for (const auto &e : (*it).second) {
108 if (e.type() != OSM::Type::Node || e.tagValue(aerowayKey) != "gate") {
109 continue;
110 }
111
112 const auto l = e.tagValue("ref").split(';');
113 for (const auto &n : l) {
114 if (n.isEmpty()) {
115 continue;
116 }
117
118 Gate gate;
119 gate.name = QString::fromUtf8(n);
120 gate.sourceElement = e;
121 gate.node = *e.node();
122 gate.node.id = m_data.dataSet().nextInternalId();
123 OSM::setTagValue(gate.node, m_data.dataSet().tagKey("name"), gate.name.toUtf8());
124 gate.level = (*it).first.numericLevel();
125 m_gates.push_back(gate);
126 }
127 }
128 }
129
130 QCollator c{QLocale()};
131 c.setNumericMode(true);
132 c.setIgnorePunctuation(true);
133 c.setCaseSensitivity(Qt::CaseInsensitive);
134 std::sort(m_gates.begin(), m_gates.end(), [&c](const auto &lhs, const auto &rhs) {
135 return c.compare(lhs.name, rhs.name) < 0;
136 });
137
138 qDebug() << m_gates.size() << "gates found";
139}
140
142{
143 m_arrivalGate = name;
144 matchGates();
145}
146
147void GateModel::setDepartureGate(const QString &name)
148{
149 m_departureGate = name;
150 matchGates();
151}
152
154{
155 return m_arrivalGateRow;
156}
157
158int GateModel::departureGateRow() const
159{
160 return m_departureGateRow;
161}
162
163void GateModel::matchGates()
164{
165 setGateTag(m_arrivalGateRow, m_tagKeys.mxArrival, false);
166 m_arrivalGateRow = matchGate(m_arrivalGate);
167 setGateTag(m_arrivalGateRow, m_tagKeys.mxArrival, true);
168
169 setGateTag(m_departureGateRow, m_tagKeys.mxDeparture, false);
170 m_departureGateRow = matchGate(m_departureGate);
171 setGateTag(m_departureGateRow, m_tagKeys.mxDeparture, true);
172
173 Q_EMIT gateIndexChanged();
174 if (m_arrivalGateRow >= 0) {
175 Q_EMIT dataChanged(index(m_arrivalGateRow, 0), index(m_arrivalGateRow, 0));
176 }
177 if (m_departureGateRow >= 0) {
178 Q_EMIT dataChanged(index(m_departureGateRow, 0), index(m_departureGateRow, 0));
179 }
180}
181
182int GateModel::matchGate(const QString &name) const
183{
184 if (name.isEmpty()) {
185 return -1;
186 }
187
188 int i = 0;
189 for (const auto &g : m_gates) {
190 if (g.name == name) {
191 return i;
192 }
193 ++i;
194 }
195
196 return -1;
197}
198
199void GateModel::setGateTag(int idx, OSM::TagKey key, bool enabled)
200{
201 if (idx < 0) {
202 return;
203 }
204
205 OSM::setTagValue(m_gates[idx].node, key, enabled ? "1" : "0");
206}
207
208#include "moc_gatemodel.cpp"
Q_INVOKABLE void setArrivalGate(const QString &name)
Match arrival/departure gates against what we found in the map data.
int arrivalGateRow
Row indexes of the matched arrival/departure gates, if found and/or set, otherwise -1.
Definition gatemodel.h:40
Raw OSM map data, separated by levels.
Definition mapdata.h:60
TagKey tagKey(const char *keyName) const
Look up a tag key for the given tag name, if it exists.
Definition datatypes.cpp:27
Id nextInternalId() const
Create a unique id for internal use (ie.
TagKey makeTagKey(const char *keyName, StringMemory keyMemOpt=StringMemory::Transient)
Create a tag key for the given tag name.
Definition datatypes.cpp:17
A reference to any of OSM::Node/OSM::Way/OSM::Relation.
Definition element.h:24
A key of an OSM tag.
Definition datatypes.h:179
OSM-based multi-floor indoor maps for buildings.
void setTagValue(Elem &elem, TagKey key, QByteArray &&value)
Inserts a new tag, or updates an existing one.
Definition datatypes.h:484
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
virtual QHash< int, QByteArray > roleNames() const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
bool isValid() const const
int row() const const
Q_EMITQ_EMIT
QObject * parent() const const
QString fromUtf8(QByteArrayView str)
QByteArray toUtf8() const const
CaseInsensitive
DisplayRole
QVariant fromValue(T &&value)
An airport gate.
Definition gatemodel.h:21
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:03 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.