void feature_style_processor<Processor>::apply(double scale_denom)
{
    Processor & p = static_cast<Processor&>(*this);
    p.start_map_processing(m_);

    projection proj(m_.srs(),true);
    if (scale_denom <= 0.0)
        scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic());
    scale_denom *= p.scale_factor(); // FIXME - we might want to comment this out

    // Asynchronous query supports:
    // This is a two steps process,
    // first we setup all queries at layer level
    // in a second time, we fetch the results and
    // do the actual rendering

    // Define processing context map used by datasources
    // implementing asynchronous queries
    feature_style_context_map ctx_map;

    if (!m_.layers().empty())
    {
        layer_rendering_material root_mat(m_.layers().front(), proj);
        prepare_layers(root_mat, m_.layers(), ctx_map, p, scale_denom);

        render_submaterials(root_mat, p);
    }

    p.end_map_processing(m_);
}
void feature_style_processor<Processor>::apply_to_layer(layer const& lay,
                                                        Processor & p,
                                                        projection const& proj0,
                                                        double scale,
                                                        double scale_denom,
                                                        unsigned width,
                                                        unsigned height,
                                                        box2d<double> const& extent,
                                                        int buffer_size,
                                                        std::set<std::string>& names)
{
    feature_style_context_map ctx_map;
    layer_rendering_material  mat(lay, proj0);

    prepare_layer(mat,
                  ctx_map,
                  p,
                  scale,
                  scale_denom,
                  width,
                  height,
                  extent,
                  buffer_size,
                  names);

    prepare_layers(mat, lay.layers(), ctx_map, p, scale_denom);

    if (!mat.active_styles_.empty())
    {
        render_material(mat,p);
        render_submaterials(mat, p);
    }
}
void feature_style_processor<Processor>::render_submaterials(layer_rendering_material const & parent_mat,
                                                             Processor & p)
{
    for (layer_rendering_material const & mat : parent_mat.materials_)
    {
        if (!mat.active_styles_.empty())
        {
            p.start_layer_processing(mat.lay_, mat.layer_ext2_);

            render_material(mat, p);
            render_submaterials(mat, p);

            p.end_layer_processing(mat.lay_);
        }
    }
}