refactor render_markers_symbolizer
This commit is contained in:
parent
8a55eefbb5
commit
f99c0e5a6f
7 changed files with 226 additions and 373 deletions
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue