From e7f0e8aac0158b44da6386f138599b1fe0b42eba Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Tue, 3 Apr 2012 19:49:57 +0100 Subject: [PATCH] + support configurable vertex converter --- include/mapnik/vertex_converters.hpp | 149 +++++++++++++------- src/agg/process_line_pattern_symbolizer.cpp | 3 +- src/agg/process_line_symbolizer.cpp | 111 +++------------ src/load_map.cpp | 4 +- 4 files changed, 122 insertions(+), 145 deletions(-) diff --git a/include/mapnik/vertex_converters.hpp b/include/mapnik/vertex_converters.hpp index 930ad5920..a5db00091 100644 --- a/include/mapnik/vertex_converters.hpp +++ b/include/mapnik/vertex_converters.hpp @@ -23,8 +23,9 @@ #ifndef MAPNIK_VERTEX_CONVERTERS_HPP #define MAPNIK_VERTEX_CONVERTERS_HPP +// boost #include - +// mpl #include #include #include @@ -35,7 +36,6 @@ #include #include #include - // fusion #include #include @@ -46,11 +46,15 @@ #include #include +// mapnik +#include + // agg #include "agg_conv_clip_polygon.h" #include "agg_conv_clip_polyline.h" #include "agg_conv_smooth_poly1.h" - +#include "agg_conv_stroke.h" +#include "agg_conv_dash.h" namespace mapnik { @@ -58,6 +62,8 @@ struct transform_tag {}; struct clip_line_tag {}; struct clip_poly_tag {}; struct smooth_tag {}; +struct stroke_tag {}; +struct dash_tag {}; namespace detail { @@ -67,7 +73,7 @@ struct converter_traits typedef T0 geometry_type; typedef geometry_type conv_type; template - static void setup(geometry_type & geom, Args & args) + static void setup(geometry_type & geom, Args & args) { throw "BOOM!"; } @@ -76,11 +82,11 @@ struct converter_traits template struct converter_traits { - typedef T geometry_type; + typedef T geometry_type; typedef typename agg::conv_smooth_poly1_curve conv_type; - + template - static void setup(geometry_type & geom, Args & args) + static void setup(geometry_type & geom, Args & args) { geom.smooth_value(boost::fusion::at_c<2>(args).smooth()); } @@ -90,14 +96,57 @@ struct converter_traits template struct converter_traits { - typedef T geometry_type; + typedef T geometry_type; typedef typename agg::conv_clip_polyline conv_type; - + template - static void setup(geometry_type & geom, Args & args) + static void setup(geometry_type & geom, Args & args) { - typename boost::mpl::at >::type const& box = boost::fusion::at_c<0>(args); - geom.clip_box(box.x0,box.y0,box.x1,box.y1); + typename boost::mpl::at >::type const& box = boost::fusion::at_c<0>(args); + geom.clip_box(box.minx(),box.miny(),box.maxx(),box.maxy()); + } +}; + + +template +struct converter_traits +{ + typedef T geometry_type; + typedef typename agg::conv_dash conv_type; + + template + static void setup(geometry_type & geom, Args & args) + { + typename boost::mpl::at >::type const& sym = boost::fusion::at_c<2>(args); + double scale_factor = 1.0; //FIXME + stroke const& stroke_ = sym.get_stroke(); + dash_array const& d = stroke_.get_dash_array(); + dash_array::const_iterator itr = d.begin(); + dash_array::const_iterator end = d.end(); + for (;itr != end;++itr) + { + geom.add_dash(itr->first * scale_factor, + itr->second * scale_factor); + } + + } +}; + +template +struct converter_traits +{ + typedef T geometry_type; + typedef typename agg::conv_stroke conv_type; + + template + static void setup(geometry_type & geom, Args & args) + { + typename boost::mpl::at >::type const& sym = boost::fusion::at_c<2>(args); + stroke const& stroke_ = sym.get_stroke(); + set_join_caps(stroke_,geom); + geom.generator().miter_limit(4.0); // FIXME : make configurable + double scale_factor = 1.0; //FIXME + geom.generator().width(stroke_.get_width() * scale_factor); } }; @@ -105,13 +154,13 @@ struct converter_traits template struct converter_traits { - typedef T geometry_type; + typedef T geometry_type; typedef typename agg::conv_clip_polygon conv_type; - + template - static void setup(geometry_type & geom, Args & args) + static void setup(geometry_type & geom, Args & args) { - typename boost::mpl::at >::type const& box = boost::fusion::at_c<0>(args); + typename boost::mpl::at >::type const& box = boost::fusion::at_c<0>(args); geom.clip_box(box.minx(),box.miny(),box.maxx(),box.maxy()); } }; @@ -120,11 +169,11 @@ struct converter_traits template struct converter_traits { - typedef T geometry_type; + typedef T geometry_type; typedef coord_transform2 conv_type; - + template - static void setup(geometry_type & geom, Args & args) + static void setup(geometry_type & geom, Args & args) { typename boost::mpl::at >::type const& tr = boost::fusion::at_c<3>(args); typename boost::mpl::at >::type const& prj_trans = boost::fusion::at_c<4>(args); @@ -137,65 +186,65 @@ template struct converter_fwd { template - static void forward(Base& base, T0 & geom,T1 & args) + static void forward(Base& base, T0 & geom,T1 & args) { typedef T0 geometry_type; typedef T2 conv_tag; typedef typename detail::converter_traits::conv_type conv_type; conv_type conv(geom); - detail::converter_traits::setup(conv,args); + detail::converter_traits::setup(conv,args); base.template dispatch(conv, typename boost::is_same::type()); - } + } }; template <> struct converter_fwd { template - static void forward(Base& base, T0 & geom,T1 & args) + static void forward(Base& base, T0 & geom,T1 & args) { base.template dispatch(geom, typename boost::is_same::type()); - } + } }; template -struct dispatcher +struct dispatcher { - typedef dispatcher this_type; + typedef dispatcher this_type; typedef A args_type; typedef C conv_types; - + dispatcher(args_type args) - : args_(args) + : args_(args) { std::memset(&vec_[0], 0, sizeof(unsigned)*vec_.size()); } - - template + + template void dispatch(Geometry & geom, boost::mpl::true_) - { + { boost::fusion::at_c<1>(args_).add_path(geom); } - + template void dispatch(Geometry & geom, boost::mpl::false_) { typedef typename boost::mpl::deref::type conv_tag; typedef typename detail::converter_traits::conv_type conv_type; typedef typename boost::mpl::next::type Next; - + std::size_t index = boost::mpl::distance::value - 1; if (vec_[index] == 1) { converter_fwd::value>:: template forward(*this,geom,args_); } - else + else { converter_fwd:: - template forward(*this,geom,args_); + template forward(*this,geom,args_); } - + } template @@ -203,11 +252,11 @@ struct dispatcher { typedef typename boost::mpl::begin::type begin; typedef typename boost::mpl::end ::type end; - dispatch(geom, boost::false_type()); + dispatch(geom, boost::false_type()); } boost::array::value> vec_; - args_type args_; + args_type args_; }; } @@ -215,7 +264,7 @@ struct dispatcher template struct vertex_converter : private boost::noncopyable -{ +{ typedef C conv_types; typedef B bbox_type; typedef R rasterizer_type; @@ -224,29 +273,29 @@ struct vertex_converter : private boost::noncopyable typedef T trans_type; typedef typename boost::fusion::vector < - bbox_type const&, - rasterizer_type&, + bbox_type const&, + rasterizer_type&, symbolizer_type const&, trans_type const&, - proj_trans_type const& + proj_trans_type const& > args_type; - - vertex_converter(bbox_type const& b, rasterizer_type & ras, + + vertex_converter(bbox_type const& b, rasterizer_type & ras, symbolizer_type const& sym, trans_type & tr, proj_trans_type const& prj_trans) : disp_(args_type(boost::cref(b),boost::ref(ras), boost::cref(sym),boost::cref(tr), boost::cref(prj_trans))) {} - + template void apply(Geometry & geom) - { + { typedef Geometry geometry_type; //BOOST_FOREACH(geometry_type & geom, cont) - { + { disp_.template apply(geom); } } - + template void set() { @@ -256,8 +305,8 @@ struct vertex_converter : private boost::noncopyable if (index < disp_.vec_.size()) disp_.vec_[index]=1; } - - + + detail::dispatcher disp_; }; diff --git a/src/agg/process_line_pattern_symbolizer.cpp b/src/agg/process_line_pattern_symbolizer.cpp index 0a00df1fe..ead7c9520 100644 --- a/src/agg/process_line_pattern_symbolizer.cpp +++ b/src/agg/process_line_pattern_symbolizer.cpp @@ -83,8 +83,7 @@ void agg_renderer::process(line_pattern_symbolizer const& sym, pattern_source source(*(*pat)); pattern_type pattern (filter,source); renderer_type ren(ren_base, pattern); - // TODO - should be sensitive to buffer size - ren.clip_box(0,0,width_,height_); + rasterizer_type ras(ren); //metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;inum_geometries();++i) diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index bb8c7c6b4..83b09d439 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -26,7 +26,7 @@ #include #include #include - +#include // agg #include "agg_basics.h" #include "agg_rendering_buffer.h" @@ -39,8 +39,6 @@ #include "agg_conv_dash.h" #include "agg_renderer_outline_aa.h" #include "agg_rasterizer_outline_aa.h" -#include "agg_conv_clip_polyline.h" -#include "agg_conv_smooth_poly1.h" // stl #include @@ -65,13 +63,16 @@ void agg_renderer::process(line_symbolizer const& sym, //agg::pixfmt_rgba32 pixf(buf); aa_renderer::pixel_format_type pixf(buf); box2d ext = query_extent_ * 1.1; + if (sym.get_rasterizer() == RASTERIZER_FAST) { + /* typedef agg::renderer_base ren_base; typedef agg::renderer_outline_aa renderer_type; typedef agg::rasterizer_outline_aa rasterizer_type; - typedef agg::conv_clip_polyline clipped_geometry_type; - typedef coord_transform2 path_type; + + //typedef agg::conv_clip_polyline clipped_geometry_type; + //typedef coord_transform2 path_type; agg::line_profile_aa profile; profile.width(stroke_.get_width() * scale_factor_); @@ -82,7 +83,7 @@ void agg_renderer::process(line_symbolizer const& sym, rasterizer_type ras(ren); ras.line_join(agg::outline_miter_accurate_join); ras.round_cap(true); - + for (unsigned i=0;inum_geometries();++i) { geometry_type & geom = feature->get_geometry(i); @@ -94,6 +95,7 @@ void agg_renderer::process(line_symbolizer const& sym, ras.add_path(path); } } + */ } else { @@ -103,96 +105,23 @@ void agg_renderer::process(line_symbolizer const& sym, ren.attach(pixf); //metawriter_with_properties writer = sym.get_metawriter(); - + typedef boost::mpl::vector conv_types; + vertex_converter,rasterizer,line_symbolizer, proj_transform, CoordTransform,conv_types> + converter(ext,*ras_ptr,sym,t_,prj_trans); + + //if (sym.clip()) + converter.set(); //FIXME make an optinal clip (default: true) + converter.set(); //always transform + if (sym.smooth() > 0.0) converter.set(); // optional smooth converter + if (stroke_.has_dash()) converter.set(); + converter.set(); //always stroke + for (unsigned i=0;inum_geometries();++i) { geometry_type & geom = feature->get_geometry(i); if (geom.num_points() > 1) { - if (stroke_.has_dash()) - { - if (sym.smooth() > 0.0) - { - typedef agg::conv_clip_polyline clipped_geometry_type; - typedef coord_transform2 path_type; - typedef agg::conv_smooth_poly1_curve smooth_type; - clipped_geometry_type clipped(geom); - clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); - path_type path(t_,clipped,prj_trans); - smooth_type smooth(path); - smooth.smooth_value(sym.smooth()); - agg::conv_dash dash(smooth); - dash_array const& d = stroke_.get_dash_array(); - dash_array::const_iterator itr = d.begin(); - dash_array::const_iterator end = d.end(); - for (;itr != end;++itr) - { - dash.add_dash(itr->first * scale_factor_, - itr->second * scale_factor_); - } - agg::conv_stroke > stroke(dash); - set_join_caps(stroke_,stroke); - stroke.generator().miter_limit(4.0); - stroke.generator().width(stroke_.get_width() * scale_factor_); - ras_ptr->add_path(stroke); - } - else - { - typedef agg::conv_clip_polyline clipped_geometry_type; - typedef coord_transform2 path_type; - clipped_geometry_type clipped(geom); - clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); - path_type path(t_,clipped,prj_trans); - - agg::conv_dash dash(path); - dash_array const& d = stroke_.get_dash_array(); - dash_array::const_iterator itr = d.begin(); - dash_array::const_iterator end = d.end(); - for (;itr != end;++itr) - { - dash.add_dash(itr->first * scale_factor_, - itr->second * scale_factor_); - } - agg::conv_stroke > stroke(dash); - set_join_caps(stroke_,stroke); - stroke.generator().miter_limit(4.0); - stroke.generator().width(stroke_.get_width() * scale_factor_); - ras_ptr->add_path(stroke); - } - } - else - { - if (sym.smooth() > 0.0) - { - typedef agg::conv_clip_polyline clipped_geometry_type; - typedef coord_transform2 path_type; - typedef agg::conv_smooth_poly1_curve smooth_type; - clipped_geometry_type clipped(geom); - clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); - path_type path(t_,clipped,prj_trans); - smooth_type smooth(path); - smooth.smooth_value(sym.smooth()); - agg::conv_stroke stroke(smooth); - set_join_caps(stroke_,stroke); - stroke.generator().miter_limit(4.0); - stroke.generator().width(stroke_.get_width() * scale_factor_); - ras_ptr->add_path(stroke); - } - else - { - typedef agg::conv_clip_polyline clipped_geometry_type; - typedef coord_transform2 path_type; - clipped_geometry_type clipped(geom); - clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); - path_type path(t_,clipped,prj_trans); - agg::conv_stroke stroke(path); - set_join_caps(stroke_,stroke); - stroke.generator().miter_limit(4.0); - stroke.generator().width(stroke_.get_width() * scale_factor_); - ras_ptr->add_path(stroke); - } - //if (writer.first) writer.first->add_line(path, *feature, t_, writer.second); - } + converter.apply(geom); } } diff --git a/src/load_map.cpp b/src/load_map.cpp index 3678c6feb..e97ce7528 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -1326,8 +1326,8 @@ void map_parser::parse_polygon_symbolizer(rule & rule, xml_node const & sym) if (smooth) poly_sym.set_smooth(*smooth); // to clip or not to clip value - optional clip = sym.get_opt_attr("clip"); - if (clip) poly_sym.set_clip(*clip); + //optional clip = sym.get_opt_attr("clip"); + //if (clip) poly_sym.set_clip(*clip); parse_metawriter_in_symbolizer(poly_sym, sym); rule.append(poly_sym);