void render_pattern<image_rgba8>(rasterizer & ras, marker_svg const& marker, agg::trans_affine const& tr, double opacity, image_rgba8 & image) { using pixfmt = agg::pixfmt_rgba32_pre; using renderer_base = agg::renderer_base<pixfmt>; using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>; agg::scanline_u8 sl; mapnik::box2d<double> const& bbox = marker.bounding_box() * tr; mapnik::coord<double,2> c = bbox.center(); agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y); mtx.translate(0.5 * bbox.width(), 0.5 * bbox.height()); mtx = tr * mtx; agg::rendering_buffer buf(image.bytes(), image.width(), image.height(), image.row_size()); pixfmt pixf(buf); renderer_base renb(pixf); mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker.get_data()->source()); mapnik::svg::svg_path_adapter svg_path(stl_storage); mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter, agg::pod_bvector<mapnik::svg::path_attributes>, renderer_solid, pixfmt > svg_renderer(svg_path, marker.get_data()->attributes()); svg_renderer.render(ras, sl, renb, mtx, opacity, bbox); }
void operator() (marker_svg const& marker) { using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); ras_ptr_->reset(); box2d<double> const& bbox = marker.get_data()->bounding_box(); coord<double,2> c = bbox.center(); // center the svg marker on '0,0' agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y); // apply symbol transformation to get to map space mtx *= tr_; mtx *= agg::trans_affine_scaling(common_.scale_factor_); // render the marker at the center of the marker box mtx.translate(pos_.x, pos_.y); using namespace mapnik::svg; vertex_stl_adapter<svg_path_storage> stl_storage(marker.get_data()->source()); svg_path_adapter svg_path(stl_storage); svg_renderer_agg<svg_path_adapter, agg::pod_bvector<path_attributes>, renderer_type, pixfmt_type> svg_renderer(svg_path, marker.get_data()->attributes()); svg_renderer.render_id(*ras_ptr_, sl, renb, feature_.id(), mtx, opacity_, bbox); }
cairo_surface_ptr operator()(marker_svg const & marker) const { box2d<double> bbox(marker.bounding_box()); agg::trans_affine tr(transform(bbox)); double width = std::max(1.0, std::round(bbox.width())); double height = std::max(1.0, std::round(bbox.height())); cairo_rectangle_t extent { 0, 0, width, height }; cairo_surface_ptr surface( cairo_recording_surface_create( CAIRO_CONTENT_COLOR_ALPHA, &extent), cairo_surface_closer()); cairo_ptr cairo = create_context(surface); cairo_context context(cairo); svg_storage_type & svg = *marker.get_data(); svg_attribute_type const& svg_attributes = svg.attributes(); svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage( svg.source()); svg::svg_path_adapter svg_path(stl_storage); render_vector_marker(context, svg_path, svg_attributes, bbox, tr, opacity_); return surface; }
void operator() (marker_svg const& mark) const { using namespace mapnik::svg; // https://github.com/mapnik/mapnik/issues/1316 bool snap_to_pixels = !mapnik::marker_cache::instance().is_uri(filename_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); svg_path_ptr stock_vector_marker = mark.get_data(); svg_path_ptr marker_ptr = stock_vector_marker; bool is_ellipse = false; svg_attribute_type s_attributes; auto const& r_attributes = get_marker_attributes(stock_vector_marker, s_attributes); // special case for simple ellipse markers // to allow for full control over rx/ry dimensions if (filename_ == "shape://ellipse" && (has_key(sym_,keys::width) || has_key(sym_,keys::height))) { marker_ptr = std::make_shared<svg_storage_type>(); is_ellipse = true; } else { box2d<double> const& bbox = mark.bounding_box(); setup_transform_scaling(image_tr, bbox.width(), bbox.height(), feature_, common_.vars_, sym_); } vertex_stl_adapter<svg_path_storage> stl_storage(marker_ptr->source()); svg_path_adapter svg_path(stl_storage); if (is_ellipse) { build_ellipse(sym_, feature_, common_.vars_, *marker_ptr, svg_path); } if (auto image_transform = get_optional<transform_type>(sym_, keys::image_transform)) { evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_); } vector_dispatch_type rasterizer_dispatch(marker_ptr, svg_path, r_attributes, image_tr, sym_, *common_.detector_, common_.scale_factor_, feature_, common_.vars_, snap_to_pixels, renderer_context_); render_marker(mark, rasterizer_dispatch); }
void operator() (marker_svg const& marker) const { agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); 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_); mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr; mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image); render(image); }
void operator() (marker_svg const& marker) { mapnik::rasterizer ras; mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr_; mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern<image_rgba8>(ras, marker, image_tr_, 1.0, image); cairo_pattern pattern(image, opacity_); pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_origin(offset_x_, offset_y_); context_.set_pattern(pattern); }
void operator() (marker_svg const& marker) { mapnik::svg_path_ptr vmarker = marker.get_data(); if (vmarker) { box2d<double> bbox = vmarker->bounding_box(); agg::trans_affine marker_tr = tr_; if (recenter_) { coord<double,2> c = bbox.center(); marker_tr = agg::trans_affine_translation(-c.x,-c.y); marker_tr *= tr_; } marker_tr *= agg::trans_affine_scaling(common_.scale_factor_); agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes(); svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(vmarker->source()); svg::svg_path_adapter svg_path(stl_storage); marker_tr.translate(pos_.x, pos_.y); render_vector_marker(context_, svg_path, attributes, bbox, marker_tr, opacity_); } }
void operator() (marker_svg 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_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); 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_); mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr; image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image); 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()); }
void operator() (marker_svg const& marker) { agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); auto image_transform = get_optional<transform_type>(sym_, keys::image_transform); if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform); mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr; mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height()); render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image); agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(), current_buffer_->height(), current_buffer_->row_size()); ras_ptr_->reset(); value_double gamma = get<value_double, keys::gamma>(sym_, feature_, common_.vars_); gamma_method_enum gamma_method = get<gamma_method_enum, keys::gamma_method>(sym_, feature_, common_.vars_); if (gamma != gamma_ || gamma_method != gamma_method_) { set_gamma_method(ras_ptr_, gamma, gamma_method); gamma_method_ = gamma_method; gamma_ = gamma; } value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_); value_double opacity = get<double, keys::opacity>(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_); box2d<double> clip_box = clipping_extent(common_); using color = agg::rgba8; using order = agg::order_rgba; using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>; using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>; using wrap_x_type = agg::wrap_mode_repeat; using wrap_y_type = agg::wrap_mode_repeat; using img_source_type = agg::image_accessor_wrap<agg::pixfmt_rgba32_pre, wrap_x_type, wrap_y_type>; using span_gen_type = agg::span_pattern_rgba<img_source_type>; using ren_base = agg::renderer_base<pixfmt_type>; using renderer_type = agg::renderer_scanline_aa_alpha<ren_base, agg::span_allocator<agg::rgba8>, span_gen_type>; pixfmt_type pixf(buf); pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_))); ren_base renb(pixf); unsigned w = image.width(); unsigned h = image.height(); agg::rendering_buffer pattern_rbuf((agg::int8u*)image.bytes(),w,h,w*4); agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf); img_source_type img_src(pixf_pattern); pattern_alignment_enum alignment = get<pattern_alignment_enum, keys::alignment>(sym_, feature_, common_.vars_); unsigned offset_x=0; unsigned offset_y=0; if (alignment == LOCAL_ALIGNMENT) { double x0 = 0; double y0 = 0; using apply_local_alignment = detail::apply_local_alignment; apply_local_alignment apply(common_.t_,prj_trans_, clip_box, x0, y0); util::apply_visitor(geometry::vertex_processor<apply_local_alignment>(apply), feature_.get_geometry()); offset_x = unsigned(current_buffer_->width() - x0); offset_y = unsigned(current_buffer_->height() - y0); } span_gen_type sg(img_src, offset_x, offset_y); agg::span_allocator<agg::rgba8> sa; renderer_type rp(renb,sa, sg, unsigned(opacity * 255)); 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_); using vertex_converter_type = vertex_converter<clip_poly_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag>; vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_); if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>(); converter.set<transform_tag>(); //always transform converter.set<affine_transform_tag>(); // optional affine transform if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer>; using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>; apply_vertex_converter_type apply(converter, *ras_ptr_); mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry()); agg::scanline_u8 sl; ras_ptr_->filling_rule(agg::fill_even_odd); agg::render_scanlines(*ras_ptr_, sl, rp); }
void operator() (marker_svg 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_); // https://github.com/mapnik/mapnik/issues/1316 bool snap_to_pixels = !mapnik::marker_cache::instance().is_uri(filename_); 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_); boost::optional<svg_path_ptr> const& stock_vector_marker = mark.get_data(); // special case for simple ellipse markers // to allow for full control over rx/ry dimensions if (filename_ == "shape://ellipse" && (has_key(sym_,keys::width) || has_key(sym_,keys::height))) { svg_path_ptr marker_ellipse = std::make_shared<svg_storage_type>(); vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse->source()); svg_path_adapter svg_path(stl_storage); build_ellipse(sym_, feature_, common_.vars_, *marker_ellipse, svg_path); svg_attribute_type attributes; bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym_, feature_, common_.vars_); auto image_transform = get_optional<transform_type>(sym_, keys::image_transform); if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform); vector_dispatch_type rasterizer_dispatch(marker_ellipse, svg_path, result ? attributes : (*stock_vector_marker)->attributes(), image_tr, sym_, *common_.detector_, common_.scale_factor_, feature_, common_.vars_, snap_to_pixels, 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_); } else { box2d<double> const& bbox = mark.bounding_box(); setup_transform_scaling(image_tr, bbox.width(), bbox.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); vertex_stl_adapter<svg_path_storage> stl_storage((*stock_vector_marker)->source()); svg_path_adapter svg_path(stl_storage); svg_attribute_type attributes; bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym_, feature_, common_.vars_); vector_dispatch_type rasterizer_dispatch(*stock_vector_marker, svg_path, result ? attributes : (*stock_vector_marker)->attributes(), image_tr, sym_, *common_.detector_, common_.scale_factor_, feature_, common_.vars_, snap_to_pixels, 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_); } }