1. new style/feature processor abstraction allowing plugable backends.

(to construct custom 'Output' derive from feature_style_processor (CRTP) e.g
	class MyOutput : public feature_style_processor<MyOutput>
     and implement:
	 process(***_symbolizer const&, Feature const&)
     methods
   At the moment only AGG renderer is implemented
This commit is contained in:
Artem Pavlenko 2006-02-07 14:41:41 +00:00
parent 9f9e4c1d8e
commit af2601eea0
20 changed files with 695 additions and 261 deletions

42
include/agg_renderer.hpp Normal file
View file

@ -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>
{
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

View file

@ -18,8 +18,8 @@
//$Id$ //$Id$
#ifndef ATTRIBUTE_COLLECTOR #ifndef ATTRIBUTE_COLLECTOR_HPP
#define ATTROBUTE_COLLECTOR #define ATTRIBUTE_COLLECTOR_HPP
#include "filter.hpp" #include "filter.hpp"
#include "expression.hpp" #include "expression.hpp"

View file

@ -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 <vector>
#include <iostream>
#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 <typename Processor>
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<Processor&>(*this);
std::vector<Layer>::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<double> const& bbox=m_.getCurrentExtent();
double scale = m_.scale();
std::vector<std::string> const& style_names = lay.styles();
std::vector<std::string>::const_iterator stylesIter = style_names.begin();
while (stylesIter != style_names.end())
{
std::set<std::string> names;
attribute_collector<Feature> collector(names);
property_index<Feature> indexer(names);
std::vector<rule_type*> if_rules;
std::vector<rule_type*> else_rules;
bool active_rules=false;
feature_type_style const& style=m_.find_style(*stylesIter++);
const std::vector<rule_type>& rules=style.get_rules();
std::vector<rule_type>::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<filter_ptr&>(ruleIter->get_filter());
filter->accept(collector);
filter->accept(indexer);
if (ruleIter->has_else_filter())
{
else_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
}
else
{
if_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));
}
}
++ruleIter;
}
std::set<std::string>::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<rule_type*>::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<rule_type*>::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

View file

@ -21,20 +21,21 @@
#ifndef LINE_PATTERN_SYMBOLIZER_HPP #ifndef LINE_PATTERN_SYMBOLIZER_HPP
#define LINE_PATTERN_SYMBOLIZER_HPP #define LINE_PATTERN_SYMBOLIZER_HPP
#include "symbolizer.hpp" #include <boost/shared_ptr.hpp>
#include <boost/utility.hpp> #include "graphics.hpp"
namespace mapnik namespace mapnik
{ {
struct line_pattern_symbolizer : public symbolizer, struct line_pattern_symbolizer
private boost::noncopyable
{ {
line_pattern_symbolizer(std::string const& file, line_pattern_symbolizer(std::string const& file,
std::string const& type, std::string const& type,
unsigned width,unsigned height); 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: private:
ImageData32 pattern_; boost::shared_ptr<ImageData32> pattern_;
}; };
} }

View file

@ -22,19 +22,22 @@
#define LINE_SYMBOLIZER_HPP #define LINE_SYMBOLIZER_HPP
#include "symbolizer.hpp" //#include "symbolizer.hpp"
#include "stroke.hpp" #include "stroke.hpp"
#include <boost/utility.hpp>
namespace mapnik namespace mapnik
{ {
struct line_symbolizer : public symbolizer, struct line_symbolizer
private boost::noncopyable
{ {
line_symbolizer(stroke const& stroke); line_symbolizer(stroke const& stroke)
line_symbolizer(const Color& pen,float width=1.0); : stroke_(stroke) {}
void render(Feature const& feat, CoordTransform const& t,Image32& image) const;
line_symbolizer(const Color& pen,float width=1.0)
: stroke_(pen,width) {}
stroke const& get_stroke() const
{
return stroke_;
}
private: private:
stroke stroke_; stroke stroke_;
}; };

View file

@ -58,8 +58,7 @@ namespace mapnik
bool insert_style(std::string const& name,feature_type_style const& style); bool insert_style(std::string const& name,feature_type_style const& style);
void remove_style(const std::string& name); 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; size_t layerCount() const;
void addLayer(const Layer& l); void addLayer(const Layer& l);
const Layer& getLayer(size_t index) const; const Layer& getLayer(size_t index) const;

View file

@ -34,21 +34,21 @@
#include "comparison.hpp" #include "comparison.hpp"
#include "regex_filter.hpp" #include "regex_filter.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "symbolizer.hpp" //#include "symbolizer.hpp"
#include "geometry.hpp" #include "geometry.hpp"
#include "geom_util.hpp" #include "geom_util.hpp"
#include "raster.hpp" #include "raster.hpp"
#include "feature.hpp" #include "feature.hpp"
#include "attribute.hpp" #include "attribute.hpp"
#include "attribute_collector.hpp" #include "attribute_collector.hpp"
#include "render.hpp"
#include "graphics.hpp" #include "graphics.hpp"
#include "image_reader.hpp" #include "image_reader.hpp"
#include "line_symbolizer.hpp" #include "line_symbolizer.hpp"
#include "polygon_symbolizer.hpp" #include "polygon_symbolizer.hpp"
#include "agg_renderer.hpp"
#include "polygon_pattern_symbolizer.hpp" #include "polygon_pattern_symbolizer.hpp"
#include "line_pattern_symbolizer.hpp" #include "line_pattern_symbolizer.hpp"
#include "image_symbolizer.hpp" #include "point_symbolizer.hpp"
#include "image_util.hpp" #include "image_util.hpp"
#include "datasource.hpp" #include "datasource.hpp"
#include "layer.hpp" #include "layer.hpp"

View file

@ -18,26 +18,25 @@
//$Id: image_symbolizer.hpp 39 2005-04-10 20:39:53Z pavlenko $ //$Id: image_symbolizer.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef IMAGE_SYMBOLIZER_HPP #ifndef POINT_SYMBOLIZER_HPP
#define IMAGE_SYMBOLIZER_HPP #define POINT_SYMBOLIZER_HPP
#include "symbolizer.hpp" #include <boost/shared_ptr.hpp>
#include <boost/utility.hpp> #include "graphics.hpp"
namespace mapnik namespace mapnik
{ {
struct image_symbolizer : public symbolizer, struct point_symbolizer
private boost::noncopyable
{ {
image_symbolizer(std::string const& file, point_symbolizer(std::string const& file,
std::string const& type, std::string const& type,
unsigned width,unsigned height); unsigned width,unsigned height);
point_symbolizer(point_symbolizer const& rhs);
void render(Feature const& feat, CoordTransform const& t,Image32& image) const; ImageData32 const& get_data() const;
private: private:
ImageData32 symbol_; boost::shared_ptr<ImageData32> symbol_;
}; };
} }
#endif // IMAGE_SYMBOLIZER_HPP #endif // POINT_SYMBOLIZER_HPP

View file

@ -21,22 +21,23 @@
#ifndef POLYGON_PATTERN_SYMBOLIZER_HPP #ifndef POLYGON_PATTERN_SYMBOLIZER_HPP
#define POLYGON_PATTERN_SYMBOLIZER_HPP #define POLYGON_PATTERN_SYMBOLIZER_HPP
#include "symbolizer.hpp" #include <boost/shared_ptr.hpp>
#include <boost/utility.hpp> #include "graphics.hpp"
namespace mapnik namespace mapnik
{ {
struct polygon_pattern_symbolizer : public symbolizer, struct polygon_pattern_symbolizer
private boost::noncopyable
{ {
polygon_pattern_symbolizer(std::string const& file, polygon_pattern_symbolizer(std::string const& file,
std::string const& type, std::string const& type,
unsigned width,unsigned height); 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: private:
ImageData32 pattern_; boost::shared_ptr<ImageData32> pattern_;
}; };
} }

View file

@ -21,16 +21,19 @@
#ifndef POLYGON_SYMBOLIZER_HPP #ifndef POLYGON_SYMBOLIZER_HPP
#define POLYGON_SYMBOLIZER_HPP #define POLYGON_SYMBOLIZER_HPP
#include "symbolizer.hpp" //#include "symbolizer.hpp"
#include <boost/utility.hpp> //#include <boost/utility.hpp>
namespace mapnik namespace mapnik
{ {
struct polygon_symbolizer : public symbolizer, struct polygon_symbolizer
private boost::noncopyable
{ {
polygon_symbolizer(const Color& fill); polygon_symbolizer(Color const& fill)
void render(Feature const& feat, CoordTransform const& t,Image32& image) const; : fill_(fill) {}
Color const& get_fill() const
{
return fill_;
}
private: private:
Color fill_; Color fill_;
}; };

View file

@ -19,16 +19,27 @@
#ifndef RULE_HPP #ifndef RULE_HPP
#define 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 "filter.hpp"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/variant.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
namespace mapnik namespace mapnik
{ {
typedef boost::shared_ptr<symbolizer> symbolizer_ptr;
typedef std::vector<symbolizer_ptr> symbolizers; typedef boost::variant<point_symbolizer,
line_symbolizer,
line_pattern_symbolizer,
polygon_symbolizer,
polygon_pattern_symbolizer> symbolizer;
typedef std::vector<symbolizer> symbolizers;
template <typename FeatureT> class all_filter; template <typename FeatureT> class all_filter;
template <typename FeatureT,template <typename> class Filter> template <typename FeatureT,template <typename> class Filter>
@ -140,9 +151,9 @@ namespace mapnik
return abstract_; 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) void remove_at(size_t index)

View file

@ -31,48 +31,6 @@
namespace mapnik namespace mapnik
{ {
class Style
{
private:
std::vector<boost::shared_ptr<symbolizer> > symbols_;
static boost::shared_ptr<symbolizer> zero_symbol_;
public:
typedef std::vector<boost::shared_ptr<symbolizer> >::const_iterator Iterator;
Style() {}
Style(const boost::shared_ptr<symbolizer>& 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<symbolizer>& symbol)
{
symbols_.push_back(symbol);
}
Iterator begin() const
{
return symbols_.begin();
}
Iterator end() const
{
return symbols_.end();
}
};
} }
#endif //STYLE_HPP #endif //STYLE_HPP

View file

@ -21,20 +21,20 @@
#ifndef SYMBOLIZER_HPP #ifndef SYMBOLIZER_HPP
#define SYMBOLIZER_HPP #define SYMBOLIZER_HPP
#include "graphics.hpp" //#include "graphics.hpp"
#include "feature.hpp" //#include "feature.hpp"
#include "geometry.hpp" //#include "geometry.hpp"
#include <limits> //#include <limits>
namespace mapnik namespace mapnik
{ {
class Image32; //class Image32;
struct symbolizer //struct symbolizer
{ //{
virtual void render(Feature const& feat, CoordTransform const& t, Image32& image) const=0; // virtual void render(Feature const& feat, CoordTransform const& t, Image32& image) const=0;
virtual ~symbolizer() {} // virtual ~symbolizer() {}
}; //};
} }
#endif //SYMBOLIZER_HPP #endif //SYMBOLIZER_HPP

View file

@ -40,17 +40,21 @@ source = Split(
params.cpp params.cpp
plugin.cpp plugin.cpp
png_reader.cpp png_reader.cpp
render.cpp
text.cpp text.cpp
tiff_reader.cpp tiff_reader.cpp
wkb.cpp wkb.cpp
line_symbolizer.cpp agg_renderer.cpp
line_pattern_symbolizer.cpp point_symbolizer.cpp
polygon_symbolizer.cpp
polygon_pattern_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) mapnik = env.SharedLibrary('mapnik', source, LIBS=libraries, LINKFLAGS=linkflags)

335
src/agg_renderer.cpp Normal file
View file

@ -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 <boost/utility.hpp>
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<agg_renderer>(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<CoordTransform,geometry_type> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> 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<agg::int8u> 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<agg::pixfmt_rgba32> ren_base;
typedef coord_transform<CoordTransform,geometry_type> path_type;
typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 1)
{
path_type path(t_,*geom);
agg::row_ptr_cache<agg::int8u> 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<path_type> 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<agg::conv_dash<path_type > > 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<path_type> 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<CoordTransform,geometry_type> path_type;
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> renderer_base;
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> 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<agg::int8u> 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<CoordTransform,geometry_type> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef agg::wrap_mode_repeat wrap_x_type;
typedef agg::wrap_mode_repeat wrap_y_type;
typedef agg::image_accessor_wrap<agg::pixfmt_rgba32,
wrap_x_type,
wrap_y_type> img_source_type;
typedef agg::span_pattern_rgba<img_source_type> span_gen_type;
typedef agg::renderer_scanline_aa<ren_base,
agg::span_allocator<agg::rgba8>,
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<agg::int8u> 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<agg::int8u> 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<agg::rgba8> 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);
}
}
}

View file

@ -20,56 +20,20 @@
#include "line_pattern_symbolizer.hpp" #include "line_pattern_symbolizer.hpp"
#include "image_reader.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 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, line_pattern_symbolizer::line_pattern_symbolizer(std::string const& file,
std::string const& type, std::string const& type,
unsigned width,unsigned height) unsigned width,unsigned height)
: symbolizer(), : pattern_(new ImageData32(width,height))
pattern_(width,height)
{ {
try try
{ {
std::auto_ptr<ImageReader> reader(get_image_reader(type,file)); std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
reader->read(0,0,pattern_); reader->read(0,0,*pattern_);
} }
catch (...) catch (...)
{ {
@ -77,30 +41,11 @@ namespace mapnik
} }
} }
void line_pattern_symbolizer::render(Feature const& feat, CoordTransform const& t,Image32& image) const line_pattern_symbolizer::line_pattern_symbolizer(line_pattern_symbolizer const& rhs)
{ : pattern_(rhs.pattern_) {}
typedef coord_transform<CoordTransform,geometry_type> path_type;
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> renderer_base;
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
geometry_ptr const& geom=feat.get_geometry(); ImageData32 const& line_pattern_symbolizer::get_pattern() const
if (geom)
{ {
path_type path(t,*geom); return *pattern_;
unsigned int width=image.width();
unsigned int height=image.height();
agg::row_ptr_cache<agg::int8u> 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);
}
} }
} }

View file

@ -66,12 +66,13 @@ namespace mapnik
styles_.erase(name); 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<std::string,feature_type_style>::const_iterator itr=styles_.find(name); std::map<std::string,feature_type_style>::const_iterator itr=styles_.find(name);
if (itr!=styles_.end()) if (itr!=styles_.end())
return itr->second; return itr->second;
return feature_type_style(); static feature_type_style default_style;
return default_style;
} }
size_t Map::layerCount() const size_t Map::layerCount() const

View file

@ -18,22 +18,21 @@
//$Id$ //$Id$
#include "image_symbolizer.hpp" #include "point_symbolizer.hpp"
#include "image_data.hpp" #include "image_data.hpp"
#include "image_reader.hpp" #include "image_reader.hpp"
namespace mapnik namespace mapnik
{ {
image_symbolizer::image_symbolizer(std::string const& file, point_symbolizer::point_symbolizer(std::string const& file,
std::string const& type, std::string const& type,
unsigned width,unsigned height) unsigned width,unsigned height)
: symbolizer(), : symbol_(new ImageData32(width,height))
symbol_(width,height)
{ {
try try
{ {
std::auto_ptr<ImageReader> reader(get_image_reader(type,file)); std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
reader->read(0,0,symbol_); reader->read(0,0,*symbol_);
} }
catch (...) 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(); return *(symbol_.get());
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_);
}
} }
} }

View file

@ -21,83 +21,29 @@
#include "polygon_pattern_symbolizer.hpp" #include "polygon_pattern_symbolizer.hpp"
#include "image_reader.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 namespace mapnik
{ {
polygon_pattern_symbolizer::polygon_pattern_symbolizer(std::string const& file, polygon_pattern_symbolizer::polygon_pattern_symbolizer(std::string const& file,
std::string const& type, std::string const& type,
unsigned width,unsigned height) unsigned width,unsigned height)
: symbolizer(), : pattern_(new ImageData32(width,height))
pattern_(width,height)
{ {
try try
{ {
std::auto_ptr<ImageReader> reader(get_image_reader(type,file)); std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
reader->read(0,0,pattern_); reader->read(0,0,*pattern_);
} }
catch (...) catch (...)
{ {
std::cerr<<"exception caught..."<<std::endl; std::cerr<<"exception caught..."<<std::endl;
} }
} }
polygon_pattern_symbolizer::polygon_pattern_symbolizer(polygon_pattern_symbolizer const& rhs)
: pattern_(rhs.pattern_) {}
void polygon_pattern_symbolizer::render(Feature const& feat,CoordTransform const& t,Image32& image) const ImageData32 const& polygon_pattern_symbolizer::get_pattern() const
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; return *pattern_;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef agg::wrap_mode_repeat wrap_x_type;
typedef agg::wrap_mode_repeat wrap_y_type;
typedef agg::image_accessor_wrap<agg::pixfmt_rgba32,
wrap_x_type,
wrap_y_type> img_source_type;
typedef agg::span_pattern_rgba<img_source_type> span_gen_type;
typedef agg::renderer_scanline_aa<ren_base,
agg::span_allocator<agg::rgba8>,
span_gen_type> renderer_type;
geometry_ptr const& geom=feat.get_geometry();
if (geom)
{
path_type path(t,*geom);
agg::row_ptr_cache<agg::int8u> 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<agg::int8u> 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<agg::rgba8> 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);
}
} }
} }

View file

@ -44,8 +44,6 @@ namespace mapnik
std::vector<std::string>::const_iterator stylesIter=namedStyles.begin(); std::vector<std::string>::const_iterator stylesIter=namedStyles.begin();
while (stylesIter!=namedStyles.end()) while (stylesIter!=namedStyles.end())
{ {
//feature_type_style style=named_style_cache::instance()->find(*stylesIter++);
std::set<std::string> names; std::set<std::string> names;
attribute_collector<Feature> collector(names); attribute_collector<Feature> collector(names);
property_index<Feature> indexer(names); property_index<Feature> indexer(names);
@ -56,7 +54,7 @@ namespace mapnik
bool active_rules=false; bool active_rules=false;
feature_type_style style=map.find_style(*stylesIter++); feature_type_style const& style=map.find_style(*stylesIter++);
const std::vector<rule_type>& rules=style.get_rules(); const std::vector<rule_type>& rules=style.get_rules();
std::vector<rule_type>::const_iterator ruleIter=rules.begin(); std::vector<rule_type>::const_iterator ruleIter=rules.begin();