7#include "mapcssresult.h"
8#include "mapcssdeclaration_p.h"
10#include <osm/datatypes.h>
17class MapCSSResultLayerPrivate {
19 std::vector<const MapCSSDeclaration*> m_declarations;
20 std::vector<ClassSelectorKey> m_classes;
21 std::vector<OSM::Tag> m_tags;
22 LayerSelectorKey m_layer;
27MapCSSResultLayer::MapCSSResultLayer()
28 : d(new MapCSSResultLayerPrivate)
37 d->m_declarations.clear();
40 d->m_flags = MapCSSDeclaration::NoFlag;
46 return d->m_flags & MapCSSDeclaration::AreaProperty;
51 return d->m_flags & MapCSSDeclaration::LineProperty;
56 return d->m_flags & MapCSSDeclaration::LabelProperty;
61 return d->m_flags & MapCSSDeclaration::ExtrudeProperty;
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;
69 if (it == d->m_declarations.end() || (*it)->property() != prop) {
77 return d->m_declarations;
80void MapCSSResultLayer::addDeclaration(
const MapCSSDeclaration *decl)
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();
85 if (it == d->m_declarations.end() || (*it)->property() != decl->property()) {
86 d->m_declarations.insert(it, decl);
91 d->m_flags |= decl->propertyFlags();
94void MapCSSResultLayer::addClass(ClassSelectorKey cls)
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);
104 return std::binary_search(d->m_classes.begin(), d->m_classes.end(), cls);
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) {
121void MapCSSResultLayer::setLayerSelector(LayerSelectorKey layer)
126void MapCSSResultLayer::setTag(
OSM::Tag &&tag)
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));
132 (*it) = std::move(tag);
138class MapCSSResultPrivate {
140 std::vector<MapCSSResultLayer> m_results;
141 std::vector<MapCSSResultLayer> m_inactivePool;
145MapCSSResult::MapCSSResult()
146 : d(new MapCSSResultPrivate)
150MapCSSResult::MapCSSResult(
MapCSSResult&&) noexcept = default;
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));
168 const auto it = std::find_if(d->m_results.begin(), d->m_results.end(), [layer](
const auto &res) {
169 return res.layerSelector() == layer;
171 if (it != d->m_results.end()) {
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));
182 res.setLayerSelector(layer);
183 d->m_results.push_back(std::move(res));
185 return d->m_results.back();
190 const auto it = std::find_if(d->m_results.begin(), d->m_results.end(), [layer](
const auto &res) {
191 return res.layerSelector() == layer;
193 if (it != d->m_results.end()) {
197 if (d->m_inactivePool.empty()) {
198 d->m_inactivePool.emplace_back();
200 return d->m_inactivePool.back();
203void MapCSSResult::applyDeclarations(LayerSelectorKey layer,
const std::vector<std::unique_ptr<MapCSSDeclaration>> &declarations)
205 auto &result = (*this)[layer];
206 for (
const auto &decl : declarations) {
207 switch (decl->type()) {
208 case MapCSSDeclaration::PropertyDeclaration:
209 result.addDeclaration(decl.get());
211 case MapCSSDeclaration::ClassDeclaration:
212 result.addClass(decl->classSelectorKey());
214 case MapCSSDeclaration::TagDeclaration:
215 if (!std::isnan(decl->doubleValue())) {
218 result.setTag(
OSM::Tag{decl->tagKey(), decl->stringValue().toUtf8()});
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.
OSM-based multi-floor indoor maps for buildings.
MapCSSProperty
Known properties in MapCSS declarations.
QByteArray number(double n, char format, int precision)