void Tile::build(StyleContext& _ctx, const Scene& _scene, const TileData& _data, const DataSource& _source) { const auto& layers = _scene.layers(); _ctx.setGlobal("$zoom", m_id.z); for (auto& style : _scene.styles()) { style->onBeginBuildTile(*this); } for (const auto& datalayer : layers) { if (datalayer.source() != _source.name()) { continue; } for (const auto& collection : _data.layers) { if (!collection.name.empty() && collection.name != datalayer.collection()) { continue; } for (const auto& feat : collection.features) { _ctx.setFeature(feat); std::vector<DrawRule> rules; datalayer.match(feat, _ctx, rules); for (auto& rule : rules) { auto* style = _scene.findStyle(rule.style); if (style) { rule.eval(_ctx); style->buildFeature(*this, feat, rule); } } } } } for (auto& style : _scene.styles()) { style->onEndBuildTile(*this); } for (auto& geometry : m_geometry) { geometry.second->compileVertexBuffer(); } }
bool DrawRuleMergeSet::match(const Feature& _feature, const SceneLayer& _layer, StyleContext& _ctx) { _ctx.setFeature(_feature); m_matchedRules.clear(); m_queuedLayers.clear(); // If uber layer is marked not visible return immediately if (!_layer.visible()) { return false; } // If the first filter doesn't match, return immediately if (!_layer.filter().eval(_feature, _ctx)) { return false; } m_queuedLayers.push_back(&_layer); // Iterate depth-first over the layer hierarchy while (!m_queuedLayers.empty()) { // Pop a layer off the top of the stack const auto& layer = *m_queuedLayers.back(); m_queuedLayers.pop_back(); // Merge rules from layer into accumulated set mergeRules(layer); // Push each of the layer's matching sublayers onto the stack for (const auto& sublayer : layer.sublayers()) { // Skip matching this sublayer if marked not visible if (!sublayer.visible()) { continue; } if (sublayer.filter().eval(_feature, _ctx)) { m_queuedLayers.push_back(&sublayer); } } } return true; }