Merge remote-tracking branch 'origin/master'

This commit is contained in:
Artem Pavlenko 2012-05-14 17:33:45 +01:00
commit 9599711e0e
8 changed files with 153 additions and 35 deletions

View file

@ -42,12 +42,19 @@ struct line_symbolizer_pickle_suite : boost::python::pickle_suite
void export_line_symbolizer() void export_line_symbolizer()
{ {
using namespace boost::python; using namespace boost::python;
enumeration_<line_rasterizer_e>("line_rasterizer")
.value("FULL",RASTERIZER_FULL)
.value("FAST",RASTERIZER_FAST)
;
class_<line_symbolizer>("LineSymbolizer", class_<line_symbolizer>("LineSymbolizer",
init<>("Default LineSymbolizer - 1px solid black")) init<>("Default LineSymbolizer - 1px solid black"))
.def(init<stroke const&>("TODO")) .def(init<stroke const&>("TODO"))
.def(init<color const& ,float>()) .def(init<color const& ,float>())
.def_pickle(line_symbolizer_pickle_suite()) .def_pickle(line_symbolizer_pickle_suite())
.add_property("rasterizer",
&line_symbolizer::get_rasterizer,
&line_symbolizer::set_rasterizer,
"Set/get the rasterization method of the line of the point")
.add_property("stroke",make_function .add_property("stroke",make_function
(&line_symbolizer::get_stroke, (&line_symbolizer::get_stroke,
return_value_policy<copy_const_reference>()), return_value_policy<copy_const_reference>()),

View file

@ -32,6 +32,7 @@
#include "agg_scanline_p.h" #include "agg_scanline_p.h"
#include "agg_renderer_outline_aa.h" #include "agg_renderer_outline_aa.h"
#include "agg_renderer_scanline.h" #include "agg_renderer_scanline.h"
#include "agg_rasterizer_outline_aa.h"
namespace mapnik { namespace mapnik {
@ -94,6 +95,40 @@ void set_join_caps(Stroke const& stroke_, PathType & stroke)
} }
template <typename Stroke,typename Rasterizer>
void set_join_caps_aa(Stroke const& stroke_, Rasterizer & ras)
{
line_join_e join=stroke_.get_line_join();
switch (join)
{
case MITER_JOIN:
ras.line_join(agg::outline_miter_accurate_join);
break;
case MITER_REVERT_JOIN:
ras.line_join(agg::outline_no_join);
break;
case ROUND_JOIN:
ras.line_join(agg::outline_round_join);
break;
default:
ras.line_join(agg::outline_no_join);
}
line_cap_e cap=stroke_.get_line_cap();
switch (cap)
{
case BUTT_CAP:
ras.round_cap(false);
break;
case SQUARE_CAP:
ras.round_cap(false);
break;
default:
ras.round_cap(true);
}
}
template <typename PixelFormat> template <typename PixelFormat>
struct renderer_scanline_solid : private boost::noncopyable struct renderer_scanline_solid : private boost::noncopyable
{ {

View file

@ -31,24 +31,36 @@
namespace mapnik namespace mapnik
{ {
enum line_rasterizer_enum {
RASTERIZER_FULL, // agg::renderer_scanline_aa_solid
RASTERIZER_FAST, // agg::rasterizer_outline_aa, twice as fast but only good for thin lines
line_rasterizer_enum_MAX
};
DEFINE_ENUM( line_rasterizer_e, line_rasterizer_enum );
struct MAPNIK_DECL line_symbolizer : public symbolizer_base struct MAPNIK_DECL line_symbolizer : public symbolizer_base
{ {
explicit line_symbolizer() explicit line_symbolizer()
: symbolizer_base(), : symbolizer_base(),
stroke_(), stroke_(),
offset_(0.0) offset_(0.0),
rasterizer_p_(RASTERIZER_FULL)
{} {}
line_symbolizer(stroke const& stroke) line_symbolizer(stroke const& stroke)
: symbolizer_base(), : symbolizer_base(),
stroke_(stroke), stroke_(stroke),
offset_(0.0) offset_(0.0),
rasterizer_p_(RASTERIZER_FULL)
{} {}
line_symbolizer(color const& pen,float width=1.0) line_symbolizer(color const& pen,float width=1.0)
: symbolizer_base(), : symbolizer_base(),
stroke_(pen,width), stroke_(pen,width),
offset_(0.0) offset_(0.0),
rasterizer_p_(RASTERIZER_FULL)
{} {}
stroke const& get_stroke() const stroke const& get_stroke() const
@ -70,10 +82,21 @@ struct MAPNIK_DECL line_symbolizer : public symbolizer_base
{ {
return offset_; return offset_;
} }
void set_rasterizer(line_rasterizer_e rasterizer_p)
{
rasterizer_p_ = rasterizer_p;
}
line_rasterizer_e get_rasterizer() const
{
return rasterizer_p_;
}
private: private:
stroke stroke_; stroke stroke_;
double offset_; double offset_;
line_rasterizer_e rasterizer_p_;
}; };
} }

View file

@ -63,45 +63,81 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
ras_ptr->reset(); ras_ptr->reset();
set_gamma_method(stroke_, ras_ptr); set_gamma_method(stroke_, ras_ptr);
typedef boost::mpl::vector<clip_line_tag,transform_tag, offset_transform_tag, affine_transform_tag, smooth_tag, dash_tag, stroke_tag> conv_types;
vertex_converter<box2d<double>,rasterizer,line_symbolizer, proj_transform, CoordTransform,conv_types>
converter(query_extent_,*ras_ptr,sym,t_,prj_trans,scale_factor_);
if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform
if (fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform
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
BOOST_FOREACH( geometry_type & geom, feature->paths())
{
if (geom.num_points() > 1)
{
converter.apply(geom);
}
}
agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4); agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4);
typedef agg::rgba8 color_type; typedef agg::rgba8 color_type;
typedef agg::order_rgba order_type; typedef agg::order_rgba order_type;
typedef agg::pixel32_type pixel_type; typedef agg::pixel32_type pixel_type;
typedef agg::comp_op_adaptor_rgba<color_type, order_type> blender_type; // comp blender typedef agg::comp_op_adaptor_rgba<color_type, order_type> blender_type; // comp blender
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type; typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type;
typedef agg::renderer_base<pixfmt_comp_type> renderer_base; typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
pixfmt_comp_type pixf(buf); pixfmt_comp_type pixf(buf);
pixf.comp_op(static_cast<agg::comp_op_e>(sym.comp_op()));
renderer_base renb(pixf); renderer_base renb(pixf);
renderer_type ren(renb);
ren.color(agg::rgba8(r, g, b, int(a * stroke_.get_opacity()))); if (sym.get_rasterizer() == RASTERIZER_FAST)
agg::scanline_u8 sl; {
agg::render_scanlines(*ras_ptr, sl, ren); typedef agg::renderer_outline_aa<renderer_base> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
// need to reduce width by half to match standard rasterizer look
double scaled = scale_factor_ * .5;
agg::line_profile_aa profile(stroke_.get_width() * scaled, agg::gamma_power(stroke_.get_gamma()));
renderer_type ren(renb, profile);
ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
rasterizer_type ras(ren);
set_join_caps_aa(stroke_,ras);
typedef boost::mpl::vector<clip_line_tag,transform_tag, offset_transform_tag, affine_transform_tag, smooth_tag, dash_tag, stroke_tag> conv_types;
vertex_converter<box2d<double>,rasterizer_type,line_symbolizer, proj_transform, CoordTransform,conv_types>
converter(query_extent_,ras,sym,t_,prj_trans,scaled);
if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform
if (fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform
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
BOOST_FOREACH( geometry_type & geom, feature->paths())
{
if (geom.num_points() > 1)
{
converter.apply(geom);
}
}
}
else
{
typedef boost::mpl::vector<clip_line_tag,transform_tag, offset_transform_tag, affine_transform_tag, smooth_tag, dash_tag, stroke_tag> conv_types;
vertex_converter<box2d<double>,rasterizer,line_symbolizer, proj_transform, CoordTransform,conv_types>
converter(query_extent_,*ras_ptr,sym,t_,prj_trans,scale_factor_);
if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform
if (fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform
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
BOOST_FOREACH( geometry_type & geom, feature->paths())
{
if (geom.num_points() > 1)
{
converter.apply(geom);
}
}
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
pixf.comp_op(static_cast<agg::comp_op_e>(sym.comp_op()));
renderer_base renb(pixf);
renderer_type ren(renb);
ren.color(agg::rgba8(r, g, b, int(a * stroke_.get_opacity())));
agg::scanline_u8 sl;
agg::render_scanlines(*ras_ptr, sl, ren);
}
} }

View file

@ -26,6 +26,13 @@
namespace mapnik namespace mapnik
{ {
//
static const char * line_rasterizer_strings[] = {
"full",
"fast",
""
};
IMPLEMENT_ENUM( line_rasterizer_e, line_rasterizer_strings )
} }

View file

@ -1430,7 +1430,10 @@ void map_parser::parse_line_symbolizer(rule & rule, xml_node const & sym)
// offset value // offset value
optional<double> offset = sym.get_opt_attr<double>("offset"); optional<double> offset = sym.get_opt_attr<double>("offset");
if (offset) symbol.set_offset(*offset); if (offset) symbol.set_offset(*offset);
line_rasterizer_e rasterizer = sym.get_attr<line_rasterizer_e>("rasterizer", RASTERIZER_FULL);
symbol.set_rasterizer(rasterizer);
// meta-writer // meta-writer
parse_symbolizer_base(symbol, sym); parse_symbolizer_base(symbol, sym);
rule.append(symbol); rule.append(symbol);

View file

@ -84,6 +84,12 @@ public:
const stroke & strk = sym.get_stroke(); const stroke & strk = sym.get_stroke();
add_stroke_attributes(sym_node, strk); add_stroke_attributes(sym_node, strk);
add_metawriter_attributes(sym_node, sym); add_metawriter_attributes(sym_node, sym);
line_symbolizer dfl;
if ( sym.get_rasterizer() != dfl.get_rasterizer() || explicit_defaults_ )
{
set_attr( sym_node, "rasterizer", sym.get_rasterizer() );
}
} }
void operator () ( line_pattern_symbolizer const& sym ) void operator () ( line_pattern_symbolizer const& sym )

View file

@ -475,6 +475,7 @@ compile_get_attr(point_placement_e);
compile_get_attr(marker_placement_e); compile_get_attr(marker_placement_e);
compile_get_attr(marker_type_e); compile_get_attr(marker_type_e);
compile_get_attr(pattern_alignment_e); compile_get_attr(pattern_alignment_e);
compile_get_attr(line_rasterizer_e);
compile_get_attr(colorizer_mode); compile_get_attr(colorizer_mode);
compile_get_attr(double); compile_get_attr(double);
compile_get_value(int); compile_get_value(int);