void grid_renderer<T>::process(building_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; using transform_path_type = transform_path_adapter<view_transform, vertex_adapter>; 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(); double height = get<value_double>(sym, keys::height, feature, common_.vars_, 0.0); render_building_symbolizer( feature, height, [&](path_type const& faces) { vertex_adapter va(faces); transform_path_type faces_path (common_.t_,va,prj_trans); ras_ptr->add_path(faces_path); ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); ras_ptr->reset(); }, [&](path_type const& frame) { vertex_adapter va(frame); transform_path_type path(common_.t_,va,prj_trans); agg::conv_stroke<transform_path_type> stroke(path); ras_ptr->add_path(stroke); ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); ras_ptr->reset(); }, [&](path_type const& roof) { vertex_adapter va(roof); transform_path_type roof_path (common_.t_,va,prj_trans); ras_ptr->add_path(roof_path); ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); }); pixmap_.add_feature(feature); }
void grid_renderer<T>::process(text_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper( sym, feature, prj_trans, width_, height_, scale_factor_ * (1.0/pixmap_.get_resolution()), t_, font_manager_, *detector_, query_extent_); bool placement_found = false; text_renderer<T> ren(pixmap_, font_manager_, sym.get_halo_rasterizer(), sym.comp_op(), scale_factor_); while (helper.next()) { placement_found = true; placements_type const& placements = helper.placements(); for (unsigned int ii = 0; ii < placements.size(); ++ii) { ren.prepare_glyphs(placements[ii]); ren.render_id(feature.id(), placements[ii].center); } } if (placement_found) pixmap_.add_feature(feature); }
void render_raster_marker(RendererType ren, RasterizerType & ras, image_data_rgba8 & src, mapnik::feature_impl const& feature, agg::trans_affine const& marker_tr, double opacity) { using color_type = typename RendererType::color_type; agg::scanline_bin sl; double width = src.width(); double height = src.height(); double p[8]; p[0] = 0; p[1] = 0; p[2] = width; p[3] = 0; p[4] = width; p[5] = height; p[6] = 0; p[7] = height; marker_tr.transform(&p[0], &p[1]); marker_tr.transform(&p[2], &p[3]); marker_tr.transform(&p[4], &p[5]); marker_tr.transform(&p[6], &p[7]); ras.move_to_d(p[0],p[1]); ras.line_to_d(p[2],p[3]); ras.line_to_d(p[4],p[5]); ras.line_to_d(p[6],p[7]); ren.color(color_type(feature.id())); agg::render_scanlines(ras, sl, ren); }
void grid_renderer<T>::process(text_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { 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_); text_symbolizer_helper helper( sym, feature, common_.vars_, prj_trans, common_.width_, common_.height_, common_.scale_factor_ * (1.0/pixmap_.get_resolution()), common_.t_, common_.font_manager_, *common_.detector_, common_.query_extent_, tr); bool placement_found = false; composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over); grid_text_renderer<T> ren(pixmap_, comp_op, common_.scale_factor_); placements_list const& placements = helper.get(); value_integer feature_id = feature.id(); for (glyph_positions_ptr glyphs : placements) { ren.render(*glyphs, feature_id); placement_found = true; } if (placement_found) { pixmap_.add_feature(feature); } }
void grid_renderer<T>::process(polygon_pattern_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<marker_ptr> mark = marker_cache::instance().find(filename,true); if (!mark) return; if (!(*mark)->is_bitmap()) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer"; return; } boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); if (!pat) return; ras_ptr->reset(); agg::trans_affine tr; evaluate_transform(tr, feature, sym.get_transform()); typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types; vertex_converter<box2d<double>, grid_rasterizer, polygon_pattern_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types> converter(query_extent_,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); if (prj_trans.equal() && sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true) converter.set<transform_tag>(); //always transform converter.set<affine_transform_tag>(); if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter for ( geometry_type & geom : feature.paths()) { if (geom.size() > 2) { converter.apply(geom); } } typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type; grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); // render id ren.color(color_type(feature.id())); agg::scanline_bin sl; ras_ptr->filling_rule(agg::fill_even_odd); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void hit_grid<T>::add_feature(mapnik::feature_impl const& feature) { value_type feature_id = feature.id(); // avoid adding duplicate features (e.g. in the case of both a line symbolizer and a polygon symbolizer) typename feature_key_type::const_iterator feature_pos = f_keys_.find(feature_id); if (feature_pos != f_keys_.end()) { return; } if (ctx_->size() == 0) { context_type::map_type::const_iterator itr = feature.context()->begin(); context_type::map_type::const_iterator end = feature.context()->end(); for ( ;itr!=end; ++itr) { ctx_->add(itr->first,itr->second); } } // NOTE: currently lookup keys must be strings, // but this should be revisited lookup_type lookup_value; if (key_ == id_name_) { mapnik::util::to_string(lookup_value,feature_id); } else { if (feature.has_key(key_)) { lookup_value = feature.get(key_).to_string(); } else { MAPNIK_LOG_DEBUG(grid) << "hit_grid: Should not get here: key '" << key_ << "' not found in feature properties"; } } if (!lookup_value.empty()) { // TODO - consider shortcutting f_keys if feature_id == lookup_value // create a mapping between the pixel id and the feature key f_keys_.emplace(feature_id,lookup_value); // if extra fields have been supplied, push them into grid memory if (!names_.empty()) { // it is ~ 2x faster to copy feature attributes compared // to building up a in-memory cache of feature_ptrs // https://github.com/mapnik/mapnik/issues/1198 mapnik::feature_ptr feature2(mapnik::feature_factory::create(ctx_,feature_id)); feature2->set_data(feature.get_data()); features_.emplace(lookup_value,feature2); } } else { MAPNIK_LOG_DEBUG(grid) << "hit_grid: Warning - key '" << key_ << "' was blank for " << feature; } }
void start_tile_feature(mapnik::feature_impl const& feature) { current_feature_ = current_layer_->add_features(); x_ = y_ = 0; // TODO - encode as sint64: (n << 1) ^ ( n >> 63) // test current behavior with negative numbers current_feature_->set_id(feature.id()); feature_kv_iterator itr = feature.begin(); feature_kv_iterator end = feature.end(); for ( ;itr!=end; ++itr) { std::string const& name = MAPNIK_GET<0>(*itr); mapnik::value const& val = MAPNIK_GET<1>(*itr); if (!val.is_null()) { // Insert the key index keys_container::const_iterator key_itr = keys_.find(name); if (key_itr == keys_.end()) { // The key doesn't exist yet in the dictionary. current_layer_->add_keys(name.c_str(), name.length()); size_t index = keys_.size(); keys_.insert(keys_container::value_type(name, index)); current_feature_->add_tags(index); } else { current_feature_->add_tags(key_itr->second); } // Insert the value index values_container::const_iterator val_itr = values_.find(val); if (val_itr == values_.end()) { // The value doesn't exist yet in the dictionary. to_tile_value visitor(current_layer_->add_values()); #if MAPNIK_VERSION >= 300000 MAPNIK_APPLY_VISITOR(visitor, val); #else MAPNIK_APPLY_VISITOR(visitor, val.base()); #endif size_t index = values_.size(); values_.insert(values_container::value_type(val, index)); current_feature_->add_tags(index); } else { current_feature_->add_tags(val_itr->second); } } } }
void grid_renderer<T>::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper( sym, feature, prj_trans, width_, height_, scale_factor_, t_, font_manager_, *detector_, query_extent_); bool placement_found = false; text_renderer<T> ren(pixmap_, font_manager_, sym.get_halo_rasterizer(), sym.comp_op(), scale_factor_); text_placement_info_ptr placement; while (helper.next()) { placement_found = true; placements_type const& placements = helper.placements(); for (unsigned int ii = 0; ii < placements.size(); ++ii) { // get_marker_position returns (minx,miny) corner position, // while (currently only) agg_renderer::render_marker newly // expects center position; // until all renderers and shield_symbolizer_helper are // modified accordingly, we must adjust the position here pixel_position pos = helper.get_marker_position(placements[ii]); pos.x += 0.5 * helper.get_marker_width(); pos.y += 0.5 * helper.get_marker_height(); render_marker(feature, pixmap_.get_resolution(), pos, helper.get_marker(), helper.get_image_transform(), sym.get_opacity(), sym.comp_op()); ren.prepare_glyphs(placements[ii]); ren.render_id(feature.id(), placements[ii].center); } } if (placement_found) pixmap_.add_feature(feature); }
void grid_renderer<T>::process(polygon_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type; typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; ras_ptr->reset(); agg::trans_affine tr; evaluate_transform(tr, feature, sym.get_transform(), scale_factor_); typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types; vertex_converter<box2d<double>, grid_rasterizer, polygon_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types> converter(query_extent_,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); if (prj_trans.equal() && sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true) converter.set<transform_tag>(); //always transform converter.set<affine_transform_tag>(); if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter for ( geometry_type & geom : feature.paths()) { if (geom.size() > 2) { converter.apply(geom); } } grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); // render id ren.color(color_type(feature.id())); agg::scanline_bin sl; ras_ptr->filling_rule(agg::fill_even_odd); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void grid_renderer<T>::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { 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_); text_symbolizer_helper helper( sym, feature, common_.vars_, prj_trans, common_.width_, common_.height_, common_.scale_factor_, common_.t_, common_.font_manager_, *common_.detector_, common_.query_extent_, tr); bool placement_found = false; composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over); double opacity = get<double>(sym, keys::opacity, feature, common_.vars_, 1.0); grid_text_renderer<T> ren(pixmap_, comp_op, common_.scale_factor_); placements_list const& placements = helper.get(); value_integer feature_id = feature.id(); for (auto const& glyphs : placements) { marker_info_ptr mark = glyphs->get_marker(); if (mark) { render_marker(feature, glyphs->marker_pos(), *mark->marker_, mark->transform_, opacity, comp_op); } ren.render(*glyphs, feature_id); placement_found = true; } if (placement_found) { pixmap_.add_feature(feature); } }
void grid_renderer<T>::process(text_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { box2d<double> clip_box = clipping_extent(common_); 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_); text_symbolizer_helper helper( sym, feature, common_.vars_, prj_trans, common_.width_, common_.height_, common_.scale_factor_, common_.t_, common_.font_manager_, *common_.detector_, clip_box, tr, common_.symbol_cache_); bool placement_found = false; composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over); grid_text_renderer<T> ren(pixmap_, comp_op, common_.scale_factor_); auto halo_transform = get_optional<transform_type>(sym, keys::halo_transform); if (halo_transform) { agg::trans_affine halo_affine_transform; evaluate_transform(halo_affine_transform, feature, common_.vars_, *halo_transform, common_.scale_factor_); ren.set_halo_transform(halo_affine_transform); } placements_list const& placements = helper.get(); value_integer feature_id = feature.id(); for (auto const& glyphs : placements) { ren.render(*glyphs, feature_id); placement_found = true; } if (placement_found) { pixmap_.add_feature(feature); } }
void grid_renderer<T>::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { text_symbolizer_helper helper( sym, feature, common_.vars_, prj_trans, common_.width_, common_.height_, common_.scale_factor_, common_.t_, common_.font_manager_, *common_.detector_, common_.query_extent_); bool placement_found = false; composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over); double opacity = get<double>(sym, keys::opacity, feature, common_.vars_, 1.0); grid_text_renderer<T> ren(pixmap_, comp_op, common_.scale_factor_); placements_list const& placements = helper.get(); value_integer feature_id = feature.id(); for (glyph_positions_ptr glyphs : placements) { if (glyphs->marker()) { render_marker(feature, pixmap_.get_resolution(), glyphs->marker_pos(), *(glyphs->marker()->marker), glyphs->marker()->transform, opacity, comp_op); } ren.render(*glyphs, feature_id); placement_found = true; } if (placement_found) { pixmap_.add_feature(feature); } }
void grid_renderer<T>::process(polygon_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using vertex_converter_type = vertex_converter<transform2_tag, clip_poly_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag, contour_tag>; ras_ptr->reset(); grid_rendering_buffer buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); render_polygon_symbolizer<vertex_converter_type>( sym, feature, prj_trans, common_, common_.query_extent_, *ras_ptr, [&](color const &, double) { pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); // render id ren.color(color_type(feature.id())); agg::scanline_bin sl; ras_ptr->filling_rule(agg::fill_non_zero); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }); }
void grid_renderer<T>::render_marker(mapnik::feature_impl & feature, unsigned int step, pixel_position const& pos, marker const& marker, agg::trans_affine const& tr, double opacity, composite_mode_e comp_op) { if (marker.is_vector()) { typedef coord_transform<CoordTransform,geometry_type> path_type; typedef agg::renderer_base<mapnik::pixfmt_gray32> ren_base; typedef agg::renderer_scanline_bin_solid<ren_base> renderer; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); mapnik::pixfmt_gray32 pixf(buf); ren_base renb(pixf); renderer ren(renb); ras_ptr->reset(); box2d<double> const& bbox = (*marker.get_vector_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(scale_factor_*(1.0/step)); // 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_vector_data())->source()); svg_path_adapter svg_path(stl_storage); svg_renderer_agg<svg_path_adapter, agg::pod_bvector<path_attributes>, renderer, mapnik::pixfmt_gray32> svg_renderer(svg_path, (*marker.get_vector_data())->attributes()); svg_renderer.render_id(*ras_ptr, sl, renb, feature.id(), mtx, opacity, bbox); } else { image_data_32 const& data = **marker.get_bitmap_data(); double width = data.width(); double height = data.height(); double cx = 0.5 * width; double cy = 0.5 * height; if (step == 1 && (std::fabs(1.0 - scale_factor_) < 0.001 && tr.is_identity())) { // TODO - support opacity pixmap_.set_rectangle(feature.id(), data, boost::math::iround(pos.x - cx), boost::math::iround(pos.y - cy)); } else { // TODO - remove support for step != or add support for agg scaling with opacity double ratio = (1.0/step); image_data_32 target(ratio * data.width(), ratio * data.height()); mapnik::scale_image_agg<image_data_32>(target,data, SCALING_NEAR, scale_factor_, 0.0, 0.0, 1.0, ratio); pixmap_.set_rectangle(feature.id(), target, boost::math::iround(pos.x - cx), boost::math::iround(pos.y - cy)); } } pixmap_.add_feature(feature); }
void grid_renderer<T>::process(line_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_); if (filename.empty()) return; boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true); if (!mark) return; if (!(*mark)->is_bitmap()) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer"; return; } boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); if (!pat) return; bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false); typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type; typedef boost::mpl::vector<clip_line_tag, transform_tag, offset_transform_tag, affine_transform_tag, simplify_tag, smooth_tag, stroke_tag> conv_types; 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(); int stroke_width = (*pat)->width(); 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> clipping_extent = common_.query_extent_; if (clip) { double padding = (double)(common_.query_extent_.width()/pixmap_.width()); double half_stroke = stroke_width/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(offset) > 0) padding *= std::fabs(offset) * 1.2; padding *= common_.scale_factor_; clipping_extent.pad(padding); } // to avoid the complexity of using an agg pattern filter instead // we create a line_symbolizer in order to fake the pattern line_symbolizer line; put<value_double>(line, keys::stroke_width, value_double(stroke_width)); // TODO: really should pass the offset to the fake line too, but // this wasn't present in the previous version and makes the test // fail - in this case, probably the test should be updated. //put<value_double>(line, keys::offset, value_double(offset)); put<value_double>(line, keys::simplify_tolerance, value_double(simplify_tolerance)); put<value_double>(line, keys::smooth, value_double(smooth)); vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> converter(clipping_extent,*ras_ptr,line,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) converter.set<transform_tag>(); // always transform if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset 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 converter.set<stroke_tag>(); //always stroke for (geometry_type & geom : feature.paths()) { if (geom.size() > 1) { converter.apply(geom); } } // render id ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void grid_renderer<T>::process(line_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_); if (filename.empty()) return; std::shared_ptr<mapnik::marker const> mark = marker_cache::instance().find(filename, true); if (mark->is<mapnik::marker_null>()) return; if (!mark->is<mapnik::marker_rgba8>()) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer"; return; } 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_); using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_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(); line_pattern_enum pattern = get<line_pattern_enum, keys::line_pattern>(sym, feature, common_.vars_); std::size_t stroke_width = (pattern == LINE_PATTERN_WARP) ? mark->width() : get<value_double, keys::stroke_width>(sym, feature, common_.vars_); 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> clipping_extent = common_.query_extent_; if (clip) { double pad_per_pixel = static_cast<double>(common_.query_extent_.width()/common_.width_); double pixels = std::ceil(std::max(stroke_width / 2.0 + std::fabs(offset), (std::fabs(offset) * offset_converter_default_threshold))); double padding = pad_per_pixel * pixels * common_.scale_factor_; clipping_extent.pad(padding); } // to avoid the complexity of using an agg pattern filter instead // we create a line_symbolizer in order to fake the pattern line_symbolizer line; put<value_double>(line, keys::stroke_width, value_double(stroke_width)); // TODO: really should pass the offset to the fake line too, but // this wasn't present in the previous version and makes the test // fail - in this case, probably the test should be updated. //put<value_double>(line, keys::offset, value_double(offset)); put<value_double>(line, keys::simplify_tolerance, value_double(simplify_tolerance)); put<value_double>(line, keys::smooth, value_double(smooth)); using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag, affine_transform_tag, simplify_tag,smooth_tag, offset_transform_tag,stroke_tag>; vertex_converter_type converter(clipping_extent,line,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 (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset 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 converter.set<stroke_tag>(); //always stroke using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type,grid_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()); // render id ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void grid_renderer<T>::process(line_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; using conv_types = boost::mpl::vector<clip_line_tag, transform_tag, offset_transform_tag, affine_transform_tag, simplify_tag, smooth_tag, dash_tag, stroke_tag>; 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(); 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> clipping_extent = common_.query_extent_; bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true); double width = get<value_double>(sym, keys::stroke_width, feature, common_.vars_,1.0); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_,0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_,0.0); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_,false); bool has_dash = has_key<dash_array>(sym, keys::stroke_dasharray); if (clip) { double padding = (double)(common_.query_extent_.width()/pixmap_.width()); double half_stroke = width/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(offset) > 0) padding *= std::fabs(offset) * 1.2; padding *= common_.scale_factor_; clipping_extent.pad(padding); } vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> converter(clipping_extent,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) converter.set<transform_tag>(); // always transform if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset 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 if (has_dash) converter.set<dash_tag>(); converter.set<stroke_tag>(); //always stroke for ( geometry_type & geom : feature.paths()) { if (geom.size() > 1) { converter.apply(geom); } } // render id ren.color(color_type(feature.id())); ras_ptr->filling_rule(agg::fill_non_zero); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void grid_renderer<T>::process(line_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_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(); 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> clipping_extent = common_.query_extent_; bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, false); double width = get<value_double>(sym, keys::stroke_width, feature, common_.vars_,1.0); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_,0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_,0.0); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_,false); bool has_dash = has_key(sym, keys::stroke_dasharray); if (clip) { double padding = (double)(common_.query_extent_.width()/pixmap_.width()); double half_stroke = width/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(offset) > 0) padding *= std::fabs(offset) * 1.2; padding *= common_.scale_factor_; clipping_extent.pad(padding); } using vertex_converter_type = vertex_converter<clip_line_tag, clip_poly_tag, transform_tag, affine_transform_tag, simplify_tag, smooth_tag, offset_transform_tag, dash_tag, stroke_tag>; vertex_converter_type converter(clipping_extent,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (clip) { 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.set<transform_tag>(); // always transform if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset 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 if (has_dash) converter.set<dash_tag>(); converter.set<stroke_tag>(); //always stroke using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, grid_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()); // render id ren.color(color_type(feature.id())); ras_ptr->filling_rule(agg::fill_non_zero); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_); if (filename.empty()) return; boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true); if (!mark) return; if (!(*mark)->is_bitmap()) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer"; return; } boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); if (!pat) return; ras_ptr->reset(); bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false); 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 conv_types = boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag>; vertex_converter<box2d<double>, grid_rasterizer, polygon_pattern_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> converter(common_.query_extent_,*ras_ptr,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); } } using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; 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); // render id ren.color(color_type(feature.id())); agg::scanline_bin sl; ras_ptr->filling_rule(agg::fill_even_odd); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_); if (filename.empty()) return; mapnik::marker const& mark = marker_cache::instance().find(filename, true); if (mark.is<mapnik::marker_null>()) return; if (!mark.is<mapnik::marker_rgba8>()) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer"; return; } ras_ptr->reset(); 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_); 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,smooth_tag>; vertex_converter_type converter(common_.query_extent_,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 using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, grid_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()); using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using color_type = typename grid_renderer_base_type::pixfmt_type::color_type; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; 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); // render id ren.color(color_type(feature.id())); agg::scanline_bin sl; ras_ptr->filling_rule(agg::fill_even_odd); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void grid_renderer<T>::process(line_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type; typedef boost::mpl::vector<clip_line_tag, transform_tag, offset_transform_tag, affine_transform_tag, simplify_tag, smooth_tag, dash_tag, stroke_tag> conv_types; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); ras_ptr->reset(); stroke const& stroke_ = sym.get_stroke(); agg::trans_affine tr; evaluate_transform(tr, feature, sym.get_transform(), scale_factor_); box2d<double> clipping_extent = query_extent_; if (sym.clip()) { double padding = (double)(query_extent_.width()/pixmap_.width()); double half_stroke = stroke_.get_width()/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(sym.offset()) > 0) padding *= std::fabs(sym.offset()) * 1.2; padding *= scale_factor_; clipping_extent.pad(padding); } vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types> converter(clipping_extent,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true) converter.set<transform_tag>(); // always transform if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset converter.set<affine_transform_tag>(); // optional affine transform if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (stroke_.has_dash()) converter.set<dash_tag>(); converter.set<stroke_tag>(); //always stroke for ( geometry_type & geom : feature.paths()) { if (geom.size() > 1) { converter.apply(geom); } } // render id ren.color(color_type(feature.id())); ras_ptr->filling_rule(agg::fill_non_zero); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }
void grid_renderer<T>::process(line_pattern_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<marker_ptr> mark = marker_cache::instance().find(filename,true); if (!mark) return; if (!(*mark)->is_bitmap()) { MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer"; return; } boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); if (!pat) return; typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type; typedef boost::mpl::vector<clip_line_tag, transform_tag, offset_transform_tag, affine_transform_tag, simplify_tag, smooth_tag, stroke_tag> conv_types; agg::scanline_bin sl; grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); pixfmt_type pixf(buf); grid_renderer_base_type renb(pixf); renderer_type ren(renb); ras_ptr->reset(); int stroke_width = (*pat)->width(); agg::trans_affine tr; evaluate_transform(tr, feature, sym.get_transform(), scale_factor_); box2d<double> clipping_extent = query_extent_; if (sym.clip()) { double padding = (double)(query_extent_.width()/pixmap_.width()); double half_stroke = stroke_width/2.0; if (half_stroke > 1) padding *= half_stroke; if (std::fabs(sym.offset()) > 0) padding *= std::fabs(sym.offset()) * 1.2; padding *= scale_factor_; clipping_extent.pad(padding); } // to avoid the complexity of using an agg pattern filter instead // we create a line_symbolizer in order to fake the pattern stroke str; str.set_width(stroke_width); line_symbolizer line(str); vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, CoordTransform, proj_transform, agg::trans_affine, conv_types> converter(clipping_extent,*ras_ptr,line,t_,prj_trans,tr,scale_factor_); if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true) converter.set<transform_tag>(); // always transform if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset converter.set<affine_transform_tag>(); // optional affine transform if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter converter.set<stroke_tag>(); //always stroke for (geometry_type & geom : feature.paths()) { if (geom.size() > 1) { converter.apply(geom); } } // render id ren.color(color_type(feature.id())); agg::render_scanlines(*ras_ptr, sl, ren); // add feature properties to grid cache pixmap_.add_feature(feature); }