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_elementState && (state.state & m_elementState) == 0) {
60 auto &resultLayer = result[m_layer];
61 if (!m_class.isNull() && !resultLayer.hasClass(m_class)) {
65 if (std::all_of(conditions.begin(), conditions.end(), [&state, &resultLayer](
const auto &cond) { return cond->matches(state, resultLayer); })) {
66 resultLayer.applyDeclarations(declarations);
72bool MapCSSBasicSelector::matchesCanvas(
const MapCSSState &state)
const
74 if (m_objectType != MapCSSObjectType::Canvas) {
78 if (m_zoomLow > 0 && state.zoomLevel < m_zoomLow) {
81 if (m_zoomHigh > 0 && state.zoomLevel >= m_zoomHigh) {
85 return std::all_of(conditions.begin(), conditions.end(), [&state](
const auto &cond) { return cond->matchesCanvas(state); });
88LayerSelectorKey MapCSSBasicSelector::layerSelector()
const
95 MapCSSObjectType type;
96}
static constexpr const object_type_map[] = {
97 {
"node", MapCSSObjectType::Node },
98 {
"way", MapCSSObjectType::Way },
99 {
"relation", MapCSSObjectType::Relation },
100 {
"area", MapCSSObjectType::Area },
101 {
"line", MapCSSObjectType::Line },
102 {
"canvas", MapCSSObjectType::Canvas },
103 {
"*", MapCSSObjectType::Any },
106void MapCSSBasicSelector::write(
QIODevice *out)
const
108 for (
const auto &t : object_type_map) {
109 if (m_objectType == t.type) {
115 if (!m_class.isNull()) {
117 out->
write(m_class.name());
120 if (m_zoomLow > 0 || m_zoomHigh > 0) {
122 if (m_zoomLow == m_zoomHigh) {
129 if (m_zoomHigh > 0) {
135 for (
const auto &cond : conditions) {
139 if (m_elementState & MapCSSElementState::Active) {
140 out->
write(
":active");
142 if (m_elementState & MapCSSElementState::Hovered) {
143 out->
write(
":hovered");
146 if (!m_layer.isNull()) {
148 out->
write(m_layer.name());
152void MapCSSBasicSelector::setObjectType(
const char *str, std::size_t len)
154 for (
const auto &t : object_type_map) {
155 if (std::strncmp(t.name, str, std::max(std::strlen(t.name), len)) == 0) {
156 m_objectType = t.type;
162void MapCSSBasicSelector::setZoomRange(
int low,
int high)
168void MapCSSBasicSelector::setConditions(MapCSSConditionHolder *conds)
173 conditions = std::move(conds->conditions);
177void MapCSSBasicSelector::setClass(ClassSelectorKey key)
182void MapCSSBasicSelector::setPseudoClass(
const char *str, std::size_t len)
184 if (std::strncmp(str,
"active", len) == 0) {
185 m_elementState |= MapCSSElementState::Active;
186 }
else if (std::strncmp(str,
"hovered", len) == 0) {
187 m_elementState |= MapCSSElementState::Hovered;
189 qWarning() <<
"Unhandled pseudo class:" <<
QByteArrayView(str, (qsizetype)len);
193void MapCSSBasicSelector::setLayer(LayerSelectorKey key)
199void MapCSSChainedSelector::compile(
const OSM::DataSet &dataSet)
201 for (
const auto &s : selectors) {
206bool MapCSSChainedSelector::matches([[maybe_unused]]
const MapCSSState &state, [[maybe_unused]]
MapCSSResult &result,
207 [[maybe_unused]]
const std::vector<std::unique_ptr<MapCSSDeclaration>> &declarations)
const
213bool MapCSSChainedSelector::matchesCanvas(
const MapCSSState &state)
const
220LayerSelectorKey MapCSSChainedSelector::layerSelector()
const
222 return selectors.back()->layerSelector();
225void MapCSSChainedSelector::write(
QIODevice *out)
const
227 assert(selectors.size() > 1);
228 selectors[0]->write(out);
229 for (
auto it = std::next(selectors.begin()); it != selectors.end(); ++it) {
236MapCSSUnionSelector::MapCSSUnionSelector() =
default;
237MapCSSUnionSelector::~MapCSSUnionSelector() =
default;
239void MapCSSUnionSelector::compile(
const OSM::DataSet &dataSet)
241 for (
const auto &ls : m_selectors) {
242 for (
const auto &s : ls.selectors) {
248bool MapCSSUnionSelector::matches(
const MapCSSState &state,
MapCSSResult &result,
const std::vector<std::unique_ptr<MapCSSDeclaration>> &declarations)
const
251 for (
const auto &ls : m_selectors) {
252 if (std::any_of(ls.selectors.begin(), ls.selectors.end(), [&state, &result, &declarations](
const auto &selector) {
253 return selector->matches(state, result, declarations);
263bool MapCSSUnionSelector::matchesCanvas(
const MapCSSState &state)
const
265 for (
const auto &ls : m_selectors) {
266 if (ls.layer.isNull()) {
267 return std::any_of(ls.selectors.begin(), ls.selectors.end(), [&state](
const auto &selector) { return selector->matchesCanvas(state); });
273LayerSelectorKey MapCSSUnionSelector::layerSelector()
const
278void MapCSSUnionSelector::write(
QIODevice *out)
const
280 for (std::size_t i = 0; i < m_selectors.size(); ++i) {
281 for (std::size_t j = 0; j < m_selectors[i].selectors.size(); ++j) {
282 if (i != 0 || j != 0) {
285 m_selectors[i].selectors[j]->write(out);
290void MapCSSUnionSelector::addSelector(std::unique_ptr<MapCSSSelector> &&selector)
292 auto it = std::find_if(m_selectors.begin(), m_selectors.end(), [&selector](
const auto &ls) {
293 return ls.layer == selector->layerSelector();
295 if (it != m_selectors.end()) {
296 (*it).selectors.push_back(std::move(selector));
299 ls.layer = selector->layerSelector();
300 ls.selectors.push_back(std::move(selector));
301 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)