7#include "mapcsselementstate.h"
8#include "mapcssselector_p.h"
9#include "mapcsscondition_p.h"
10#include "mapcssresult.h"
11#include "mapcssstate_p.h"
21MapCSSSelector::MapCSSSelector() =
default;
22MapCSSSelector::~MapCSSSelector() =
default;
24MapCSSBasicSelector::MapCSSBasicSelector() =
default;
25MapCSSBasicSelector::~MapCSSBasicSelector() =
default;
27void MapCSSBasicSelector::compile(
const OSM::DataSet &dataSet)
29 for (
const auto &c : conditions) {
34bool MapCSSBasicSelector::matches(
const MapCSSState &state,
MapCSSResult &result,
const std::vector<std::unique_ptr<MapCSSDeclaration>> &declarations)
const
37 switch (m_objectType) {
38 case MapCSSObjectType::Node:
if (state.element.type() != OSM::Type::Node)
return false;
break;
39 case MapCSSObjectType::Way:
if (state.element.type() != OSM::Type::Way)
return false;
break;
40 case MapCSSObjectType::Relation:
if (state.element.type() != OSM::Type::Relation)
return false;
break;
41 case MapCSSObjectType::Area:
if (state.objectType !=MapCSSObjectType::Area && state.objectType != MapCSSObjectType::LineOrArea)
return false;
break;
42 case MapCSSObjectType::Line:
if (state.objectType !=MapCSSObjectType::Line && state.objectType != MapCSSObjectType::LineOrArea)
return false;
break;
43 case MapCSSObjectType::Canvas:
return false;
44 case MapCSSObjectType::Any:
break;
45 case MapCSSObjectType::LineOrArea: Q_UNREACHABLE();
49 if (m_zoomLow > 0 && state.zoomLevel < m_zoomLow) {
52 if (m_zoomHigh > 0 && state.zoomLevel >= m_zoomHigh) {
56 if (!m_class.isNull() && !result[m_layer].hasClass(m_class)) {
60 if (m_elementState && (state.state & m_elementState) == 0) {
64 if (std::all_of(conditions.begin(), conditions.end(), [&state](
const auto &cond) { return cond->matches(state); })) {
65 result.applyDeclarations(m_layer, declarations);
71bool MapCSSBasicSelector::matchesCanvas(
const MapCSSState &state)
const
73 if (m_objectType != MapCSSObjectType::Canvas) {
77 if (m_zoomLow > 0 && state.zoomLevel < m_zoomLow) {
80 if (m_zoomHigh > 0 && state.zoomLevel >= m_zoomHigh) {
84 return std::all_of(conditions.begin(), conditions.end(), [&state](
const auto &cond) { return cond->matchesCanvas(state); });
87LayerSelectorKey MapCSSBasicSelector::layerSelector()
const
94 MapCSSObjectType type;
95}
static constexpr const object_type_map[] = {
96 {
"node", MapCSSObjectType::Node },
97 {
"way", MapCSSObjectType::Way },
98 {
"relation", MapCSSObjectType::Relation },
99 {
"area", MapCSSObjectType::Area },
100 {
"line", MapCSSObjectType::Line },
101 {
"canvas", MapCSSObjectType::Canvas },
102 {
"*", MapCSSObjectType::Any },
105void MapCSSBasicSelector::write(
QIODevice *out)
const
107 for (
const auto &t : object_type_map) {
108 if (m_objectType == t.type) {
114 if (!m_class.isNull()) {
116 out->
write(m_class.name());
119 if (m_zoomLow > 0 || m_zoomHigh > 0) {
121 if (m_zoomLow == m_zoomHigh) {
128 if (m_zoomHigh > 0) {
134 for (
const auto &cond : conditions) {
138 if (m_elementState & MapCSSElementState::Active) {
139 out->
write(
":active");
141 if (m_elementState & MapCSSElementState::Hovered) {
142 out->
write(
":hovered");
145 if (!m_layer.isNull()) {
147 out->
write(m_layer.name());
151void MapCSSBasicSelector::setObjectType(
const char *str, std::size_t len)
153 for (
const auto &t : object_type_map) {
154 if (std::strncmp(t.name, str, std::max(std::strlen(t.name), len)) == 0) {
155 m_objectType = t.type;
161void MapCSSBasicSelector::setZoomRange(
int low,
int high)
167void MapCSSBasicSelector::setConditions(MapCSSConditionHolder *conds)
172 conditions = std::move(conds->conditions);
176void MapCSSBasicSelector::setClass(ClassSelectorKey key)
181void MapCSSBasicSelector::setPseudoClass(
const char *str, std::size_t len)
183 if (std::strncmp(str,
"active", len) == 0) {
184 m_elementState |= MapCSSElementState::Active;
185 }
else if (std::strncmp(str,
"hovered", len) == 0) {
186 m_elementState |= MapCSSElementState::Hovered;
188 qWarning() <<
"Unhandled pseudo class:" <<
QByteArrayView(str, (qsizetype)len);
192void MapCSSBasicSelector::setLayer(LayerSelectorKey key)
198void MapCSSChainedSelector::compile(
const OSM::DataSet &dataSet)
200 for (
const auto &s : selectors) {
205bool MapCSSChainedSelector::matches([[maybe_unused]]
const MapCSSState &state, [[maybe_unused]]
MapCSSResult &result,
206 [[maybe_unused]]
const std::vector<std::unique_ptr<MapCSSDeclaration>> &declarations)
const
212bool MapCSSChainedSelector::matchesCanvas(
const MapCSSState &state)
const
219LayerSelectorKey MapCSSChainedSelector::layerSelector()
const
221 return selectors.back()->layerSelector();
224void MapCSSChainedSelector::write(
QIODevice *out)
const
226 assert(selectors.size() > 1);
227 selectors[0]->write(out);
228 for (
auto it = std::next(selectors.begin()); it != selectors.end(); ++it) {
235MapCSSUnionSelector::MapCSSUnionSelector() =
default;
236MapCSSUnionSelector::~MapCSSUnionSelector() =
default;
238void MapCSSUnionSelector::compile(
const OSM::DataSet &dataSet)
240 for (
const auto &ls : m_selectors) {
241 for (
const auto &s : ls.selectors) {
247bool MapCSSUnionSelector::matches(
const MapCSSState &state,
MapCSSResult &result,
const std::vector<std::unique_ptr<MapCSSDeclaration>> &declarations)
const
250 for (
const auto &ls : m_selectors) {
251 if (std::any_of(ls.selectors.begin(), ls.selectors.end(), [&state, &result, &declarations](
const auto &selector) {
252 return selector->matches(state, result, declarations);
262bool MapCSSUnionSelector::matchesCanvas(
const MapCSSState &state)
const
264 for (
const auto &ls : m_selectors) {
265 if (ls.layer.isNull()) {
266 return std::any_of(ls.selectors.begin(), ls.selectors.end(), [&state](
const auto &selector) { return selector->matchesCanvas(state); });
272LayerSelectorKey MapCSSUnionSelector::layerSelector()
const
277void MapCSSUnionSelector::write(
QIODevice *out)
const
279 for (std::size_t i = 0; i < m_selectors.size(); ++i) {
280 for (std::size_t j = 0; j < m_selectors[i].selectors.size(); ++j) {
281 if (i != 0 || j != 0) {
284 m_selectors[i].selectors[j]->write(out);
289void MapCSSUnionSelector::addSelector(std::unique_ptr<MapCSSSelector> &&selector)
291 auto it = std::find_if(m_selectors.begin(), m_selectors.end(), [&selector](
const auto &ls) {
292 return ls.layer == selector->layerSelector();
294 if (it != m_selectors.end()) {
295 (*it).selectors.push_back(std::move(selector));
298 ls.layer = selector->layerSelector();
299 ls.selectors.push_back(std::move(selector));
300 m_selectors.push_back(std::move(ls));
Result of MapCSS stylesheet evaluation for all layer selectors.
A set of nodes, ways and relations.
OSM-based multi-floor indoor maps for buildings.
QByteArray number(double n, char format, int precision)
qint64 write(const QByteArray &data)