bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms, mapnik::feature_impl & feature, proj_transform const& prj_trans) { // svg renderer supports processing of multiple symbolizers. typedef coord_transform<CoordTransform, geometry_type> path_type; bool process_path = false; // process each symbolizer to collect its (path) information. // path information (attributes from line_ and polygon_ symbolizers) // is collected with the path_attributes_ data member. for (symbolizer const& sym : syms) { if (is_path_based(sym)) { process_path = true; } boost::apply_visitor(symbol_dispatch(*this, feature, prj_trans), sym); } if (process_path) { // generate path output for each geometry of the current feature. for(std::size_t i=0; i<feature.num_geometries(); ++i) { geometry_type & geom = feature.get_geometry(i); if(geom.size() > 0) { path_type path(t_, geom, prj_trans); generator_.generate_path(path, path_attributes_); } } // set the previously collected values back to their defaults // for the feature that will be processed next. path_attributes_.reset(); } return true; }
void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { composite_mode_e comp_op = get<composite_mode_e, keys::comp_op>(sym, feature, common_.vars_); std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_); value_bool clip = get<value_bool, keys::clip>(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_); 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); cairo_save_restore guard(context_); context_.set_operator(comp_op); boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance().find(filename,true); if (!marker || !(*marker)) return; unsigned offset_x=0; unsigned offset_y=0; box2d<double> const& clip_box = clipping_extent(common_); pattern_alignment_enum alignment = get<pattern_alignment_enum, keys::alignment>(sym, feature, common_.vars_); if (alignment == LOCAL_ALIGNMENT) { double x0 = 0.0; double y0 = 0.0; if (feature.num_geometries() > 0) { using clipped_geometry_type = agg::conv_clip_polygon<geometry_type>; using path_type = transform_path_adapter<view_transform,clipped_geometry_type>; clipped_geometry_type clipped(feature.get_geometry(0)); clipped.clip_box(clip_box.minx(), clip_box.miny(), clip_box.maxx(), clip_box.maxy()); path_type path(common_.t_, clipped, prj_trans); path.vertex(&x0, &y0); } offset_x = std::abs(clip_box.width() - x0); offset_y = std::abs(clip_box.height() - y0); } if ((*marker)->is_bitmap()) { cairo_pattern pattern(**((*marker)->get_bitmap_data()), opacity); pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_origin(offset_x, offset_y); context_.set_pattern(pattern); } else { mapnik::rasterizer ras; image_ptr image = render_pattern(ras, **marker, image_tr, 1.0); // cairo_pattern pattern(*image, opacity); pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_origin(offset_x, offset_y); context_.set_pattern(pattern); } agg::trans_affine tr; auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform); if (geom_transform) { evaluate_transform(tr, feature, common_.vars_, *geom_transform, common_.scale_factor_); } vertex_converter<cairo_context,clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> converter(clip_box, context_,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true) converter.set<transform_tag>(); //always transform converter.set<affine_transform_tag>(); if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter for ( geometry_type & geom : feature.paths()) { if (geom.size() > 2) { converter.apply(geom); } } // fill polygon context_.set_fill_rule(CAIRO_FILL_RULE_EVEN_ODD); context_.fill(); }
void render_point_symbolizer(point_symbolizer const &sym, mapnik::feature_impl &feature, proj_transform const &prj_trans, RendererType &common, F render_marker) { std::string filename = get<std::string>(sym, keys::file, feature, common.vars_); boost::optional<mapnik::marker_ptr> marker = filename.empty() ? std::make_shared<mapnik::marker>() : marker_cache::instance().find(filename, true); if (marker) { double opacity = get<double>(sym,keys::opacity,feature, common.vars_, 1.0); bool allow_overlap = get<bool>(sym, keys::allow_overlap, feature, common.vars_, false); bool ignore_placement = get<bool>(sym, keys::ignore_placement, feature, common.vars_, false); point_placement_enum placement= get<point_placement_enum>(sym, keys::point_placement_type, feature, common.vars_, CENTROID_POINT_PLACEMENT); box2d<double> const& bbox = (*marker)->bounding_box(); coord2d center = bbox.center(); agg::trans_affine tr; auto image_transform = get_optional<transform_type>(sym, keys::image_transform); if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform); agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine recenter_tr = recenter * tr; box2d<double> label_ext = bbox * recenter_tr * agg::trans_affine_scaling(common.scale_factor_); for (std::size_t i=0; i<feature.num_geometries(); ++i) { geometry_type const& geom = feature.get_geometry(i); double x; double y; double z=0; if (placement == CENTROID_POINT_PLACEMENT) { if (!label::centroid(geom, x, y)) return; } else { if (!label::interior_position(geom ,x, y)) return; } prj_trans.backward(x,y,z); common.t_.forward(&x,&y); label_ext.re_center(x,y); if (allow_overlap || common.detector_->has_placement(label_ext)) { render_marker(pixel_position(x, y), **marker, tr, opacity); if (!ignore_placement) common.detector_->insert(label_ext); } } } }
void agg_renderer<T>::process(building_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { typedef coord_transform<CoordTransform,geometry_type> path_type; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_scanline_aa_solid<ren_base> renderer; agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4); agg::pixfmt_rgba32 pixf(buf); ren_base renb(pixf); color const& fill_ = sym.get_fill(); unsigned r=fill_.red(); unsigned g=fill_.green(); unsigned b=fill_.blue(); unsigned a=fill_.alpha(); renderer ren(renb); agg::scanline_u8 sl; ras_ptr->reset(); ras_ptr->gamma(agg::gamma_power()); double height = 0.0; expression_ptr height_expr = sym.height(); if (height_expr) { value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr); height = result.to_double() * scale_factor_; } for (unsigned i=0;i<feature.num_geometries();++i) { geometry_type const& geom = feature.get_geometry(i); if (geom.size() > 2) { boost::scoped_ptr<geometry_type> frame(new geometry_type(LineString)); boost::scoped_ptr<geometry_type> roof(new geometry_type(Polygon)); std::deque<segment_t> face_segments; double x0 = 0; double y0 = 0; double x,y; geom.rewind(0); for (unsigned cm = geom.vertex(&x, &y); cm != SEG_END; cm = geom.vertex(&x, &y)) { if (cm == SEG_MOVETO) { frame->move_to(x,y); } else if (cm == SEG_LINETO || cm == SEG_CLOSE) { frame->line_to(x,y); face_segments.push_back(segment_t(x0,y0,x,y)); } x0 = x; y0 = y; } std::sort(face_segments.begin(),face_segments.end(), y_order); std::deque<segment_t>::const_iterator itr=face_segments.begin(); std::deque<segment_t>::const_iterator end=face_segments.end(); for (; itr!=end; ++itr) { boost::scoped_ptr<geometry_type> faces(new geometry_type(Polygon)); faces->move_to(itr->get<0>(),itr->get<1>()); faces->line_to(itr->get<2>(),itr->get<3>()); faces->line_to(itr->get<2>(),itr->get<3>() + height); faces->line_to(itr->get<0>(),itr->get<1>() + height); path_type faces_path (t_,*faces,prj_trans); ras_ptr->add_path(faces_path); ren.color(agg::rgba8(int(r*0.8), int(g*0.8), int(b*0.8), int(a * sym.get_opacity()))); agg::render_scanlines(*ras_ptr, sl, ren); ras_ptr->reset(); // frame->move_to(itr->get<0>(),itr->get<1>()); frame->line_to(itr->get<0>(),itr->get<1>()+height); } geom.rewind(0); for (unsigned cm = geom.vertex(&x, &y); cm != SEG_END; cm = geom.vertex(&x, &y)) { if (cm == SEG_MOVETO) { frame->move_to(x,y+height); roof->move_to(x,y+height); } else if (cm == SEG_LINETO || cm == SEG_CLOSE) { frame->line_to(x,y+height); roof->line_to(x,y+height); } } path_type path(t_,*frame,prj_trans); agg::conv_stroke<path_type> stroke(path); stroke.width(scale_factor_); ras_ptr->add_path(stroke); ren.color(agg::rgba8(int(r*0.8), int(g*0.8), int(b*0.8), int(a * sym.get_opacity()))); agg::render_scanlines(*ras_ptr, sl, ren); ras_ptr->reset(); path_type roof_path (t_,*roof,prj_trans); ras_ptr->add_path(roof_path); ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity()))); agg::render_scanlines(*ras_ptr, sl, ren); } } }
void agg_renderer<T>::process(point_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature); boost::optional<mapnik::marker_ptr> marker; if ( !filename.empty() ) { marker = marker_cache::instance()->find(filename, true); } else { marker.reset(boost::make_shared<mapnik::marker>()); } if (marker) { box2d<double> const& bbox = (*marker)->bounding_box(); coord2d center = bbox.center(); agg::trans_affine tr; evaluate_transform(tr, feature, sym.get_image_transform()); agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine recenter_tr = recenter * tr; box2d<double> label_ext = bbox * recenter_tr; for (unsigned i=0; i<feature.num_geometries(); ++i) { geometry_type const& geom = feature.get_geometry(i); double x; double y; double z=0; if (sym.get_point_placement() == CENTROID_POINT_PLACEMENT) { if (!label::centroid(geom, x, y)) return; } else { if (!label::interior_position(geom ,x, y)) return; } prj_trans.backward(x,y,z); t_.forward(&x,&y); label_ext.re_center(x,y); if (sym.get_allow_overlap() || detector_->has_placement(label_ext)) { render_marker(pixel_position(x, y), **marker, tr, sym.get_opacity(), sym.comp_op()); if (!sym.get_ignore_placement()) detector_->insert(label_ext); } } } }