diff --git a/include/agg_renderer.hpp b/include/agg_renderer.hpp new file mode 100644 index 000000000..a8951030c --- /dev/null +++ b/include/agg_renderer.hpp @@ -0,0 +1,42 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2006 Artem Pavlenko + * + * Mapnik is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#ifndef AGG_RENDERER_HPP +#define AGG_RENDERER_HPP + +#include "feature_style_processor.hpp" + +namespace mapnik +{ + struct agg_renderer : public feature_style_processor + { + agg_renderer(Map const& m, Image32 & pixmap); + void process(point_symbolizer const& sym,Feature const& feature); + void process(line_symbolizer const& sym,Feature const& feature); + void process(line_pattern_symbolizer const& sym,Feature const& feature); + void process(polygon_symbolizer const& sym,Feature const& feature); + void process(polygon_pattern_symbolizer const& sym,Feature const& feature); + private: + Image32 & pixmap_; + CoordTransform t_; + }; +} + +#endif //AGG_RENDERER_HPP diff --git a/include/attribute_collector.hpp b/include/attribute_collector.hpp index 27aa1c6fe..1eeb38e75 100644 --- a/include/attribute_collector.hpp +++ b/include/attribute_collector.hpp @@ -18,8 +18,8 @@ //$Id$ -#ifndef ATTRIBUTE_COLLECTOR -#define ATTROBUTE_COLLECTOR +#ifndef ATTRIBUTE_COLLECTOR_HPP +#define ATTRIBUTE_COLLECTOR_HPP #include "filter.hpp" #include "expression.hpp" diff --git a/include/feature_style_processor.hpp b/include/feature_style_processor.hpp new file mode 100644 index 000000000..3a3aad6b3 --- /dev/null +++ b/include/feature_style_processor.hpp @@ -0,0 +1,198 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2006 Artem Pavlenko + * + * Mapnik is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#ifndef FEATURE_STYLE_PROCESSOR_HPP +#define FEATURE_STYLE_PROCESSOR_HPP + +#include +#include + +#include "envelope.hpp" +#include "datasource.hpp" +#include "layer.hpp" +#include "map.hpp" +#include "attribute_collector.hpp" +#include "property_index.hpp" +#include "utils.hpp" + +namespace mapnik +{ + + template + class feature_style_processor + { + struct symbol_dispatch : public boost::static_visitor<> + { + symbol_dispatch (Processor & output,Feature const& f) + : output_(output),f_(f) {} + + void operator () (polygon_symbolizer const& sym) const + { + output_.process(sym,f_); + } + + void operator () (polygon_pattern_symbolizer const& sym) const + { + output_.process(sym,f_); + } + + void operator () (line_symbolizer const& sym) const + { + output_.process(sym,f_); + } + + void operator () (line_pattern_symbolizer const& sym) const + { + output_.process(sym,f_); + } + + void operator () (point_symbolizer const& sym) const + { + output_.process(sym,f_); + } + + Processor & output_; + Feature const& f_; + }; + public: + feature_style_processor(Map const& m) + : m_(m) {} + + void apply() + { + timer clock; + + Processor & p = static_cast(*this); + std::vector::const_iterator itr = m_.layers().begin(); + while (itr != m_.layers().end()) + { + if (itr->isVisible(m_.scale()))// && itr->envelope().intersects(extent)) + { + apply_to_layer(*itr,p); + } + ++itr; + } + clock.stop(); + } + private: + void apply_to_layer(Layer const& lay,Processor & p) + { + datasource *ds=lay.datasource().get(); + if (ds) + { + Envelope const& bbox=m_.getCurrentExtent(); + double scale = m_.scale(); + + std::vector const& style_names = lay.styles(); + std::vector::const_iterator stylesIter = style_names.begin(); + while (stylesIter != style_names.end()) + { + std::set names; + attribute_collector collector(names); + property_index indexer(names); + std::vector if_rules; + std::vector else_rules; + + bool active_rules=false; + + feature_type_style const& style=m_.find_style(*stylesIter++); + + const std::vector& rules=style.get_rules(); + std::vector::const_iterator ruleIter=rules.begin(); + + query q(bbox,m_.getWidth(),m_.getHeight()); + while (ruleIter!=rules.end()) + { + if (ruleIter->active(scale)) + { + active_rules=true; + filter_ptr& filter=const_cast(ruleIter->get_filter()); + filter->accept(collector); + filter->accept(indexer); + if (ruleIter->has_else_filter()) + { + else_rules.push_back(const_cast(&(*ruleIter))); + } + else + { + if_rules.push_back(const_cast(&(*ruleIter))); + } + } + ++ruleIter; + } + std::set::const_iterator namesIter=names.begin(); + // push all property names + while (namesIter!=names.end()) + { + q.add_property_name(*namesIter); + ++namesIter; + } + if (active_rules) + { + featureset_ptr fs=ds->features(q); + if (fs) + { + feature_ptr feature; + while ((feature = fs->next())) + { + bool do_else=true; + std::vector::const_iterator itr=if_rules.begin(); + while (itr!=if_rules.end()) + { + filter_ptr const& 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()) + { + boost::apply_visitor(symbol_dispatch(p,*feature),*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()) + { + boost::apply_visitor(symbol_dispatch(p,*feature),*symIter++); + } + ++itr; + } + } + } + } + } + } + } + } + + Map const& m_; + }; +} + +#endif //FEATURE_STYLE_PROCESSOR_HPP diff --git a/include/line_pattern_symbolizer.hpp b/include/line_pattern_symbolizer.hpp index ea646dad8..6a2e9bede 100644 --- a/include/line_pattern_symbolizer.hpp +++ b/include/line_pattern_symbolizer.hpp @@ -21,20 +21,21 @@ #ifndef LINE_PATTERN_SYMBOLIZER_HPP #define LINE_PATTERN_SYMBOLIZER_HPP -#include "symbolizer.hpp" -#include +#include +#include "graphics.hpp" namespace mapnik { - struct line_pattern_symbolizer : public symbolizer, - private boost::noncopyable + struct line_pattern_symbolizer { line_pattern_symbolizer(std::string const& file, std::string const& type, unsigned width,unsigned height); - void render(Feature const& feat, CoordTransform const& t,Image32& image) const; + + line_pattern_symbolizer(line_pattern_symbolizer const& rhs); + ImageData32 const& get_pattern() const; private: - ImageData32 pattern_; + boost::shared_ptr pattern_; }; } diff --git a/include/line_symbolizer.hpp b/include/line_symbolizer.hpp index 6f3c536ac..b6fe2cfdb 100644 --- a/include/line_symbolizer.hpp +++ b/include/line_symbolizer.hpp @@ -22,19 +22,22 @@ #define LINE_SYMBOLIZER_HPP -#include "symbolizer.hpp" +//#include "symbolizer.hpp" #include "stroke.hpp" -#include - namespace mapnik { - struct line_symbolizer : public symbolizer, - private boost::noncopyable + struct line_symbolizer { - line_symbolizer(stroke const& stroke); - line_symbolizer(const Color& pen,float width=1.0); - void render(Feature const& feat, CoordTransform const& t,Image32& image) const; + line_symbolizer(stroke const& stroke) + : stroke_(stroke) {} + + line_symbolizer(const Color& pen,float width=1.0) + : stroke_(pen,width) {} + stroke const& get_stroke() const + { + return stroke_; + } private: stroke stroke_; }; diff --git a/include/map.hpp b/include/map.hpp index cfcd6af1a..f64f5f4ad 100644 --- a/include/map.hpp +++ b/include/map.hpp @@ -58,8 +58,7 @@ namespace mapnik bool insert_style(std::string const& name,feature_type_style const& style); void remove_style(const std::string& name); - feature_type_style find_style(std::string const& name) const; - + feature_type_style const& find_style(std::string const& name) const; size_t layerCount() const; void addLayer(const Layer& l); const Layer& getLayer(size_t index) const; diff --git a/include/mapnik.hpp b/include/mapnik.hpp index 31b63418d..debe01af1 100644 --- a/include/mapnik.hpp +++ b/include/mapnik.hpp @@ -34,21 +34,21 @@ #include "comparison.hpp" #include "regex_filter.hpp" #include "utils.hpp" -#include "symbolizer.hpp" +//#include "symbolizer.hpp" #include "geometry.hpp" #include "geom_util.hpp" #include "raster.hpp" #include "feature.hpp" #include "attribute.hpp" #include "attribute_collector.hpp" -#include "render.hpp" #include "graphics.hpp" #include "image_reader.hpp" #include "line_symbolizer.hpp" #include "polygon_symbolizer.hpp" +#include "agg_renderer.hpp" #include "polygon_pattern_symbolizer.hpp" #include "line_pattern_symbolizer.hpp" -#include "image_symbolizer.hpp" +#include "point_symbolizer.hpp" #include "image_util.hpp" #include "datasource.hpp" #include "layer.hpp" diff --git a/include/image_symbolizer.hpp b/include/point_symbolizer.hpp similarity index 72% rename from include/image_symbolizer.hpp rename to include/point_symbolizer.hpp index 267d2f6ad..0fdabbf64 100644 --- a/include/image_symbolizer.hpp +++ b/include/point_symbolizer.hpp @@ -18,26 +18,25 @@ //$Id: image_symbolizer.hpp 39 2005-04-10 20:39:53Z pavlenko $ -#ifndef IMAGE_SYMBOLIZER_HPP -#define IMAGE_SYMBOLIZER_HPP +#ifndef POINT_SYMBOLIZER_HPP +#define POINT_SYMBOLIZER_HPP -#include "symbolizer.hpp" -#include +#include +#include "graphics.hpp" namespace mapnik { - struct image_symbolizer : public symbolizer, - private boost::noncopyable + struct point_symbolizer { - - image_symbolizer(std::string const& file, + + point_symbolizer(std::string const& file, std::string const& type, unsigned width,unsigned height); - - void render(Feature const& feat, CoordTransform const& t,Image32& image) const; + point_symbolizer(point_symbolizer const& rhs); + ImageData32 const& get_data() const; private: - ImageData32 symbol_; + boost::shared_ptr symbol_; }; } -#endif // IMAGE_SYMBOLIZER_HPP +#endif // POINT_SYMBOLIZER_HPP diff --git a/include/polygon_pattern_symbolizer.hpp b/include/polygon_pattern_symbolizer.hpp index ed52d3669..a50bc44bf 100644 --- a/include/polygon_pattern_symbolizer.hpp +++ b/include/polygon_pattern_symbolizer.hpp @@ -21,22 +21,23 @@ #ifndef POLYGON_PATTERN_SYMBOLIZER_HPP #define POLYGON_PATTERN_SYMBOLIZER_HPP -#include "symbolizer.hpp" -#include +#include +#include "graphics.hpp" namespace mapnik { - struct polygon_pattern_symbolizer : public symbolizer, - private boost::noncopyable + struct polygon_pattern_symbolizer { polygon_pattern_symbolizer(std::string const& file, std::string const& type, unsigned width,unsigned height); - void render(Feature const& feat, CoordTransform const& t,Image32& image) const; + polygon_pattern_symbolizer(polygon_pattern_symbolizer const& rhs); + + ImageData32 const& get_pattern() const; private: - ImageData32 pattern_; + boost::shared_ptr pattern_; }; } diff --git a/include/polygon_symbolizer.hpp b/include/polygon_symbolizer.hpp index 3209c02a2..2028590cd 100644 --- a/include/polygon_symbolizer.hpp +++ b/include/polygon_symbolizer.hpp @@ -21,16 +21,19 @@ #ifndef POLYGON_SYMBOLIZER_HPP #define POLYGON_SYMBOLIZER_HPP -#include "symbolizer.hpp" -#include +//#include "symbolizer.hpp" +//#include namespace mapnik { - struct polygon_symbolizer : public symbolizer, - private boost::noncopyable + struct polygon_symbolizer { - polygon_symbolizer(const Color& fill); - void render(Feature const& feat, CoordTransform const& t,Image32& image) const; + polygon_symbolizer(Color const& fill) + : fill_(fill) {} + Color const& get_fill() const + { + return fill_; + } private: Color fill_; }; diff --git a/include/rule.hpp b/include/rule.hpp index 1ecd1c3a6..450b75407 100644 --- a/include/rule.hpp +++ b/include/rule.hpp @@ -19,16 +19,27 @@ #ifndef RULE_HPP #define RULE_HPP -#include "symbolizer.hpp" +#include "line_symbolizer.hpp" +#include "line_pattern_symbolizer.hpp" +#include "polygon_symbolizer.hpp" +#include "polygon_pattern_symbolizer.hpp" +#include "point_symbolizer.hpp" #include "filter.hpp" #include +#include #include #include namespace mapnik { - typedef boost::shared_ptr symbolizer_ptr; - typedef std::vector symbolizers; + + typedef boost::variant symbolizer; + + typedef std::vector symbolizers; template class all_filter; template class Filter> @@ -140,9 +151,9 @@ namespace mapnik return abstract_; } - void append(const symbolizer_ptr& symbol) + void append(const symbolizer& sym) { - syms_.push_back(symbol); + syms_.push_back(sym); } void remove_at(size_t index) diff --git a/include/style.hpp b/include/style.hpp index 96aa6a696..cca3ba4f4 100644 --- a/include/style.hpp +++ b/include/style.hpp @@ -30,49 +30,7 @@ #include namespace mapnik -{ - class Style - { - private: - std::vector > symbols_; - static boost::shared_ptr zero_symbol_; - public: - typedef std::vector >::const_iterator Iterator; - - Style() {} - - Style(const boost::shared_ptr& symbol) - { - symbols_.push_back(symbol); - } - - ~Style() {} - - Style(const Style& rhs) - : symbols_(rhs.symbols_) {} - - Style& operator=(const Style& rhs) - { - if (this==&rhs) return *this; - symbols_=rhs.symbols_; - return *this; - } - - void add(const boost::shared_ptr& symbol) - { - symbols_.push_back(symbol); - } - - Iterator begin() const - { - return symbols_.begin(); - } - - Iterator end() const - { - return symbols_.end(); - } - }; +{ } #endif //STYLE_HPP diff --git a/include/symbolizer.hpp b/include/symbolizer.hpp index fd093a6cb..829a622a3 100644 --- a/include/symbolizer.hpp +++ b/include/symbolizer.hpp @@ -21,20 +21,20 @@ #ifndef SYMBOLIZER_HPP #define SYMBOLIZER_HPP -#include "graphics.hpp" -#include "feature.hpp" -#include "geometry.hpp" -#include +//#include "graphics.hpp" +//#include "feature.hpp" +//#include "geometry.hpp" +//#include namespace mapnik { - class Image32; + //class Image32; - struct symbolizer - { - virtual void render(Feature const& feat, CoordTransform const& t, Image32& image) const=0; - virtual ~symbolizer() {} - }; + //struct symbolizer + //{ + // virtual void render(Feature const& feat, CoordTransform const& t, Image32& image) const=0; + // virtual ~symbolizer() {} + //}; } #endif //SYMBOLIZER_HPP diff --git a/src/SConscript b/src/SConscript index 4a704e59c..150da28f6 100644 --- a/src/SConscript +++ b/src/SConscript @@ -40,17 +40,21 @@ source = Split( params.cpp plugin.cpp png_reader.cpp - render.cpp text.cpp tiff_reader.cpp wkb.cpp - line_symbolizer.cpp - line_pattern_symbolizer.cpp - polygon_symbolizer.cpp + agg_renderer.cpp + point_symbolizer.cpp polygon_pattern_symbolizer.cpp - image_symbolizer.cpp + line_pattern_symbolizer.cpp """ ) +#render.cpp +#line_symbolizer.cpp +# line_pattern_symbolizer.cpp +# polygon_symbolizer.cpp +# polygon_pattern_symbolizer.cpp +# image_symbolizer.cpp mapnik = env.SharedLibrary('mapnik', source, LIBS=libraries, LINKFLAGS=linkflags) diff --git a/src/agg_renderer.cpp b/src/agg_renderer.cpp new file mode 100644 index 000000000..3c4e8103f --- /dev/null +++ b/src/agg_renderer.cpp @@ -0,0 +1,335 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2006 Artem Pavlenko + * + * Mapnik is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#include "agg_renderer.hpp" + +#include "agg_basics.h" +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_scanline_p.h" +#include "agg_scanline_u.h" +#include "agg_renderer_scanline.h" +#include "agg_pixfmt_rgba.h" +#include "agg_path_storage.h" +#include "agg_span_allocator.h" +#include "agg_span_pattern_rgba.h" +#include "agg_image_accessors.h" +#include "agg_conv_stroke.h" +#include "agg_conv_dash.h" +#include "agg_conv_contour.h" +#include "agg_vcgen_stroke.h" +#include "agg_conv_adaptor_vcgen.h" +#include "agg_conv_smooth_poly1.h" +#include "agg_conv_marker.h" +#include "agg_arrowhead.h" +#include "agg_vcgen_markers_term.h" +#include "agg_renderer_outline_aa.h" +#include "agg_rasterizer_outline_aa.h" +#include "agg_rasterizer_outline.h" +#include "agg_renderer_outline_image.h" +#include "agg_span_allocator.h" +#include "agg_span_pattern_rgba.h" +#include "agg_renderer_scanline.h" +#include "agg_pattern_filters_rgba.h" +#include "agg_renderer_outline_image.h" + +#include + +namespace mapnik +{ + + + class pattern_source : private boost::noncopyable + { + public: + pattern_source(ImageData32 const& pattern) + : pattern_(pattern) {} + + unsigned int width() const + { + return pattern_.width(); + } + unsigned int height() const + { + return pattern_.height(); + } + agg::rgba8 pixel(int x, int y) const + { + unsigned c = pattern_(x,y); + return agg::rgba8(c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff,(c >> 24) & 0xff); + } + private: + ImageData32 const& pattern_; + }; + + + agg_renderer::agg_renderer(Map const& m, Image32 & pixmap) + : feature_style_processor(m),pixmap_(pixmap), + t_(m.getWidth(),m.getHeight(),m.getCurrentExtent()) + { + Color const& bg=m.getBackground(); + pixmap_.setBackground(bg); + } + + void agg_renderer::process(polygon_symbolizer const& sym,Feature const& feature) + { + typedef coord_transform path_type; + typedef agg::renderer_base ren_base; + typedef agg::renderer_scanline_aa_solid renderer; + + Color const& fill_ = sym.get_fill(); + + geometry_ptr const& geom=feature.get_geometry(); + if (geom && geom->num_points() > 2) + { + unsigned width = pixmap_.width(); + unsigned height = pixmap_.height(); + path_type path(t_,*geom); + agg::row_ptr_cache buf(pixmap_.raw_data(),width,height,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,width,height); + ras.add_path(path); + ren.color(agg::rgba8(r, g, b, a)); + agg::render_scanlines(ras, sl, ren); + } + } + void agg_renderer::process(line_symbolizer const& sym,Feature const& feature) + { + typedef agg::renderer_base ren_base; + typedef coord_transform path_type; + typedef agg::renderer_outline_aa renderer_oaa; + typedef agg::rasterizer_outline_aa rasterizer_outline_aa; + typedef agg::renderer_scanline_aa_solid renderer; + + geometry_ptr const& geom=feature.get_geometry(); + if (geom && geom->num_points() > 1) + { + path_type path(t_,*geom); + agg::row_ptr_cache buf(pixmap_.raw_data(),pixmap_.width(),pixmap_.height(), + pixmap_.width()*4); + agg::pixfmt_rgba32 pixf(buf); + ren_base renb(pixf); + + mapnik::stroke const& stroke_ = sym.get_stroke(); + + Color const& col = stroke_.get_color(); + unsigned r=col.red(); + unsigned g=col.green(); + unsigned b=col.blue(); + + if (stroke_.has_dash()) + { + renderer ren(renb); + agg::rasterizer_scanline_aa<> ras; + agg::scanline_u8 sl; + 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,pixmap_.width(),pixmap_.height()); + ras.add_path(stroke); + ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); + agg::render_scanlines(ras, sl, ren); + } + else if (0) //(stroke_.get_width() <= 1.0) + { + //faster but clipping doesn't work + agg::line_profile_aa prof; + prof.width(stroke_.get_width()); + renderer_oaa ren_oaa(renb, prof); + rasterizer_outline_aa ras_oaa(ren_oaa); + + ren_oaa.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); + ren_oaa.clip_box(0,0,pixmap_.width(),pixmap_.height()); + ras_oaa.add_path(path); + + } + else + { + renderer ren(renb); + agg::rasterizer_scanline_aa<> ras; + agg::scanline_p8 sl; + agg::conv_stroke stroke(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,pixmap_.width(),pixmap_.height()); + ras.add_path(stroke); + ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); + agg::render_scanlines(ras, sl, ren); + } + } + } + + void agg_renderer::process(point_symbolizer const& sym,Feature const& feature) + { + geometry_ptr const& geom=feature.get_geometry(); + if (geom) + { + double x; + double y; + ImageData32 const& data = sym.get_data(); + geom->label_position(&x,&y); + t_.forward_x(&x); + t_.forward_y(&y); + int w=data.width(); + int h=data.height(); + int px=int(ceil(x - 0.5 * w)); + int py=int(ceil(y - 0.5 * h)); + pixmap_.set_rectangle_alpha(px,py,data); + } + } + void agg_renderer::process(line_pattern_symbolizer const& sym,Feature const& feature) + { + typedef coord_transform 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; + + geometry_ptr const& geom=feature.get_geometry(); + if (geom) + { + unsigned width = pixmap_.width(); + unsigned height = pixmap_.height(); + ImageData32 const& pat = sym.get_pattern(); + path_type path(t_,*geom); + agg::row_ptr_cache buf(pixmap_.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(pat); + 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); + } + } + + void agg_renderer::process(polygon_pattern_symbolizer const& sym,Feature const& feature) + { + typedef coord_transform path_type; + typedef agg::renderer_base ren_base; + typedef agg::wrap_mode_repeat wrap_x_type; + typedef agg::wrap_mode_repeat wrap_y_type; + typedef agg::image_accessor_wrap img_source_type; + + typedef agg::span_pattern_rgba span_gen_type; + + typedef agg::renderer_scanline_aa, + span_gen_type> renderer_type; + geometry_ptr const& geom=feature.get_geometry(); + if (geom) + { + ImageData32 const& pattern = sym.get_pattern(); + + unsigned width = pixmap_.width(); + unsigned height = pixmap_.height(); + path_type path(t_,*geom); + + agg::row_ptr_cache buf(pixmap_.raw_data(),width,height,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); + + double x0,y0; + path.vertex(&x0,&y0); + path.rewind(0); + + unsigned offset_x = unsigned(width - x0); + unsigned offset_y = unsigned(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::rasterizer_scanline_aa<> ras; + agg::scanline_u8 sl; + ras.clip_box(0,0,width,height); + ras.add_path(path); + agg::render_scanlines(ras, sl, rp); + } + } +} diff --git a/src/line_pattern_symbolizer.cpp b/src/line_pattern_symbolizer.cpp index 922a1e00a..c3a3669ca 100644 --- a/src/line_pattern_symbolizer.cpp +++ b/src/line_pattern_symbolizer.cpp @@ -20,87 +20,32 @@ #include "line_pattern_symbolizer.hpp" #include "image_reader.hpp" -#include "agg_basics.h" -#include "agg_rendering_buffer.h" -#include "agg_rasterizer_scanline_aa.h" -#include "agg_rasterizer_outline_aa.h" -#include "agg_scanline_p.h" -#include "agg_scanline_u.h" -#include "agg_renderer_scanline.h" -#include "agg_pixfmt_rgba.h" -#include "agg_path_storage.h" -#include "agg_span_allocator.h" -#include "agg_span_pattern_rgba.h" -#include "agg_image_accessors.h" -#include "agg_pattern_filters_rgba.h" -#include "agg_renderer_outline_image.h" + namespace mapnik { - class pattern_source : private boost::noncopyable - { - public: - pattern_source(ImageData32 const& pattern) - : pattern_(pattern) {} - - unsigned int width() const - { - return pattern_.width(); - } - unsigned int height() const - { - return pattern_.height(); - } - agg::rgba8 pixel(int x, int y) const - { - unsigned c = pattern_(x,y); - return agg::rgba8(c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff,(c >> 24) & 0xff); - } - private: - ImageData32 const& pattern_; - }; - + line_pattern_symbolizer::line_pattern_symbolizer(std::string const& file, std::string const& type, unsigned width,unsigned height) - : symbolizer(), - pattern_(width,height) + : pattern_(new ImageData32(width,height)) { try { std::auto_ptr reader(get_image_reader(type,file)); - reader->read(0,0,pattern_); + reader->read(0,0,*pattern_); } catch (...) { std::cerr << "exception caught..." << std::endl; } } - - void line_pattern_symbolizer::render(Feature const& feat, CoordTransform const& t,Image32& image) const - { - typedef coord_transform 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; - 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); - } + line_pattern_symbolizer::line_pattern_symbolizer(line_pattern_symbolizer const& rhs) + : pattern_(rhs.pattern_) {} + + ImageData32 const& line_pattern_symbolizer::get_pattern() const + { + return *pattern_; } } diff --git a/src/map.cpp b/src/map.cpp index 2e24a27ce..248a9a0f8 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -66,12 +66,13 @@ namespace mapnik styles_.erase(name); } - feature_type_style Map::find_style(std::string const& name) const + feature_type_style const& Map::find_style(std::string const& name) const { std::map::const_iterator itr=styles_.find(name); if (itr!=styles_.end()) return itr->second; - return feature_type_style(); + static feature_type_style default_style; + return default_style; } size_t Map::layerCount() const diff --git a/src/image_symbolizer.cpp b/src/point_symbolizer.cpp similarity index 60% rename from src/image_symbolizer.cpp rename to src/point_symbolizer.cpp index fbab5ae2c..776a59883 100644 --- a/src/image_symbolizer.cpp +++ b/src/point_symbolizer.cpp @@ -18,22 +18,21 @@ //$Id$ -#include "image_symbolizer.hpp" +#include "point_symbolizer.hpp" #include "image_data.hpp" #include "image_reader.hpp" namespace mapnik { - image_symbolizer::image_symbolizer(std::string const& file, - std::string const& type, - unsigned width,unsigned height) - : symbolizer(), - symbol_(width,height) + point_symbolizer::point_symbolizer(std::string const& file, + std::string const& type, + unsigned width,unsigned height) + : symbol_(new ImageData32(width,height)) { try { std::auto_ptr reader(get_image_reader(type,file)); - reader->read(0,0,symbol_); + reader->read(0,0,*symbol_); } catch (...) { @@ -41,22 +40,13 @@ namespace mapnik } } - void image_symbolizer::render(Feature const& feat,CoordTransform const& t,Image32& image) const + point_symbolizer::point_symbolizer(point_symbolizer const& rhs) + : symbol_(rhs.symbol_) + {} + + ImageData32 const& point_symbolizer::get_data() const { - geometry_ptr const& geom=feat.get_geometry(); - if (geom) - { - double x; - double y; - geom->label_position(&x,&y); - t.forward_x(&x); - t.forward_y(&y); - int w=symbol_.width(); - int h=symbol_.height(); - int px=int(ceil(x - 0.5 * w)); - int py=int(ceil(y - 0.5 * h)); - image.set_rectangle_alpha(px,py,symbol_); - } + return *(symbol_.get()); } } diff --git a/src/polygon_pattern_symbolizer.cpp b/src/polygon_pattern_symbolizer.cpp index 506d39477..149ed7240 100644 --- a/src/polygon_pattern_symbolizer.cpp +++ b/src/polygon_pattern_symbolizer.cpp @@ -21,83 +21,29 @@ #include "polygon_pattern_symbolizer.hpp" #include "image_reader.hpp" -#include "agg_basics.h" -#include "agg_rendering_buffer.h" -#include "agg_rasterizer_scanline_aa.h" -#include "agg_scanline_p.h" -#include "agg_scanline_u.h" -#include "agg_renderer_scanline.h" -#include "agg_pixfmt_rgba.h" -#include "agg_path_storage.h" -#include "agg_span_allocator.h" -#include "agg_span_pattern_rgba.h" -#include "agg_image_accessors.h" namespace mapnik { polygon_pattern_symbolizer::polygon_pattern_symbolizer(std::string const& file, std::string const& type, unsigned width,unsigned height) - : symbolizer(), - pattern_(width,height) + : pattern_(new ImageData32(width,height)) { try { std::auto_ptr reader(get_image_reader(type,file)); - reader->read(0,0,pattern_); + reader->read(0,0,*pattern_); } catch (...) { std::cerr<<"exception caught..."< path_type; - typedef agg::renderer_base ren_base; - typedef agg::wrap_mode_repeat wrap_x_type; - typedef agg::wrap_mode_repeat wrap_y_type; - typedef agg::image_accessor_wrap img_source_type; - - typedef agg::span_pattern_rgba span_gen_type; - - typedef agg::renderer_scanline_aa, - 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); - - 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); - - 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(path); - agg::render_scanlines(ras, sl, rp); - } + return *pattern_; } } diff --git a/src/render.cpp b/src/render.cpp index 927d0943b..8c593ca25 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -44,8 +44,6 @@ namespace mapnik std::vector::const_iterator stylesIter=namedStyles.begin(); while (stylesIter!=namedStyles.end()) { - //feature_type_style style=named_style_cache::instance()->find(*stylesIter++); - std::set names; attribute_collector collector(names); property_index indexer(names); @@ -56,8 +54,8 @@ namespace mapnik bool active_rules=false; - feature_type_style style=map.find_style(*stylesIter++); - + feature_type_style const& style=map.find_style(*stylesIter++); + const std::vector& rules=style.get_rules(); std::vector::const_iterator ruleIter=rules.begin();