refactor render_markers_symbolizer

This commit is contained in:
Mickey Rose 2016-01-27 01:55:50 +01:00
parent 8a55eefbb5
commit f99c0e5a6f
7 changed files with 226 additions and 373 deletions

View file

@ -48,64 +48,106 @@ struct clip_poly_tag;
using svg_attribute_type = agg::pod_bvector<svg::path_attributes>;
struct markers_dispatch_params
{
// placement
markers_placement_params placement_params;
marker_placement_enum placement_method;
value_bool ignore_placement;
// rendering
bool snap_to_pixels;
double scale_factor;
value_double opacity;
markers_dispatch_params(box2d<double> const& size,
agg::trans_affine const& tr,
symbolizer_base const& sym,
feature_impl const& feature,
attributes const& vars,
double scale = 1.0,
bool snap = false)
: placement_params{
.size = size,
.tr = tr,
.spacing = get<value_double, keys::spacing>(sym, feature, vars),
.max_error = get<value_double, keys::max_error>(sym, feature, vars),
.allow_overlap = get<value_bool, keys::allow_overlap>(sym, feature, vars),
.avoid_edges = get<value_bool, keys::avoid_edges>(sym, feature, vars),
.direction = get<direction_enum, keys::direction>(sym, feature, vars)}
, placement_method(get<marker_placement_enum, keys::markers_placement_type>(sym, feature, vars))
, ignore_placement(get<value_bool, keys::ignore_placement>(sym, feature, vars))
, snap_to_pixels(snap)
, scale_factor(scale)
, opacity(get<value_double, keys::opacity>(sym, feature, vars))
{
placement_params.spacing *= scale;
}
};
struct markers_renderer_context : util::noncopyable
{
virtual void render_marker(image_rgba8 const& src,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr) = 0;
virtual void render_marker(svg_path_ptr const& src,
svg_path_adapter & path,
svg_attribute_type const& attrs,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr) = 0;
};
template <typename Detector>
struct vector_markers_dispatch : util::noncopyable
{
vector_markers_dispatch(svg_path_ptr const& src,
svg_path_adapter & path,
svg_attribute_type const& attrs,
agg::trans_affine const& marker_trans,
symbolizer_base const& sym,
Detector & detector,
double scale_factor,
feature_impl const& feature,
attributes const& vars)
: src_(src),
marker_trans_(marker_trans),
sym_(sym),
detector_(detector),
feature_(feature),
vars_(vars),
scale_factor_(scale_factor)
attributes const& vars,
bool snap_to_pixels,
markers_renderer_context & renderer_context)
: params_(src->bounding_box(), recenter(src) * marker_trans,
sym, feature, vars, scale_factor, snap_to_pixels)
, renderer_context_(renderer_context)
, src_(src)
, path_(path)
, attrs_(attrs)
, detector_(detector)
{}
virtual ~vector_markers_dispatch() {}
template <typename T>
void add_path(T & path)
{
marker_placement_enum placement_method = get<marker_placement_enum, keys::markers_placement_type>(sym_, feature_, vars_);
value_bool ignore_placement = get<value_bool, keys::ignore_placement>(sym_, feature_, vars_);
value_bool allow_overlap = get<value_bool, keys::allow_overlap>(sym_, feature_, vars_);
value_bool avoid_edges = get<value_bool, keys::avoid_edges>(sym_, feature_, vars_);
value_double opacity = get<value_double,keys::opacity>(sym_, feature_, vars_);
value_double spacing = get<value_double, keys::spacing>(sym_, feature_, vars_);
value_double max_error = get<value_double, keys::max_error>(sym_, feature_, vars_);
coord2d center = src_->bounding_box().center();
agg::trans_affine_translation recenter(-center.x, -center.y);
agg::trans_affine tr = recenter * marker_trans_;
direction_enum direction = get<direction_enum, keys::direction>(sym_, feature_, vars_);
markers_placement_params params { src_->bounding_box(), tr, spacing * scale_factor_, max_error, allow_overlap, avoid_edges, direction };
markers_placement_finder<T, Detector> placement_finder(
placement_method, path, detector_, params);
params_.placement_method, path, detector_, params_.placement_params);
double x, y, angle = .0;
while (placement_finder.get_point(x, y, angle, ignore_placement))
while (placement_finder.get_point(x, y, angle, params_.ignore_placement))
{
agg::trans_affine matrix = tr;
agg::trans_affine matrix = params_.placement_params.tr;
matrix.rotate(angle);
matrix.translate(x, y);
render_marker(matrix, opacity);
renderer_context_.render_marker(src_, path_, attrs_, params_, matrix);
}
}
virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;
protected:
static agg::trans_affine recenter(svg_path_ptr const& src)
{
coord2d center = src->bounding_box().center();
return agg::trans_affine_translation(-center.x, -center.y);
}
markers_dispatch_params params_;
markers_renderer_context & renderer_context_;
svg_path_ptr const& src_;
agg::trans_affine const& marker_trans_;
symbolizer_base const& sym_;
svg_path_adapter & path_;
svg_attribute_type const& attrs_;
Detector & detector_;
feature_impl const& feature_;
attributes const& vars_;
double scale_factor_;
};
template <typename Detector>
@ -117,53 +159,35 @@ struct raster_markers_dispatch : util::noncopyable
Detector & detector,
double scale_factor,
feature_impl const& feature,
attributes const& vars)
: src_(src),
marker_trans_(marker_trans),
sym_(sym),
detector_(detector),
feature_(feature),
vars_(vars),
scale_factor_(scale_factor)
attributes const& vars,
markers_renderer_context & renderer_context)
: params_(box2d<double>(0, 0, src.width(), src.height()),
marker_trans, sym, feature, vars, scale_factor)
, renderer_context_(renderer_context)
, src_(src)
, detector_(detector)
{}
virtual ~raster_markers_dispatch() {}
template <typename T>
void add_path(T & path)
{
marker_placement_enum placement_method = get<marker_placement_enum, keys::markers_placement_type>(sym_, feature_, vars_);
value_bool allow_overlap = get<value_bool, keys::allow_overlap>(sym_, feature_, vars_);
value_bool avoid_edges = get<value_bool, keys::avoid_edges>(sym_, feature_, vars_);
value_double opacity = get<value_double, keys::opacity>(sym_, feature_, vars_);
value_bool ignore_placement = get<value_bool, keys::ignore_placement>(sym_, feature_, vars_);
value_double spacing = get<value_double, keys::spacing>(sym_, feature_, vars_);
value_double max_error = get<value_double, keys::max_error>(sym_, feature_, vars_);
box2d<double> bbox(0,0, src_.width(),src_.height());
direction_enum direction = get<direction_enum, keys::direction>(sym_, feature_, vars_);
markers_placement_params params { bbox, marker_trans_, spacing * scale_factor_, max_error, allow_overlap, avoid_edges, direction };
markers_placement_finder<T, Detector> placement_finder(
placement_method, path, detector_, params);
params_.placement_method, path, detector_, params_.placement_params);
double x, y, angle = .0;
while (placement_finder.get_point(x, y, angle, ignore_placement))
while (placement_finder.get_point(x, y, angle, params_.ignore_placement))
{
agg::trans_affine matrix = marker_trans_;
agg::trans_affine matrix = params_.placement_params.tr;
matrix.rotate(angle);
matrix.translate(x, y);
render_marker(matrix, opacity);
renderer_context_.render_marker(src_, params_, matrix);
}
}
virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;
protected:
markers_dispatch_params params_;
markers_renderer_context & renderer_context_;
image_rgba8 const& src_;
agg::trans_affine const& marker_trans_;
symbolizer_base const& sym_;
Detector & detector_;
feature_impl const& feature_;
attributes const& vars_;
double scale_factor_;
};
void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars,

View file

@ -40,8 +40,8 @@ namespace mapnik {
struct markers_placement_params
{
box2d<double> const& size;
agg::trans_affine const& tr;
box2d<double> size;
agg::trans_affine tr;
double spacing;
double max_error;
bool allow_overlap;
@ -132,23 +132,8 @@ protected:
// Rotates the size_ box and translates the position.
box2d<double> perform_transform(double angle, double dx, double dy)
{
double x1 = params_.size.minx();
double x2 = params_.size.maxx();
double y1 = params_.size.miny();
double y2 = params_.size.maxy();
agg::trans_affine tr = params_.tr * agg::trans_affine_rotation(angle).translate(dx, dy);
double xA = x1, yA = y1,
xB = x2, yB = y1,
xC = x2, yC = y2,
xD = x1, yD = y2;
tr.transform(&xA, &yA);
tr.transform(&xB, &yB);
tr.transform(&xC, &yC);
tr.transform(&xD, &yD);
box2d<double> result(xA, yA, xC, yC);
result.expand_to_include(xB, yB);
result.expand_to_include(xD, yD);
return result;
return box2d<double>(params_.size, tr);
}
bool set_direction(double & angle)

View file

@ -37,7 +37,6 @@ struct render_marker_symbolizer_visitor
{
using vector_dispatch_type = VD;
using raster_dispatch_type = RD;
using buffer_type = typename std::tuple_element<0,ContextType>::type;
using vertex_converter_type = vertex_converter<clip_line_tag,
clip_poly_tag,
@ -246,14 +245,19 @@ struct render_marker_symbolizer_visitor
ContextType const& renderer_context_;
};
template <typename VD, typename RD, typename RendererType, typename ContextType>
template <typename RendererType>
void render_markers_symbolizer(markers_symbolizer const& sym,
mapnik::feature_impl & feature,
proj_transform const& prj_trans,
RendererType const& common,
box2d<double> const& clip_box,
ContextType const& renderer_context)
markers_renderer_context & renderer_context)
{
using Detector = decltype(*common.detector_);
using VD = vector_markers_dispatch<Detector>;
using RD = raster_markers_dispatch<Detector>;
using ContextType = markers_renderer_context & ;
using namespace mapnik::svg;
std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
if (!filename.empty())

View file

@ -60,106 +60,58 @@ namespace mapnik {
namespace detail {
template <typename SvgRenderer, typename Detector, typename RendererContext>
struct vector_markers_rasterizer_dispatch : public vector_markers_dispatch<Detector>
template <typename SvgRenderer, typename BufferType, typename RasterizerType>
struct agg_markers_renderer_context : markers_renderer_context
{
using renderer_base = typename SvgRenderer::renderer_base;
using vertex_source_type = typename SvgRenderer::vertex_source_type;
using attribute_source_type = typename SvgRenderer::attribute_source_type;
using pixfmt_type = typename renderer_base::pixfmt_type;
using BufferType = typename std::tuple_element<0,RendererContext>::type;
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
vector_markers_rasterizer_dispatch(svg_path_ptr const& src,
vertex_source_type & path,
svg_attribute_type const& attrs,
agg::trans_affine const& marker_trans,
symbolizer_base const& sym,
Detector & detector,
double scale_factor,
feature_impl & feature,
attributes const& vars,
bool snap_to_pixels,
RendererContext const& renderer_context)
: vector_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
buf_(std::get<0>(renderer_context)),
agg_markers_renderer_context(symbolizer_base const& sym,
feature_impl const& feature,
attributes const& vars,
BufferType & buf,
RasterizerType & ras)
: buf_(buf),
pixf_(buf_),
renb_(pixf_),
svg_renderer_(path, attrs),
ras_(std::get<1>(renderer_context)),
snap_to_pixels_(snap_to_pixels)
ras_(ras)
{
pixf_.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym, feature, vars)));
auto comp_op = get<composite_mode_e, keys::comp_op>(sym, feature, vars);
pixf_.comp_op(static_cast<agg::comp_op_e>(comp_op));
}
~vector_markers_rasterizer_dispatch() {}
void render_marker(agg::trans_affine const& marker_tr, double opacity)
virtual void render_marker(svg_path_ptr const& src,
svg_path_adapter & path,
svg_attribute_type const& attrs,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr)
{
render_vector_marker(svg_renderer_, ras_, renb_, this->src_->bounding_box(),
marker_tr, opacity, snap_to_pixels_);
SvgRenderer svg_renderer(path, attrs);
render_vector_marker(svg_renderer, ras_, renb_, src->bounding_box(),
marker_tr, params.opacity, params.snap_to_pixels);
}
virtual void render_marker(image_rgba8 const& src,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr)
{
// In the long term this should be a visitor pattern based on the type of
// render src provided that converts the destination pixel type required.
render_raster_marker(renb_, ras_, src, marker_tr, params.opacity,
params.scale_factor, params.snap_to_pixels);
}
private:
BufferType & buf_;
pixfmt_type pixf_;
renderer_base renb_;
SvgRenderer svg_renderer_;
RasterizerType & ras_;
bool snap_to_pixels_;
};
template <typename Detector, typename RendererContext>
struct raster_markers_rasterizer_dispatch : public raster_markers_dispatch<Detector>
{
using BufferType = typename std::remove_reference<typename std::tuple_element<0,RendererContext>::type>::type;
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
using color_type = agg::rgba8;
using order_type = agg::order_rgba;
using pixel_type = agg::pixel32_type;
using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, BufferType>;
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
raster_markers_rasterizer_dispatch(image_rgba8 const& src,
agg::trans_affine const& marker_trans,
symbolizer_base const& sym,
Detector & detector,
double scale_factor,
feature_impl & feature,
attributes const& vars,
RendererContext const& renderer_context,
bool snap_to_pixels = false)
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
buf_(std::get<0>(renderer_context)),
pixf_(buf_),
renb_(pixf_),
ras_(std::get<1>(renderer_context)),
snap_to_pixels_(snap_to_pixels)
{
pixf_.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym, feature, vars)));
}
~raster_markers_rasterizer_dispatch() {}
void render_marker(agg::trans_affine const& marker_tr, double opacity)
{
// In the long term this should be a visitor pattern based on the type of render this->src_ provided that converts
// the destination pixel type required.
render_raster_marker(renb_, ras_, this->src_, marker_tr, opacity, this->scale_factor_, snap_to_pixels_);
}
private:
BufferType & buf_;
pixfmt_comp_type pixf_;
renderer_base renb_;
RasterizerType & ras_;
bool snap_to_pixels_;
};
}
} // namespace detail
template <typename T0, typename T1>
void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
@ -194,16 +146,16 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
buf_type render_buffer(current_buffer_->bytes(), current_buffer_->width(), current_buffer_->height(), current_buffer_->row_size());
box2d<double> clip_box = clipping_extent(common_);
auto renderer_context = std::tie(render_buffer,*ras_ptr,pixmap_);
using markers_context_type = decltype(renderer_context);
using vector_dispatch_type = detail::vector_markers_rasterizer_dispatch<svg_renderer_type, detector_type, markers_context_type>;
using raster_dispatch_type = detail::raster_markers_rasterizer_dispatch<detector_type, markers_context_type>;
using context_type = detail::agg_markers_renderer_context<svg_renderer_type,
buf_type,
rasterizer>;
context_type renderer_context(sym, feature, common_.vars_, render_buffer, *ras_ptr);
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
render_markers_symbolizer(
sym, feature, prj_trans, common_, clip_box, renderer_context);
}
template void agg_renderer<image_rgba8>::process(markers_symbolizer const&,
mapnik::feature_impl &,
proj_transform const&);
}
} // namespace mapnik

View file

@ -42,73 +42,40 @@
namespace mapnik
{
class feature_impl;
class proj_transform;
namespace detail {
template <typename RendererContext, typename Detector>
struct vector_markers_dispatch_cairo : public vector_markers_dispatch<Detector>
struct cairo_markers_renderer_context : markers_renderer_context
{
vector_markers_dispatch_cairo(svg_path_ptr const& src,
svg::svg_path_adapter & path,
svg_attribute_type const& attrs,
agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
double scale_factor,
feature_impl & feature,
mapnik::attributes const& vars,
bool /* snap_to_pixels */, // only used in agg renderer currently
RendererContext const& renderer_context)
: vector_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
path_(path),
attr_(attrs),
ctx_(std::get<0>(renderer_context))
explicit cairo_markers_renderer_context(cairo_context & ctx)
: ctx_(ctx)
{}
void render_marker(agg::trans_affine const& marker_tr, double opacity)
virtual void render_marker(svg_path_ptr const& src,
svg_path_adapter & path,
svg_attribute_type const& attrs,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr)
{
render_vector_marker(ctx_,
path_,
attr_,
this->src_->bounding_box(),
path,
attrs,
src->bounding_box(),
marker_tr,
opacity);
params.opacity);
}
private:
svg::svg_path_adapter & path_;
svg_attribute_type const& attr_;
cairo_context & ctx_;
};
template <typename RendererContext, typename Detector>
struct raster_markers_dispatch_cairo : public raster_markers_dispatch<Detector>
{
raster_markers_dispatch_cairo(image_rgba8 const& src,
agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
double scale_factor,
feature_impl & feature,
mapnik::attributes const& vars,
RendererContext const& renderer_context)
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
ctx_(std::get<0>(renderer_context)) {}
~raster_markers_dispatch_cairo() {}
void render_marker(agg::trans_affine const& marker_tr, double opacity)
virtual void render_marker(image_rgba8 const& src,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr)
{
ctx_.add_image(marker_tr, this->src_, opacity);
ctx_.add_image(marker_tr, src, params.opacity);
}
private:
cairo_context & ctx_;
};
}
} // namespace detail
template <typename T>
void cairo_renderer<T>::process(markers_symbolizer const& sym,
@ -120,17 +87,10 @@ void cairo_renderer<T>::process(markers_symbolizer const& sym,
context_.set_operator(comp_op);
box2d<double> clip_box = common_.query_extent_;
auto renderer_context = std::tie(context_);
using context_type = detail::cairo_markers_renderer_context;
context_type renderer_context(context_);
using RendererContextType = decltype(renderer_context);
using vector_dispatch_type = detail::vector_markers_dispatch_cairo<RendererContextType,
label_collision_detector4>;
using raster_dispatch_type = detail::raster_markers_dispatch_cairo<RendererContextType,
label_collision_detector4>;
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
render_markers_symbolizer(
sym, feature, prj_trans, common_, clip_box,
renderer_context);
}
@ -139,6 +99,6 @@ template void cairo_renderer<cairo_ptr>::process(markers_symbolizer const&,
mapnik::feature_impl &,
proj_transform const&);
}
} // namespace mapnik
#endif // HAVE_CAIRO

View file

@ -81,109 +81,72 @@ namespace mapnik {
namespace detail {
template <typename SvgRenderer, typename Detector, typename RendererContext>
struct vector_markers_rasterizer_dispatch : public vector_markers_dispatch<Detector>
template <typename SvgRenderer, typename ScanlineRenderer,
typename BufferType, typename RasterizerType, typename PixMapType>
struct grid_markers_renderer_context : markers_renderer_context
{
using renderer_base = typename SvgRenderer::renderer_base;
using vertex_source_type = typename SvgRenderer::vertex_source_type;
using attribute_source_type = typename SvgRenderer::attribute_source_type;
using pixfmt_type = typename renderer_base::pixfmt_type;
using BufferType = typename std::tuple_element<0,RendererContext>::type;
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
using PixMapType = typename std::tuple_element<2,RendererContext>::type;
vector_markers_rasterizer_dispatch(svg_path_ptr const& src,
vertex_source_type & path,
svg_attribute_type const& attrs,
agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
double scale_factor,
mapnik::feature_impl & feature,
attributes const& vars,
bool snap_to_pixels,
RendererContext const& renderer_context)
: vector_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
buf_(std::get<0>(renderer_context)),
grid_markers_renderer_context(feature_impl const& feature,
BufferType & buf,
RasterizerType & ras,
PixMapType & pixmap)
: feature_(feature),
buf_(buf),
pixf_(buf_),
renb_(pixf_),
svg_renderer_(path, attrs),
ras_(std::get<1>(renderer_context)),
pixmap_(std::get<2>(renderer_context)),
ras_(ras),
pixmap_(pixmap),
placed_(false)
{}
void render_marker(agg::trans_affine const& marker_tr, double opacity)
virtual void render_marker(svg_path_ptr const& src,
svg_path_adapter & path,
svg_attribute_type const& attrs,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr)
{
SvgRenderer svg_renderer_(path, attrs);
agg::scanline_bin sl_;
svg_renderer_.render_id(ras_, sl_, renb_, this->feature_.id(), marker_tr, opacity, this->src_->bounding_box());
svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), marker_tr,
params.opacity, src->bounding_box());
place_feature();
}
virtual void render_marker(image_rgba8 const& src,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr)
{
// In the long term this should be a visitor pattern based on the type of
// render src provided that converts the destination pixel type required.
render_raster_marker(ScanlineRenderer(renb_), ras_, src, feature_,
marker_tr, params.opacity);
place_feature();
}
void place_feature()
{
if (!placed_)
{
pixmap_.add_feature(this->feature_);
pixmap_.add_feature(feature_);
placed_ = true;
}
}
private:
feature_impl const& feature_;
BufferType & buf_;
pixfmt_type pixf_;
renderer_base renb_;
SvgRenderer svg_renderer_;
RasterizerType & ras_;
PixMapType & pixmap_;
bool placed_;
};
template <typename RendererBase, typename RendererType, typename Detector, typename RendererContext>
struct raster_markers_rasterizer_dispatch : public raster_markers_dispatch<Detector>
{
using pixfmt_type = typename RendererBase::pixfmt_type;
using color_type = typename RendererBase::pixfmt_type::color_type;
using BufferType = typename std::tuple_element<0,RendererContext>::type;
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
using PixMapType = typename std::tuple_element<2,RendererContext>::type;
raster_markers_rasterizer_dispatch(image_rgba8 const& src,
agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
double scale_factor,
mapnik::feature_impl & feature,
attributes const& vars,
RendererContext const& renderer_context)
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
buf_(std::get<0>(renderer_context)),
pixf_(buf_),
renb_(pixf_),
ras_(std::get<1>(renderer_context)),
pixmap_(std::get<2>(renderer_context)),
placed_(false)
{}
void render_marker(agg::trans_affine const& marker_tr, double opacity)
{
// In the long term this should be a visitor pattern based on the type of render this->src_ provided that converts
// the destination pixel type required.
render_raster_marker(RendererType(renb_), ras_, this->src_, this->feature_, marker_tr, opacity);
if (!placed_)
{
pixmap_.add_feature(this->feature_);
placed_ = true;
}
}
private:
BufferType & buf_;
pixfmt_type pixf_;
RendererBase renb_;
RasterizerType & ras_;
PixMapType & pixmap_;
bool placed_;
};
}
} // namespace detail
template <typename T>
void grid_renderer<T>::process(markers_symbolizer const& sym,
@ -193,7 +156,6 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
using buf_type = grid_rendering_buffer;
using pixfmt_type = typename grid_renderer_base_type::pixfmt_type;
using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>;
using detector_type = label_collision_detector4;
using namespace mapnik::svg;
using svg_attribute_type = agg::pod_bvector<path_attributes>;
@ -206,22 +168,20 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
ras_ptr->reset();
box2d<double> clip_box = common_.query_extent_;
auto renderer_context = std::tie(render_buf,*ras_ptr,pixmap_);
using grid_context_type = decltype(renderer_context);
using vector_dispatch_type = detail::vector_markers_rasterizer_dispatch<svg_renderer_type,
detector_type,
grid_context_type>;
using raster_dispatch_type = detail::raster_markers_rasterizer_dispatch<grid_renderer_base_type,
renderer_type,
detector_type,
grid_context_type>;
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
sym, feature, prj_trans, common_, clip_box,renderer_context);
using context_type = detail::grid_markers_renderer_context<svg_renderer_type,
renderer_type,
buf_type,
grid_rasterizer,
buffer_type>;
context_type renderer_context(feature, render_buf, *ras_ptr, pixmap_);
render_markers_symbolizer(
sym, feature, prj_trans, common_, clip_box, renderer_context);
}
template void grid_renderer<grid>::process(markers_symbolizer const&,
mapnik::feature_impl &,
proj_transform const&);
}
} // namespace mapnik
#endif

View file

@ -38,68 +38,38 @@ virtual_renderer_common::virtual_renderer_common(renderer_common const& other)
namespace detail {
template <typename Detector, typename RendererContext>
struct vector_marker_thunk_dispatch : public vector_markers_dispatch<Detector>
struct thunk_markers_renderer_context : markers_renderer_context
{
vector_marker_thunk_dispatch(svg_path_ptr const& src,
svg_path_adapter & path,
svg_attribute_type const& attrs,
agg::trans_affine const& marker_trans,
symbolizer_base const& sym,
Detector & detector,
double scale_factor,
feature_impl & feature,
attributes const& vars,
bool snap_to_pixels,
RendererContext const& renderer_context)
: vector_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
attrs_(attrs), comp_op_(get<composite_mode_e, keys::comp_op>(sym, feature, vars)),
snap_to_pixels_(snap_to_pixels), thunks_(std::get<0>(renderer_context))
thunk_markers_renderer_context(symbolizer_base const& sym,
feature_impl const& feature,
attributes const& vars,
render_thunk_list & thunks)
: comp_op_(get<composite_mode_e, keys::comp_op>(sym, feature, vars))
, thunks_(thunks)
{}
~vector_marker_thunk_dispatch() {}
void render_marker(agg::trans_affine const& marker_tr, double opacity)
virtual void render_marker(svg_path_ptr const& src,
svg_path_adapter & path,
svg_attribute_type const& attrs,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr)
{
vector_marker_render_thunk thunk(this->src_, this->attrs_, marker_tr, opacity, comp_op_, snap_to_pixels_);
vector_marker_render_thunk thunk(src, attrs, marker_tr, params.opacity,
comp_op_, params.snap_to_pixels);
thunks_.push_back(std::make_unique<render_thunk>(std::move(thunk)));
}
private:
svg_attribute_type const& attrs_;
composite_mode_e comp_op_;
bool snap_to_pixels_;
render_thunk_list & thunks_;
};
template <typename Detector, typename RendererContext>
struct raster_marker_thunk_dispatch : public raster_markers_dispatch<Detector>
{
raster_marker_thunk_dispatch(image_rgba8 const& src,
agg::trans_affine const& marker_trans,
symbolizer_base const& sym,
Detector & detector,
double scale_factor,
feature_impl & feature,
attributes const& vars,
RendererContext const& renderer_context,
bool snap_to_pixels = false)
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
comp_op_(get<composite_mode_e, keys::comp_op>(sym, feature, vars)),
snap_to_pixels_(snap_to_pixels), thunks_(std::get<0>(renderer_context))
{}
~raster_marker_thunk_dispatch() {}
void render_marker(agg::trans_affine const& marker_tr, double opacity)
virtual void render_marker(image_rgba8 const& src,
markers_dispatch_params const& params,
agg::trans_affine const& marker_tr)
{
raster_marker_render_thunk thunk(this->src_, marker_tr, opacity, comp_op_, snap_to_pixels_);
raster_marker_render_thunk thunk(src, marker_tr, params.opacity,
comp_op_, params.snap_to_pixels);
thunks_.push_back(std::make_unique<render_thunk>(std::move(thunk)));
}
private:
composite_mode_e comp_op_;
bool snap_to_pixels_;
render_thunk_list & thunks_;
};
@ -118,12 +88,10 @@ render_thunk_extractor::render_thunk_extractor(box2d<double> & box,
void render_thunk_extractor::operator()(markers_symbolizer const& sym) const
{
auto renderer_context = std::tie(thunks_);
using thunk_context_type = decltype(renderer_context);
using vector_dispatch_type = detail::vector_marker_thunk_dispatch<label_collision_detector4, thunk_context_type>;
using raster_dispatch_type = detail::raster_marker_thunk_dispatch<label_collision_detector4, thunk_context_type>;
using context_type = detail::thunk_markers_renderer_context;
context_type renderer_context(sym, feature_, vars_, thunks_);
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
render_markers_symbolizer(
sym, feature_, prj_trans_, common_, clipping_extent_, renderer_context);
update_box();