KOSMIndoorMap

mapcssresult.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 "mapcssresult.h"
8#include "mapcssdeclaration_p.h"
9
10#include <osm/datatypes.h>
11
12#include <algorithm>
13
14using namespace KOSMIndoorMap;
15
16namespace KOSMIndoorMap {
17class MapCSSResultLayerPrivate {
18public:
19 std::vector<const MapCSSDeclaration*> m_declarations;
20 std::vector<ClassSelectorKey> m_classes;
21 std::vector<OSM::Tag> m_tags;
22 LayerSelectorKey m_layer;
23 int m_flags = 0;
24};
25}
26
27MapCSSResultLayer::MapCSSResultLayer()
28 : d(new MapCSSResultLayerPrivate)
29{
30}
31MapCSSResultLayer::MapCSSResultLayer(MapCSSResultLayer&&) noexcept = default;
32MapCSSResultLayer& MapCSSResultLayer::operator=(MapCSSResultLayer&&) noexcept = default;
34
35void MapCSSResultLayer::clear()
36{
37 d->m_declarations.clear();
38 d->m_classes.clear();
39 d->m_tags.clear();
40 d->m_flags = MapCSSDeclaration::NoFlag;
41 d->m_layer = {};
42}
43
45{
46 return d->m_flags & MapCSSDeclaration::AreaProperty;
47}
48
50{
51 return d->m_flags & MapCSSDeclaration::LineProperty;
52}
53
55{
56 return d->m_flags & MapCSSDeclaration::LabelProperty;
57}
58
60{
61 return d->m_flags & MapCSSDeclaration::ExtrudeProperty;
62}
63
64const MapCSSDeclaration* MapCSSResultLayer::declaration(MapCSSProperty prop) const
65{
66 const auto it = std::lower_bound(d->m_declarations.begin(), d->m_declarations.end(), prop, [](auto lhs, auto rhs) {
67 return lhs->property() < rhs;
68 });
69 if (it == d->m_declarations.end() || (*it)->property() != prop) {
70 return nullptr;
71 }
72 return (*it);
73}
74
75const std::vector<const MapCSSDeclaration*>& MapCSSResultLayer::declarations() const
76{
77 return d->m_declarations;
78}
79
80void MapCSSResultLayer::addDeclaration(const MapCSSDeclaration *decl)
81{
82 const auto it = std::lower_bound(d->m_declarations.begin(), d->m_declarations.end(), decl, [](auto lhs, auto rhs) {
83 return lhs->property() < rhs->property();
84 });
85 if (it == d->m_declarations.end() || (*it)->property() != decl->property()) {
86 d->m_declarations.insert(it, decl);
87 } else {
88 (*it) = decl;
89 }
90
91 d->m_flags |= decl->propertyFlags();
92}
93
94void MapCSSResultLayer::addClass(ClassSelectorKey cls)
95{
96 const auto it = std::lower_bound(d->m_classes.begin(), d->m_classes.end(), cls);
97 if (it == d->m_classes.end() || (*it) != cls) {
98 d->m_classes.insert(it, cls);
99 }
100}
101
102bool MapCSSResultLayer::hasClass(ClassSelectorKey cls) const
103{
104 return std::binary_search(d->m_classes.begin(), d->m_classes.end(), cls);
105}
106
107LayerSelectorKey MapCSSResultLayer::layerSelector() const
108{
109 return d->m_layer;
110}
111
113{
114 const auto it = std::lower_bound(d->m_tags.begin(), d->m_tags.end(), key);
115 if (it != d->m_tags.end() && (*it).key == key) {
116 return (*it).value;
117 }
118 return {};
119}
120
121void MapCSSResultLayer::setLayerSelector(LayerSelectorKey layer)
122{
123 d->m_layer = layer;
124}
125
126void MapCSSResultLayer::setTag(OSM::Tag &&tag)
127{
128 const auto it = std::lower_bound(d->m_tags.begin(), d->m_tags.end(), tag);
129 if (it == d->m_tags.end() || (*it).key != tag.key) {
130 d->m_tags.insert(it, std::move(tag));
131 } else {
132 (*it) = std::move(tag);
133 }
134}
135
136
137namespace KOSMIndoorMap {
138class MapCSSResultPrivate {
139public:
140 std::vector<MapCSSResultLayer> m_results;
141 std::vector<MapCSSResultLayer> m_inactivePool; // for reuse of already allocated result items
142};
143}
144
145MapCSSResult::MapCSSResult()
146 : d(new MapCSSResultPrivate)
147{
148}
149
150MapCSSResult::MapCSSResult(MapCSSResult&&) noexcept = default;
151MapCSSResult::~MapCSSResult() = default;
152MapCSSResult& MapCSSResult::operator=(MapCSSResult&&) noexcept = default;
153
154void MapCSSResult::clear()
155{
156 std::move(d->m_results.begin(), d->m_results.end(), std::back_inserter(d->m_inactivePool));
157 d->m_results.clear();
158 std::for_each(d->m_inactivePool.begin(), d->m_inactivePool.end(), std::mem_fn(&MapCSSResultLayer::clear));
159}
160
161const std::vector<MapCSSResultLayer>& MapCSSResult::results() const
162{
163 return d->m_results;
164}
165
166MapCSSResultLayer& MapCSSResult::operator[](LayerSelectorKey layer)
167{
168 const auto it = std::find_if(d->m_results.begin(), d->m_results.end(), [layer](const auto &res) {
169 return res.layerSelector() == layer;
170 });
171 if (it != d->m_results.end()) {
172 return *it;
173 }
174
175 if (!d->m_inactivePool.empty()) {
176 auto res = std::move(d->m_inactivePool.back());
177 d->m_inactivePool.pop_back();
178 res.setLayerSelector(layer);
179 d->m_results.push_back(std::move(res));
180 } else {
182 res.setLayerSelector(layer);
183 d->m_results.push_back(std::move(res));
184 }
185 return d->m_results.back();
186}
187
188const MapCSSResultLayer& MapCSSResult::operator[](LayerSelectorKey layer) const
189{
190 const auto it = std::find_if(d->m_results.begin(), d->m_results.end(), [layer](const auto &res) {
191 return res.layerSelector() == layer;
192 });
193 if (it != d->m_results.end()) {
194 return *it;
195 }
196
197 if (d->m_inactivePool.empty()) {
198 d->m_inactivePool.emplace_back();
199 }
200 return d->m_inactivePool.back();
201}
202
203void MapCSSResult::applyDeclarations(LayerSelectorKey layer, const std::vector<std::unique_ptr<MapCSSDeclaration>> &declarations)
204{
205 auto &result = (*this)[layer];
206 for (const auto &decl : declarations) {
207 switch (decl->type()) {
208 case MapCSSDeclaration::PropertyDeclaration:
209 result.addDeclaration(decl.get());
210 break;
211 case MapCSSDeclaration::ClassDeclaration:
212 result.addClass(decl->classSelectorKey());
213 break;
214 case MapCSSDeclaration::TagDeclaration:
215 if (!std::isnan(decl->doubleValue())) {
216 result.setTag(OSM::Tag{decl->tagKey(), QByteArray::number(decl->doubleValue())});
217 } else {
218 result.setTag(OSM::Tag{decl->tagKey(), decl->stringValue().toUtf8()});
219 }
220 break;
221 }
222 }
223}
Result of MapCSS stylesheet evaluation for a single layer selector.
QByteArray tagValue(OSM::TagKey key) const
Tag lookup for tags overridden by the style sheet.
bool hasClass(ClassSelectorKey cls) const
Check whether this result layer has class cls set.
LayerSelectorKey layerSelector() const
The layer selector for this result.
bool hasLineProperties() const
Returns true if a way/line needs to be drawn.
bool hasLabelProperties() const
Returns true if a label needs to be drawn.
const MapCSSDeclaration * declaration(MapCSSProperty prop) const
Returns the declaration for property @prop, or nullptr is this property isn't set.
bool hasExtrudeProperties() const
Returns true if a 3D extrusion is requested.
const std::vector< const MapCSSDeclaration * > & declarations() const
The active declarations for the queried element.
bool hasAreaProperties() const
Returns true if an area/polygon needs to be drawn.
Result of MapCSS stylesheet evaluation for all layer selectors.
const MapCSSResultLayer & operator[](LayerSelectorKey layer) const
Access a specific result layer selector.
const std::vector< MapCSSResultLayer > & results() const
Results for all layer selectors.
A key of an OSM tag.
Definition datatypes.h:179
An OSM element tag.
Definition datatypes.h:182
OSM-based multi-floor indoor maps for buildings.
MapCSSProperty
Known properties in MapCSS declarations.
QByteArray number(double n, char format, int precision)
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.