diff --git a/include/ctrans.hpp b/include/ctrans.hpp index c0004f2b9..b1f16fcc1 100644 --- a/include/ctrans.hpp +++ b/include/ctrans.hpp @@ -27,7 +27,30 @@ namespace mapnik { typedef coord_array CoordinateArray; - + + template + struct coord_transform + { + coord_transform(Transform const& t,Geometry& geom) + : t_(t), geom_(geom) {} + + unsigned vertex(double *x , double *y) const + { + unsigned command = geom_.vertex(x,y); + *x = t_.forward_x_(x); + *y = t_.forward_y_(y); + return command; + } + void rewind (unsigned pos) + { + geom_.rewind(pos); + } + + private: + Transform const& t_; + Geometry& geom_; + }; + class CoordTransform { private: @@ -58,7 +81,17 @@ namespace mapnik { *y = (extent.maxy() - *y) * scale_; } + + inline double forward_x_(double* x) const + { + return (*x - extent.minx() ) * scale_; + } + inline double forward_y_(double* y) const + { + return (extent.maxy() - *y) * scale_; + } + inline void backward_x(double* x) const { *x = extent.minx() + *x/scale_; diff --git a/include/feature.hpp b/include/feature.hpp index 2f7f42326..8d2f8a3b5 100644 --- a/include/feature.hpp +++ b/include/feature.hpp @@ -77,7 +77,7 @@ namespace mapnik geom_=geom; } - geometry_type& get_geometry() + geometry_type const& get_geometry() const { return geom_; } diff --git a/include/image_symbolizer.hpp b/include/image_symbolizer.hpp index 6e3293629..267d2f6ad 100644 --- a/include/image_symbolizer.hpp +++ b/include/image_symbolizer.hpp @@ -34,8 +34,7 @@ namespace mapnik std::string const& type, unsigned width,unsigned height); - void render(geometry_type& geom,Image32& image) const; - + void render(Feature const& feat, CoordTransform const& t,Image32& image) const; private: ImageData32 symbol_; }; diff --git a/include/line_pattern_symbolizer.hpp b/include/line_pattern_symbolizer.hpp index d1e94a650..ea646dad8 100644 --- a/include/line_pattern_symbolizer.hpp +++ b/include/line_pattern_symbolizer.hpp @@ -32,8 +32,7 @@ namespace mapnik line_pattern_symbolizer(std::string const& file, std::string const& type, unsigned width,unsigned height); - void render(geometry_type& geom,Image32& image) const; - + void render(Feature const& feat, CoordTransform const& t,Image32& image) const; private: ImageData32 pattern_; }; diff --git a/include/line_symbolizer.hpp b/include/line_symbolizer.hpp index de8cf8cd5..6f3c536ac 100644 --- a/include/line_symbolizer.hpp +++ b/include/line_symbolizer.hpp @@ -34,7 +34,7 @@ namespace mapnik { line_symbolizer(stroke const& stroke); line_symbolizer(const Color& pen,float width=1.0); - void render(geometry_type& geom, Image32& image) const; + void render(Feature const& feat, CoordTransform const& t,Image32& image) const; private: stroke stroke_; }; diff --git a/include/polygon_pattern_symbolizer.hpp b/include/polygon_pattern_symbolizer.hpp index cd22e23e2..ed52d3669 100644 --- a/include/polygon_pattern_symbolizer.hpp +++ b/include/polygon_pattern_symbolizer.hpp @@ -33,8 +33,8 @@ namespace mapnik polygon_pattern_symbolizer(std::string const& file, std::string const& type, unsigned width,unsigned height); - - void render(geometry_type& geom,Image32& image) const; + + void render(Feature const& feat, CoordTransform const& t,Image32& image) const; private: ImageData32 pattern_; }; diff --git a/include/polygon_symbolizer.hpp b/include/polygon_symbolizer.hpp index 252917f02..3209c02a2 100644 --- a/include/polygon_symbolizer.hpp +++ b/include/polygon_symbolizer.hpp @@ -30,7 +30,7 @@ namespace mapnik private boost::noncopyable { polygon_symbolizer(const Color& fill); - void render(geometry_type& geom,Image32& image) const; + void render(Feature const& feat, CoordTransform const& t,Image32& image) const; private: Color fill_; }; diff --git a/include/symbolizer.hpp b/include/symbolizer.hpp index 630dfd1f3..fd093a6cb 100644 --- a/include/symbolizer.hpp +++ b/include/symbolizer.hpp @@ -22,6 +22,7 @@ #define SYMBOLIZER_HPP #include "graphics.hpp" +#include "feature.hpp" #include "geometry.hpp" #include @@ -31,7 +32,7 @@ namespace mapnik struct symbolizer { - virtual void render(geometry_type& geom, Image32& image) const=0; + virtual void render(Feature const& feat, CoordTransform const& t, Image32& image) const=0; virtual ~symbolizer() {} }; } diff --git a/src/image_symbolizer.cpp b/src/image_symbolizer.cpp index 7ff9e694b..d1a51922c 100644 --- a/src/image_symbolizer.cpp +++ b/src/image_symbolizer.cpp @@ -41,18 +41,24 @@ namespace mapnik } } - void image_symbolizer::render(geometry_type& geom,Image32& image) const + void image_symbolizer::render(Feature const& feat,CoordTransform const& t,Image32& image) const { - int w=symbol_.width(); - int h=symbol_.height(); - double x,y; - unsigned size = geom.num_points(); - for (unsigned pos = 0; pos < size ;++pos) + typedef coord_transform path_type; + geometry_ptr const& geom=feat.get_geometry(); + if (geom) { - geom.vertex(&x,&y); - int px=int(x - 0.5 * w); - int py=int(y - 0.5 * h); - image.set_rectangle_alpha(px,py,symbol_); + path_type path(t,*geom); + unsigned num_points=geom->num_points(); + int w=symbol_.width(); + int h=symbol_.height(); + double x,y; + for(unsigned i=0;i path_type; typedef agg::line_image_pattern pattern_type; typedef agg::renderer_base renderer_base; typedef agg::renderer_outline_image renderer_type; typedef agg::rasterizer_outline_aa rasterizer_type; - - unsigned int width=image.width(); - unsigned int height=image.height(); - agg::row_ptr_cache buf(image.raw_data(), width, height,width*4); - agg::pixfmt_rgba32 pixf(buf); - renderer_base ren_base(pixf); - agg::pattern_filter_bilinear_rgba8 filter; - pattern_source source(pattern_); - pattern_type pattern (filter,source); - renderer_type ren(ren_base, pattern); - ren.clip_box(0,0,width,height); - rasterizer_type ras(ren); - ras.add_path(geom); + + geometry_ptr const& geom=feat.get_geometry(); + if (geom) + { + path_type path(t,*geom); + unsigned int width=image.width(); + unsigned int height=image.height(); + agg::row_ptr_cache buf(image.raw_data(), width, height,width*4); + agg::pixfmt_rgba32 pixf(buf); + renderer_base ren_base(pixf); + agg::pattern_filter_bilinear_rgba8 filter; + pattern_source source(pattern_); + pattern_type pattern (filter,source); + renderer_type ren(ren_base, pattern); + ren.clip_box(0,0,width,height); + rasterizer_type ras(ren); + ras.add_path(path); + } } } diff --git a/src/line_symbolizer.cpp b/src/line_symbolizer.cpp index beb745ce8..978dfc908 100644 --- a/src/line_symbolizer.cpp +++ b/src/line_symbolizer.cpp @@ -52,109 +52,116 @@ namespace mapnik : symbolizer(), stroke_(pen,width) {} - void line_symbolizer::render(geometry_type& geom, Image32& image) const + void line_symbolizer::render(Feature const& feat, CoordTransform const& t,Image32& image) const { - typedef agg::renderer_base ren_base; - agg::row_ptr_cache buf(image.raw_data(),image.width(),image.height(), - image.width()*4); - agg::pixfmt_rgba32 pixf(buf); - ren_base renb(pixf); - - Color const& col = stroke_.get_color(); - unsigned r=col.red(); - unsigned g=col.green(); - unsigned b=col.blue(); - - if (0)//stroke_.get_width() <= 1.0) + typedef agg::renderer_base ren_base; + typedef coord_transform path_type; + geometry_ptr const& geom=feat.get_geometry(); + if (geom) { - typedef agg::renderer_outline_aa renderer_oaa; - typedef agg::rasterizer_outline_aa rasterizer_outline_aa; - agg::line_profile_aa prof; - prof.width(stroke_.get_width()); - renderer_oaa ren_oaa(renb, prof); - rasterizer_outline_aa ras_oaa(ren_oaa); + path_type path(t,*geom); + agg::row_ptr_cache buf(image.raw_data(),image.width(),image.height(), + image.width()*4); + agg::pixfmt_rgba32 pixf(buf); + ren_base renb(pixf); + + Color const& col = stroke_.get_color(); + unsigned r=col.red(); + unsigned g=col.green(); + unsigned b=col.blue(); + - ren_oaa.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); - ren_oaa.clip_box(0,0,image.width(),image.height()); - ras_oaa.add_path(geom); - - } - else - { - typedef agg::renderer_scanline_aa_solid renderer; - renderer ren(renb); - agg::rasterizer_scanline_aa<> ras; - agg::scanline_u8 sl; - - if (stroke_.has_dash()) + if (0)//stroke_.get_width() <= 1.0) { + typedef agg::renderer_outline_aa renderer_oaa; + typedef agg::rasterizer_outline_aa rasterizer_outline_aa; + agg::line_profile_aa prof; + prof.width(stroke_.get_width()); + renderer_oaa ren_oaa(renb, prof); + rasterizer_outline_aa ras_oaa(ren_oaa); - agg::conv_dash > dash(geom); - dash_array const& d = stroke_.get_dash_array(); - dash_array::const_iterator itr = d.begin(); - dash_array::const_iterator end = d.end(); - while (itr != end) - { - dash.add_dash(itr->first, itr->second); - ++itr; - } - agg::conv_stroke > > stroke(dash); + ren_oaa.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); + ren_oaa.clip_box(0,0,image.width(),image.height()); + ras_oaa.add_path(path); - line_join_e join=stroke_.get_line_join(); - if ( join == MITER_JOIN) - stroke.generator().line_join(agg::miter_join); - else if( join == MITER_REVERT_JOIN) - stroke.generator().line_join(agg::miter_join); - else if( join == ROUND_JOIN) - stroke.generator().line_join(agg::round_join); - else - stroke.generator().line_join(agg::bevel_join); - - line_cap_e cap=stroke_.get_line_cap(); - if (cap == BUTT_CAP) - stroke.generator().line_cap(agg::butt_cap); - else if (cap == SQUARE_CAP) - stroke.generator().line_cap(agg::square_cap); - else - stroke.generator().line_cap(agg::round_cap); - - stroke.generator().miter_limit(4.0); - stroke.generator().width(stroke_.get_width()); - - ras.clip_box(0,0,image.width(),image.height()); - ras.add_path(stroke); - ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); - agg::render_scanlines(ras, sl, ren); } else { - agg::conv_stroke > stroke(geom); + typedef agg::renderer_scanline_aa_solid renderer; + renderer ren(renb); + agg::rasterizer_scanline_aa<> ras; + agg::scanline_u8 sl; - line_join_e join=stroke_.get_line_join(); - if ( join == MITER_JOIN) - stroke.generator().line_join(agg::miter_join); - else if( join == MITER_REVERT_JOIN) - stroke.generator().line_join(agg::miter_join); - else if( join == ROUND_JOIN) - stroke.generator().line_join(agg::round_join); - else - stroke.generator().line_join(agg::bevel_join); + if (stroke_.has_dash()) + { - line_cap_e cap=stroke_.get_line_cap(); - if (cap == BUTT_CAP) - stroke.generator().line_cap(agg::butt_cap); - else if (cap == SQUARE_CAP) - stroke.generator().line_cap(agg::square_cap); + 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(); + while (itr != end) + { + dash.add_dash(itr->first, itr->second); + ++itr; + } + agg::conv_stroke > stroke(dash); + + line_join_e join=stroke_.get_line_join(); + if ( join == MITER_JOIN) + stroke.generator().line_join(agg::miter_join); + else if( join == MITER_REVERT_JOIN) + stroke.generator().line_join(agg::miter_join); + else if( join == ROUND_JOIN) + stroke.generator().line_join(agg::round_join); + else + stroke.generator().line_join(agg::bevel_join); + + line_cap_e cap=stroke_.get_line_cap(); + if (cap == BUTT_CAP) + stroke.generator().line_cap(agg::butt_cap); + else if (cap == SQUARE_CAP) + stroke.generator().line_cap(agg::square_cap); + else + stroke.generator().line_cap(agg::round_cap); + + stroke.generator().miter_limit(4.0); + stroke.generator().width(stroke_.get_width()); + + ras.clip_box(0,0,image.width(),image.height()); + ras.add_path(stroke); + ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); + agg::render_scanlines(ras, sl, ren); + } else - stroke.generator().line_cap(agg::round_cap); - - stroke.generator().miter_limit(4.0); - stroke.generator().width(stroke_.get_width()); + { + agg::conv_stroke stroke(path); - ras.clip_box(0,0,image.width(),image.height()); - ras.add_path(stroke); - ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); - agg::render_scanlines(ras, sl, ren); + line_join_e join=stroke_.get_line_join(); + if ( join == MITER_JOIN) + stroke.generator().line_join(agg::miter_join); + else if( join == MITER_REVERT_JOIN) + stroke.generator().line_join(agg::miter_join); + else if( join == ROUND_JOIN) + stroke.generator().line_join(agg::round_join); + else + stroke.generator().line_join(agg::bevel_join); + + line_cap_e cap=stroke_.get_line_cap(); + if (cap == BUTT_CAP) + stroke.generator().line_cap(agg::butt_cap); + else if (cap == SQUARE_CAP) + stroke.generator().line_cap(agg::square_cap); + else + stroke.generator().line_cap(agg::round_cap); + + stroke.generator().miter_limit(4.0); + stroke.generator().width(stroke_.get_width()); + + ras.clip_box(0,0,image.width(),image.height()); + ras.add_path(stroke); + ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); + agg::render_scanlines(ras, sl, ren); + } } } } diff --git a/src/polygon_pattern_symbolizer.cpp b/src/polygon_pattern_symbolizer.cpp index 3cd8a725b..506d39477 100644 --- a/src/polygon_pattern_symbolizer.cpp +++ b/src/polygon_pattern_symbolizer.cpp @@ -52,18 +52,10 @@ namespace mapnik } } - void polygon_pattern_symbolizer::render(geometry_type& geom,Image32& image) const + void polygon_pattern_symbolizer::render(Feature const& feat,CoordTransform const& t,Image32& image) const { + typedef coord_transform path_type; typedef agg::renderer_base ren_base; - agg::row_ptr_cache buf(image.raw_data(),image.width(),image.height(), - image.width()*4); - agg::pixfmt_rgba32 pixf(buf); - ren_base renb(pixf); - - unsigned w=pattern_.width(); - unsigned h=pattern_.height(); - agg::row_ptr_cache pattern_rbuf((agg::int8u*)pattern_.getBytes(),w,h,w*4); - typedef agg::wrap_mode_repeat wrap_x_type; typedef agg::wrap_mode_repeat wrap_y_type; typedef agg::image_accessor_wrap, span_gen_type> renderer_type; + geometry_ptr const& geom=feat.get_geometry(); + if (geom) + { + path_type path(t,*geom); + + agg::row_ptr_cache buf(image.raw_data(),image.width(),image.height(), + image.width()*4); + agg::pixfmt_rgba32 pixf(buf); + ren_base renb(pixf); - double x0,y0; - geom.vertex(&x0,&y0); - geom.rewind(0); + unsigned w=pattern_.width(); + unsigned h=pattern_.height(); + agg::row_ptr_cache pattern_rbuf((agg::int8u*)pattern_.getBytes(),w,h,w*4); + + double x0,y0; + path.vertex(&x0,&y0); + path.rewind(0); - unsigned offset_x = unsigned(image.width() - x0); - unsigned offset_y = unsigned(image.height() - y0); + unsigned offset_x = unsigned(image.width() - x0); + unsigned offset_y = unsigned(image.height() - y0); - agg::span_allocator sa; - img_source_type img_src(pattern_rbuf); - span_gen_type sg(img_src, offset_x, offset_y); - renderer_type rp(renb,sa, sg); + agg::span_allocator sa; + img_source_type img_src(pattern_rbuf); + span_gen_type sg(img_src, offset_x, offset_y); + renderer_type rp(renb,sa, sg); - agg::rasterizer_scanline_aa<> ras; - agg::scanline_u8 sl; - ras.clip_box(0,0,image.width(),image.height()); - ras.add_path(geom); - agg::render_scanlines(ras, sl, rp); + agg::rasterizer_scanline_aa<> ras; + agg::scanline_u8 sl; + ras.clip_box(0,0,image.width(),image.height()); + ras.add_path(path); + agg::render_scanlines(ras, sl, rp); + } } } diff --git a/src/polygon_symbolizer.cpp b/src/polygon_symbolizer.cpp index 97afdef47..922dd68ea 100644 --- a/src/polygon_symbolizer.cpp +++ b/src/polygon_symbolizer.cpp @@ -38,26 +38,34 @@ namespace mapnik : symbolizer(), fill_(fill) {} - void polygon_symbolizer::render(geometry_type& geom,Image32& image) const + + void polygon_symbolizer::render(Feature const& feat,CoordTransform const& t,Image32& image) const { + typedef coord_transform path_type; typedef agg::renderer_base ren_base; typedef agg::renderer_scanline_aa_solid renderer; - agg::row_ptr_cache buf(image.raw_data(),image.width(),image.height(), - image.width()*4); - agg::pixfmt_rgba32 pixf(buf); - ren_base renb(pixf); - - unsigned r=fill_.red(); - unsigned g=fill_.green(); - unsigned b=fill_.blue(); - unsigned a=fill_.alpha(); - renderer ren(renb); - - agg::rasterizer_scanline_aa<> ras; - agg::scanline_u8 sl; - ras.clip_box(0,0,image.width(),image.height()); - ras.add_path(geom); - ren.color(agg::rgba8(r, g, b, a)); - agg::render_scanlines(ras, sl, ren); + + geometry_ptr const& geom=feat.get_geometry(); + if (geom) + { + path_type path(t,*geom); + agg::row_ptr_cache buf(image.raw_data(),image.width(),image.height(), + image.width()*4); + agg::pixfmt_rgba32 pixf(buf); + ren_base renb(pixf); + + unsigned r=fill_.red(); + unsigned g=fill_.green(); + unsigned b=fill_.blue(); + unsigned a=fill_.alpha(); + renderer ren(renb); + + agg::rasterizer_scanline_aa<> ras; + agg::scanline_u8 sl; + ras.clip_box(0,0,image.width(),image.height()); + ras.add_path(path); + ren.color(agg::rgba8(r, g, b, a)); + agg::render_scanlines(ras, sl, ren); + } } } diff --git a/src/render.cpp b/src/render.cpp index f1710a345..5df021f08 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -96,45 +96,45 @@ namespace mapnik while ((feature = fs->next())) { bool do_else=true; - geometry_ptr& geom=feature->get_geometry(); - if (geom) - { - geom->transform(t);//todo: transform once + //geometry_ptr& geom=feature->get_geometry(); + //if (geom) - std::vector::const_iterator itr=if_rules.begin(); - while (itr!=if_rules.end()) + //geom->transform(t);//todo: transform once + // coord_transform path(t,*geom); + + std::vector::const_iterator itr=if_rules.begin(); + while (itr!=if_rules.end()) + { + const filter_ptr& filter=(*itr)->get_filter(); + if (filter->pass(*feature)) + { + do_else=false; + const symbolizers& symbols = (*itr)->get_symbolizers(); + symbolizers::const_iterator symIter=symbols.begin(); + while (symIter!=symbols.end()) + { + (*symIter)->render(*feature,t,image); + ++symIter; + } + } + ++itr; + } + if (do_else) + { + //else filter + std::vector::const_iterator itr=else_rules.begin(); + while (itr != else_rules.end()) { - const filter_ptr& filter=(*itr)->get_filter(); - if (filter->pass(*feature)) - { - do_else=false; - const symbolizers& symbols = (*itr)->get_symbolizers(); - symbolizers::const_iterator symIter=symbols.begin(); - while (symIter!=symbols.end()) - { - (*symIter)->render(*geom,image); - ++symIter; - } - } + const symbolizers& symbols = (*itr)->get_symbolizers(); + symbolizers::const_iterator symIter=symbols.begin(); + while (symIter!=symbols.end()) + { + (*symIter)->render(*feature,t,image); + ++symIter; + } ++itr; } - if (do_else) - { - //else filter - std::vector::const_iterator itr=else_rules.begin(); - while (itr != else_rules.end()) - { - const symbolizers& symbols = (*itr)->get_symbolizers(); - symbolizers::const_iterator symIter=symbols.begin(); - while (symIter!=symbols.end()) - { - (*symIter)->render(*geom,image); - ++symIter; - } - ++itr; - } - } - } + } } } }