void operator() (marker_rgba8 const& mark)
    {
        using namespace mapnik::svg;
        bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
        double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
        double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
        double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);

        agg::trans_affine geom_tr;
        auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
        if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
        agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);

        setup_transform_scaling(image_tr, mark.width(), mark.height(), feature_, common_.vars_, sym_);
        auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
        if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
        box2d<double> const& bbox = mark.bounding_box();
        mapnik::image_rgba8 const& marker = mark.get_data();
        // - clamp sizes to > 4 pixels of interactivity
        coord2d center = bbox.center();
        agg::trans_affine_translation recenter(-center.x, -center.y);
        agg::trans_affine marker_trans = recenter * image_tr;
        raster_dispatch_type rasterizer_dispatch(marker,
                                                 marker_trans,
                                                 sym_,
                                                 *common_.detector_,
                                                 common_.scale_factor_,
                                                 feature_,
                                                 common_.vars_,
                                                 renderer_context_);


        vertex_converter_type converter(clip_box_,
                                        sym_,
                                        common_.t_,
                                        prj_trans_,
                                        geom_tr,
                                        feature_,
                                        common_.vars_,
                                        common_.scale_factor_);

        if (clip) // optional clip (default: true)
        {
            geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
            if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
                converter.template set<clip_poly_tag>();
            else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
                converter.template set<clip_line_tag>();
        }
        converter.template set<transform_tag>(); //always transform
        if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
        converter.template set<affine_transform_tag>(); // optional affine transform
        if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
        if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
        apply_markers_multi(feature_, common_.vars_, converter, rasterizer_dispatch, sym_);
    }
    void operator() (marker_rgba8 const& mark) const
    {
        agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);

        setup_transform_scaling(image_tr, mark.width(), mark.height(), feature_, common_.vars_, sym_);
        auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
        if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
        box2d<double> const& bbox = mark.bounding_box();
        mapnik::image_rgba8 const& marker = mark.get_data();
        // - clamp sizes to > 4 pixels of interactivity
        coord2d center = bbox.center();
        agg::trans_affine_translation recenter(-center.x, -center.y);
        agg::trans_affine marker_trans = recenter * image_tr;
        raster_dispatch_type rasterizer_dispatch(marker,
                                                 marker_trans,
                                                 sym_,
                                                 *common_.detector_,
                                                 common_.scale_factor_,
                                                 feature_,
                                                 common_.vars_,
                                                 renderer_context_);

        render_marker(mark, rasterizer_dispatch);
    }
    void operator() (marker_rgba8 const& marker) const
    {
        using color = agg::rgba8;
        using order = agg::order_rgba;
        using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
        using pattern_filter_type = agg::pattern_filter_bilinear_rgba8;
        using pattern_type = agg::line_image_pattern<pattern_filter_type>;
        using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
        using renderer_base = agg::renderer_base<pixfmt_type>;
        using renderer_type = agg::renderer_outline_image<renderer_base, pattern_type>;
        using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;

        value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
        mapnik::image_rgba8 const& image = marker.get_data();

        value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
        value_double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
        value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
        value_double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);

        agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),
                                  current_buffer_->height(), current_buffer_->row_size());
        pixfmt_type pixf(buf);
        pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
        renderer_base ren_base(pixf);
        agg::pattern_filter_bilinear_rgba8 filter;

        pattern_source source(image, opacity);
        pattern_type pattern (filter,source);
        renderer_type ren(ren_base, pattern);
        double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0);
        int rast_clip_padding = static_cast<int>(std::round(half_stroke));
        ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding);
        rasterizer_type ras(ren);

        agg::trans_affine tr;
        auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
        if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_);

        box2d<double> clip_box = clipping_extent(common_);
        if (clip)
        {
            double padding = (double)(common_.query_extent_.width()/pixmap_.width());
            if (half_stroke > 1)
                padding *= half_stroke;
            if (std::fabs(offset) > 0)
                padding *= std::fabs(offset) * 1.2;
            padding *= common_.scale_factor_;
            clip_box.pad(padding);
        }
        using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
                                                       affine_transform_tag,
                                                       simplify_tag,smooth_tag,
                                                       offset_transform_tag>;

        vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);

        if (clip) converter.set<clip_line_tag>();
        converter.set<transform_tag>(); //always transform
        if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
        if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
        converter.set<affine_transform_tag>(); // optional affine transform
        if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter

        using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer_type>;
        using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>;
        apply_vertex_converter_type apply(converter, ras);
        mapnik::util::apply_visitor(vertex_processor_type(apply), feature_.get_geometry());
    }