KOSMIndoorMap

gatemodel.cpp
1 /*
2  SPDX-FileCopyrightText: 2020 Volker Krause <[email protected]>
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 
13 using namespace KOSMIndoorMap;
14 
15 GateModel::GateModel(QObject *parent)
16  : QAbstractListModel(parent)
17 {
18 }
19 
20 GateModel::~GateModel() = default;
21 
22 MapData GateModel::mapData() const
23 {
24  return m_data;
25 }
26 
27 void 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  }
41  endResetModel();
42  Q_EMIT mapDataChanged();
43  matchGates();
44 }
45 
46 bool GateModel::isEmpty() const
47 {
48  return rowCount() == 0;
49 }
50 
51 int GateModel::rowCount(const QModelIndex &parent) const
52 {
53  if (parent.isValid()) {
54  return 0;
55  }
56 
57  return m_gates.size();
58 }
59 
60 QVariant 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 
87 QHash<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 
99 void 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"), "TODO");
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 
147 void GateModel::setDepartureGate(const QString &name)
148 {
149  m_departureGate = name;
150  matchGates();
151 }
152 
153 int GateModel::arrivalGateRow() const
154 {
155  return m_arrivalGateRow;
156 }
157 
158 int GateModel::departureGateRow() const
159 {
160  return m_departureGateRow;
161 }
162 
163 void 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 
182 int 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 
199 void 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 }
OSM-based multi-floor indoor maps for buildings.
virtual QHash< int, QByteArray > roleNames() const const
Q_INVOKABLE void setArrivalGate(const QString &name)
Match arrival/departure gates against what we found in the map data.
Definition: gatemodel.cpp:141
Q_INVOKABLE QString name(int level) const
Returns the name for the floor level.
bool isValid() const const
An airport gate.
Definition: gatemodel.h:21
A reference to any of OSM::Node/OSMWay/OSMRelation.
Definition: element.h:22
QString fromUtf8(const char *str, int size)
A key of an OSM tag.
Definition: datatypes.h:179
void setTagValue(Elem &elem, TagKey key, const QByteArray &value)
Inserts a new tag, or updates an existing one.
Definition: datatypes.h:433
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
CaseInsensitive
DisplayRole
bool isEmpty() const const
Raw OSM map data, separated by levels.
Definition: mapdata.h:59
int row() const const
QVariant fromValue(const T &value)
TagKey makeTagKey(const char *keyName, StringMemory keyMemOpt=StringMemory::Transient)
Create a tag key for the given tag name.
Definition: datatypes.cpp:17
QObject * parent() const const
Q_EMITQ_EMIT
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:03:45 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.