1. new feature model - based on boost::property_map concept

f = feature(id);
       f["name"] = "what is my name?";
       boost.put(f,"area",123123.4325);
       
2. simplified and corrected value class and operators
3. updated input plug-ins to work with new features
4. add text_symbolizer (getting there:)
5. template version of agg_renderer 
6. attribute_collector how accepts rules 
	(to collect attribute names for text labels)
This commit is contained in:
Artem Pavlenko 2006-02-10 17:13:02 +00:00
parent f4a64526c3
commit aed5516197
19 changed files with 509 additions and 533 deletions

View file

@ -26,18 +26,20 @@
namespace mapnik namespace mapnik
{ {
struct agg_renderer : public feature_style_processor<agg_renderer>, template <typename T>
struct agg_renderer : public feature_style_processor<agg_renderer<T> >,
private boost::noncopyable private boost::noncopyable
{ {
agg_renderer(Map const& m, Image32 & pixmap); agg_renderer(Map const& m, T & pixmap);
void process(point_symbolizer const& sym,Feature const& feature); void process(point_symbolizer const& sym,Feature const& feature);
void process(line_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(line_pattern_symbolizer const& sym,Feature const& feature);
void process(polygon_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); void process(polygon_pattern_symbolizer const& sym,Feature const& feature);
void process(raster_symbolizer const& sym,Feature const& feature); void process(raster_symbolizer const& sym,Feature const& feature);
void process(text_symbolizer const& sym,Feature const& feature);
private: private:
Image32 & pixmap_; T & pixmap_;
CoordTransform t_; CoordTransform t_;
}; };
} }

View file

@ -24,15 +24,35 @@
#include "filter.hpp" #include "filter.hpp"
#include "expression.hpp" #include "expression.hpp"
#include "feature_layer_desc.hpp" #include "feature_layer_desc.hpp"
#include "rule.hpp"
#include <set> #include <set>
#include <iostream>
namespace mapnik namespace mapnik
{ {
struct symbolizer_attributes : public boost::static_visitor<>
{
symbolizer_attributes(std::set<std::string>& names)
: names_(names) {}
template <typename T>
void operator () (T const&) const {}
void operator () (text_symbolizer const& sym)
{
names_.insert(sym.get_name());
}
private:
std::set<std::string>& names_;
};
template <typename FeatureT> template <typename FeatureT>
class attribute_collector : public filter_visitor<FeatureT> class attribute_collector : public filter_visitor<FeatureT>
{ {
private:
std::set<std::string>& names_;
public: public:
attribute_collector(std::set<std::string>& names) attribute_collector(std::set<std::string>& names)
: names_(names) {} : names_(names) {}
@ -48,15 +68,27 @@ namespace mapnik
{ {
names_.insert(pf->name()); names_.insert(pf->name());
} }
} }
void visit(rule_type const& r)
{
const symbolizers& symbols = r.get_symbolizers();
symbolizers::const_iterator symIter=symbols.begin();
symbolizer_attributes attr(names_);
while (symIter != symbols.end())
{
boost::apply_visitor(attr,*symIter++);
}
filter_ptr const& filter = r.get_filter();
filter->accept(*this);
}
virtual ~attribute_collector() {} virtual ~attribute_collector() {}
private: private:
// no copying // no copying
attribute_collector(attribute_collector const&); attribute_collector(attribute_collector const&);
attribute_collector& operator=(attribute_collector const&); attribute_collector& operator=(attribute_collector const&);
private: };
std::set<std::string>& names_;
};
} }
#endif //ATTRIBUTE_COLLECTOR_HPP #endif //ATTRIBUTE_COLLECTOR_HPP

View file

@ -82,19 +82,19 @@ namespace mapnik
public: public:
property(std::string const& name) property(std::string const& name)
: expression<FeatureT>(), : expression<FeatureT>(),
name_(name), name_(name)
index_(0), {}
valid_(false) {}
property(property const& other) property(property const& other)
: expression<FeatureT>(), : expression<FeatureT>(),
name_(other.name_), name_(other.name_)
index_(other.index_), //index_(other.index_),
valid_(other.valid_) {} //valid_(other.valid_)
{}
value get_value(FeatureT const& feature) const value get_value(FeatureT const& feature) const
{ {
return feature.get_property(index_); return feature[name_];
} }
void accept(filter_visitor<FeatureT>& v) void accept(filter_visitor<FeatureT>& v)
{ {
@ -110,8 +110,8 @@ namespace mapnik
} }
void set_index(size_t index) void set_index(size_t index)
{ {
index_=index; //index_=index;
valid_=true; //valid_=true;
} }
std::string to_string() const std::string to_string() const
{ {
@ -120,8 +120,8 @@ namespace mapnik
~property() {} ~property() {}
private: private:
std::string name_; std::string name_;
size_t index_; //size_t index_;
bool valid_; //bool valid_;
}; };
} }

View file

@ -24,15 +24,20 @@
#include "geometry.hpp" #include "geometry.hpp"
#include "raster.hpp" #include "raster.hpp"
#include "value.hpp" #include "value.hpp"
#include <vector> #include <map>
#include <boost/property_map.hpp>
#include <boost/utility.hpp>
namespace mapnik namespace mapnik
{ {
typedef boost::shared_ptr<raster> raster_ptr; typedef boost::shared_ptr<raster> raster_ptr;
typedef std::vector<value> properties; //typedef std::vector<value> properties;
typedef boost::associative_property_map<std::map<std::string,value> > properties;
template <typename T1,typename T2> template <typename T1,typename T2>
struct feature struct feature : public properties,
private boost::noncopyable
{ {
public: public:
typedef T1 geometry_type; typedef T1 geometry_type;
@ -41,32 +46,20 @@ namespace mapnik
int id_; int id_;
geometry_type geom_; geometry_type geom_;
raster_type raster_; raster_type raster_;
properties props_; std::map<std::string,value> props_;
public: public:
explicit feature(int id) explicit feature(int id)
: id_(id), : properties(props_),
id_(id),
geom_(), geom_(),
raster_() {} raster_() {}
feature(int id,const geometry_type& geom) feature(int id,const geometry_type& geom)
: id_(id), : properties(props_),
id_(id),
geom_(geom), geom_(geom),
raster_() {} raster_() {}
feature(const feature<T1,T2>& rhs)
: id_(rhs.id_),
geom_(rhs.geom_),
raster_(rhs.raster_) {}
feature<T1,T2>& operator=(const feature<T1,T2>& rhs)
{
feature<T1,T2> tmp;
swap(tmp);
return *this;
}
~feature() {}
int id() const int id() const
{ {
return id_; return id_;
@ -90,51 +83,32 @@ namespace mapnik
{ {
raster_=raster; raster_=raster;
} }
void reserve_props(unsigned n)
{
props_.reserve(n);
}
void add_property(int v)
{
return props_.push_back(value(v));
}
void add_property(double v)
{
return props_.push_back(value(v));
}
void add_property(std::string const& v)
{
return props_.push_back(value(v));
}
value get_property(size_t index) const
{
if (index < props_.size())
return props_[index];
else
return value("");
}
const properties& get_properties() const const properties& get_properties() const
{ {
return props_; return props_;
} }
private: std::string to_string() const
void swap(const feature<T1,T2>& rhs) throw()
{ {
std::swap(id_,rhs.id_); std::stringstream ss;
std::swap(geom_,rhs.geom_); ss << "feature (" << std::endl;
std::swap(raster_,rhs.raster_); for (std::map<std::string,value>::const_iterator itr=props_.begin();
std::swap(props_,rhs.props_); itr != props_.end();++itr)
{
ss << " " << itr->first << ":" << itr->second << std::endl;
}
ss << ")" << std::endl;
return ss.str();
} }
}; };
typedef feature<geometry_ptr,raster_ptr> Feature; typedef feature<geometry_ptr,raster_ptr> Feature;
inline std::ostream& operator<< (std::ostream & out,Feature const& f)
{
out << f.to_string();
return out;
}
} }
#endif //FEATURE_HPP #endif //FEATURE_HPP

View file

@ -29,7 +29,6 @@
#include "layer.hpp" #include "layer.hpp"
#include "map.hpp" #include "map.hpp"
#include "attribute_collector.hpp" #include "attribute_collector.hpp"
#include "property_index.hpp"
#include "utils.hpp" #include "utils.hpp"
namespace mapnik namespace mapnik
@ -64,7 +63,8 @@ namespace mapnik
std::vector<Layer>::const_iterator itr = m_.layers().begin(); std::vector<Layer>::const_iterator itr = m_.layers().begin();
while (itr != m_.layers().end()) while (itr != m_.layers().end())
{ {
if (itr->isVisible(m_.scale()))// && itr->envelope().intersects(extent)) if (itr->isVisible(m_.scale()) &&
itr->envelope().intersects(m_.getCurrentExtent()))
{ {
apply_to_layer(*itr,p); apply_to_layer(*itr,p);
} }
@ -87,7 +87,7 @@ namespace mapnik
{ {
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);
std::vector<rule_type*> if_rules; std::vector<rule_type*> if_rules;
std::vector<rule_type*> else_rules; std::vector<rule_type*> else_rules;
@ -104,9 +104,10 @@ namespace mapnik
if (ruleIter->active(scale)) if (ruleIter->active(scale))
{ {
active_rules=true; active_rules=true;
filter_ptr& filter=const_cast<filter_ptr&>(ruleIter->get_filter()); //filter_ptr& filter=const_cast<filter_ptr&>(ruleIter->get_filter());
filter->accept(collector); //filter->accept(collector);
filter->accept(indexer); ruleIter->accept(collector);
//filter->accept(indexer);
if (ruleIter->has_else_filter()) if (ruleIter->has_else_filter())
{ {
else_rules.push_back(const_cast<rule_type*>(&(*ruleIter))); else_rules.push_back(const_cast<rule_type*>(&(*ruleIter)));

View file

@ -28,7 +28,6 @@
namespace mapnik namespace mapnik
{ {
typedef rule<Feature,filter> rule_type;
typedef std::vector<rule_type> rules; typedef std::vector<rule_type> rules;
class feature_type_style class feature_type_style
{ {

View file

@ -21,12 +21,11 @@
#ifndef FILTER_HPP #ifndef FILTER_HPP
#define FILTER_HPP #define FILTER_HPP
#include "filter_visitor.hpp" //#include "filter_visitor.hpp"
#include "feature.hpp" #include "feature.hpp"
namespace mapnik namespace mapnik
{ {
typedef boost::shared_ptr<filter<Feature> > filter_ptr;
template <typename FeatureT> class filter_visitor; template <typename FeatureT> class filter_visitor;
template <typename FeatureT> template <typename FeatureT>
struct filter struct filter
@ -37,7 +36,8 @@ namespace mapnik
virtual std::string to_string() const=0; virtual std::string to_string() const=0;
virtual ~filter() {} virtual ~filter() {}
}; };
typedef boost::shared_ptr<filter<Feature> > filter_ptr;
template <typename FeatureT> template <typename FeatureT>
struct all_filter : public filter<FeatureT> struct all_filter : public filter<FeatureT>

View file

@ -26,11 +26,14 @@ namespace mapnik
{ {
template <typename FeatureT> class filter; template <typename FeatureT> class filter;
template <typename FeatureT> class expression; template <typename FeatureT> class expression;
template <typename FeatureT> class expression;
template <typename Feature,template <typename> class Filter> class rule;
template <typename FeatureT> template <typename FeatureT>
struct filter_visitor struct filter_visitor
{ {
virtual void visit(filter<FeatureT>& filter)=0; virtual void visit(filter<FeatureT>& filter)=0;
virtual void visit(expression<FeatureT>&)=0; virtual void visit(expression<FeatureT>&)=0;
virtual void visit(rule<FeatureT,filter> const& r)=0;
virtual ~filter_visitor() {} virtual ~filter_visitor() {}
}; };
} }

View file

@ -50,6 +50,7 @@
#include "line_pattern_symbolizer.hpp" #include "line_pattern_symbolizer.hpp"
#include "point_symbolizer.hpp" #include "point_symbolizer.hpp"
#include "raster_symbolizer.hpp" #include "raster_symbolizer.hpp"
#include "text_symbolizer.hpp"
#include "image_util.hpp" #include "image_util.hpp"
#include "datasource.hpp" #include "datasource.hpp"
#include "layer.hpp" #include "layer.hpp"

View file

@ -28,6 +28,8 @@
namespace mapnik namespace mapnik
{ {
/*
template <typename FeatureT> template <typename FeatureT>
class property_index : public filter_visitor<FeatureT> class property_index : public filter_visitor<FeatureT>
{ {
@ -63,6 +65,7 @@ namespace mapnik
std::set<std::string> const& names_; std::set<std::string> const& names_;
}; };
*/
} }
#endif //PROPERTY_INDEX_HPP #endif //PROPERTY_INDEX_HPP

View file

@ -25,7 +25,10 @@
#include "polygon_pattern_symbolizer.hpp" #include "polygon_pattern_symbolizer.hpp"
#include "point_symbolizer.hpp" #include "point_symbolizer.hpp"
#include "raster_symbolizer.hpp" #include "raster_symbolizer.hpp"
#include "text_symbolizer.hpp"
#include "filter.hpp" #include "filter.hpp"
#include "filter_visitor.hpp"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <string> #include <string>
@ -39,7 +42,8 @@ namespace mapnik
line_pattern_symbolizer, line_pattern_symbolizer,
polygon_symbolizer, polygon_symbolizer,
polygon_pattern_symbolizer, polygon_pattern_symbolizer,
raster_symbolizer> symbolizer; raster_symbolizer,
text_symbolizer> symbolizer;
typedef std::vector<symbolizer> symbolizers; typedef std::vector<symbolizer> symbolizers;
template <typename FeatureT> class all_filter; template <typename FeatureT> class all_filter;
@ -128,12 +132,12 @@ namespace mapnik
name_=name; name_=name;
} }
const std::string& get_name() const std::string const& get_name() const
{ {
return name_; return name_;
} }
const std::string& get_title() const std::string const& get_title() const
{ {
return title_; return title_;
} }
@ -143,12 +147,12 @@ namespace mapnik
title_=title; title_=title;
} }
void set_abstract(const std::string& abstract) void set_abstract(std::string const& abstract)
{ {
abstract_=abstract; abstract_=abstract;
} }
const std::string& get_abstract() const std::string const& get_abstract() const
{ {
return abstract_; return abstract_;
} }
@ -186,7 +190,7 @@ namespace mapnik
filter_=filter; filter_=filter;
} }
const filter_ptr& get_filter() const filter_ptr const& get_filter() const
{ {
return filter_; return filter_;
} }
@ -206,6 +210,11 @@ namespace mapnik
return ( scale > min_scale_ && scale < max_scale_ ); return ( scale > min_scale_ && scale < max_scale_ );
} }
void accept(filter_visitor<FeatureT>& v) const
{
v.visit(*this);
}
private: private:
void swap(rule& rhs) throw() void swap(rule& rhs) throw()
@ -220,6 +229,8 @@ namespace mapnik
else_filter_=rhs.else_filter_; else_filter_=rhs.else_filter_;
} }
}; };
typedef rule<Feature,filter> rule_type;
} }
#endif //RULE_HPP #endif //RULE_HPP

View file

@ -21,34 +21,33 @@
#ifndef TEXT_SYMBOLIZER_HPP #ifndef TEXT_SYMBOLIZER_HPP
#define TEXT_SYMBOLIZER_HPP #define TEXT_SYMBOLIZER_HPP
#include "symbolizer.hpp" //#include "symbolizer.hpp"
#include "fill.hpp" //#include "fill.hpp"
#include "expression.hpp" //#include "expression.hpp"
namespace mapnik namespace mapnik
{ {
template <typename FeatureT> struct text_symbolizer
struct text_symbolizer : public symbolizer
{ {
text_symbolizer(expression<FeatureT> const& label,fill const& f) text_symbolizer(std::string const& name,Color const& fill)
: label_(label.clone()), : name_(name),
fill_(f) {} fill_(fill) {}
text_symbolizer(text_symbolizer const& rhs)
: name_(rhs.name_),
fill_(rhs.fill_) {}
~text_symbolizer() ~text_symbolizer()
{ {
delete label_; //
} }
std::string const& get_name() const
void render(geometry_type& geom,Image32& image) const
{ {
//todo : render text return name_;
} }
private: private:
expression<FeatureT>* label_; std::string name_;
fill fill_; Color fill_;
private:
text_symbolizer(text_symbolizer const&);
text_symbolizer& operator=(text_symbolizer const&);
}; };
} }

View file

@ -25,445 +25,376 @@
#include <sstream> #include <sstream>
#include <boost/variant.hpp> #include <boost/variant.hpp>
using std::string;
using namespace boost; using namespace boost;
namespace mapnik { namespace impl { namespace mapnik {
typedef variant<int,double,string> value_holder; typedef variant<int,double,std::string> value_base;
class equals namespace impl {
: public boost::static_visitor<bool> struct equals
: public boost::static_visitor<bool>
{
template <typename T, typename U>
bool operator() (const T &, const U & ) const
{
return false;
}
template <typename T>
bool operator() (T lhs, T rhs) const
{
return lhs == rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs == rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs == rhs;
}
bool operator() (std::string const& lhs, std::string const& rhs) const
{
return lhs == rhs;
}
};
struct greater_than
: public boost::static_visitor<bool>
{
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false;
}
template <typename T>
bool operator()( T lhs, T rhs ) const
{
return lhs > rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs > rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs > rhs;
}
bool operator() (std::string const& lhs, std::string const& rhs) const
{
return lhs > rhs;
}
};
struct greater_or_equal
: public boost::static_visitor<bool>
{
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false;
}
template <typename T>
bool operator() (T lhs, T rhs) const
{
return lhs >= rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs >= rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs >= rhs;
}
bool operator() (std::string const& lhs, std::string const& rhs ) const
{
return lhs >= rhs;
}
};
struct less_than
: public boost::static_visitor<bool>
{
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false;
}
template <typename T>
bool operator()( T lhs,T rhs) const
{
return lhs < rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs < rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs < rhs;
}
bool operator()( std::string const& lhs, std::string const& rhs ) const
{
return lhs < rhs;
}
};
struct less_or_equal
: public boost::static_visitor<bool>
{
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false;
}
template <typename T>
bool operator()(T lhs, T rhs ) const
{
return lhs <= rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs <= rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs <= rhs;
}
template <typename T>
bool operator()( std::string const& lhs, std::string const& rhs ) const
{
return lhs <= rhs;
}
};
template <typename V>
struct add : public boost::static_visitor<V>
{
typedef V value_type;
template <typename T1, typename T2>
value_type operator() (T1 const& lhs, T2 const&) const
{
return lhs;
}
template <typename T>
value_type operator() (T lhs, T rhs) const
{
return lhs + rhs ;
}
value_type operator() (std::string const& lhs,std::string const& rhs ) const
{
return lhs + rhs;
}
value_type operator() (double lhs, int rhs) const
{
return lhs + rhs;
}
value_type operator() (int lhs, double rhs) const
{
return lhs + rhs;
}
};
template <typename V>
struct sub : public boost::static_visitor<V>
{
typedef V value_type;
template <typename T1, typename T2>
value_type operator() (T1 const& lhs, T2 const&) const
{
return lhs;
}
template <typename T>
value_type operator() (T lhs, T rhs) const
{
return lhs - rhs ;
}
value_type operator() (std::string const& lhs,std::string const& ) const
{
return lhs;
}
value_type operator() (double lhs, int rhs) const
{
return lhs - rhs;
}
value_type operator() (int lhs, double rhs) const
{
return lhs - rhs;
}
};
template <typename V>
struct mult : public boost::static_visitor<V>
{
typedef V value_type;
template <typename T1, typename T2>
value_type operator() (T1 const& lhs , T2 const& ) const
{
return lhs;
}
template <typename T>
value_type operator() (T lhs, T rhs) const
{
return lhs * rhs;
}
value_type operator() (std::string const& lhs,std::string const& ) const
{
return lhs;
}
value_type operator() (double lhs, int rhs) const
{
return lhs * rhs;
}
value_type operator() (int lhs, double rhs) const
{
return lhs * rhs;
}
};
template <typename V>
struct div: public boost::static_visitor<V>
{
typedef V value_type;
template <typename T1, typename T2>
value_type operator() (T1 const& lhs, T2 const&) const
{
return lhs;
}
template <typename T>
value_type operator() (T lhs, T rhs) const
{
return lhs / rhs;
}
value_type operator() (std::string const& lhs,std::string const&) const
{
return lhs;
}
value_type operator() (double lhs, int rhs) const
{
return lhs / rhs;
}
value_type operator() (int lhs, double rhs) const
{
return lhs / rhs;
}
};
struct to_string : public boost::static_visitor<std::string>
{
template <typename T>
std::string operator() (T val) const
{
std::stringstream ss;
ss << val;
return ss.str();
}
std::string operator() (std::string const& val) const
{
return "'" + val + "'";
}
};
}
class value : public value_base
{ {
public: public:
template <typename T, typename U> value ()
bool operator()( const T &, const U & ) const : value_base(0) {}
{
return false;
}
bool operator() (int lhs, int rhs) const template <typename T> value(T _val_)
{ : value_base(_val_) {}
return lhs == rhs;
}
bool operator() (double lhs, double rhs) const
{
return lhs == rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs == rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs == rhs;
}
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const
{
return lhs == rhs;
}
};
class greater_than
: public boost::static_visitor<bool>
{
public:
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false;
}
bool operator() (int lhs, int rhs) const
{
return lhs > rhs;
}
bool operator() (double lhs, double rhs) const
{
return lhs > rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs > rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs > rhs;
}
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const
{
return lhs > rhs;
}
};
class greater_or_equal
: public boost::static_visitor<bool>
{
public:
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false;
}
bool operator() (int lhs, int rhs) const
{
return lhs >= rhs;
}
bool operator() (double lhs, double rhs) const
{
return lhs >= rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs >= rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs >= rhs;
}
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const
{
return lhs >= rhs;
}
};
class less_than
: public boost::static_visitor<bool>
{
public:
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false;
}
bool operator() (int lhs, int rhs) const
{
return lhs < rhs;
}
bool operator() (double lhs, double rhs) const
{
return lhs < rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs < rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs < rhs;
}
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const
{
return lhs < rhs;
}
};
class less_or_equal
: public boost::static_visitor<bool>
{
public:
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false;
}
bool operator() (int lhs, int rhs) const
{
return lhs <= rhs;
}
bool operator() (double lhs, double rhs) const
{
return lhs <= rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs <= rhs;
}
bool operator() (double lhs, int rhs) const
{
return lhs <= rhs;
}
template <typename T>
bool operator()( const T & lhs, const T & rhs ) const
{
return lhs <= rhs;
}
};
struct add : public boost::static_visitor<value_holder>
{
template <typename T1, typename T2>
value_holder operator() (T1 const& , T2 const&) const
{
return value_holder();
}
template <typename T>
value_holder operator() (T const& lhs, T const& rhs) const
{
return lhs + rhs ;
}
value_holder operator() (int lhs,int rhs) const
{
return lhs + rhs;
}
value_holder operator() (double lhs, double rhs) const
{
return lhs + rhs;
}
value_holder operator() (double lhs, int rhs) const
{
return lhs + rhs;
}
value_holder operator() (int lhs, double rhs) const
{
return lhs + rhs;
}
};
struct sub : public boost::static_visitor<value_holder>
{
template <typename T1, typename T2>
value_holder operator() (T1 const& lhs, T2 const&) const
{
return value_holder(lhs);
}
template <typename T>
value_holder operator() (T const& lhs, T const& rhs) const
{
return lhs - rhs ;
}
value_holder operator() (string const& lhs,string const& ) const
{
return lhs;
}
value_holder operator() (int lhs,int rhs) const
{
return lhs - rhs;
}
value_holder operator() (double lhs, double rhs) const
{
return lhs - rhs;
}
value_holder operator() (double lhs, int rhs) const
{
return lhs - rhs;
}
value_holder operator() (int lhs, double rhs) const
{
return lhs - rhs;
}
};
struct mult : public boost::static_visitor<value_holder>
{
template <typename T1, typename T2>
value_holder operator() (T1 const&, T2 const& ) const
{
return value_holder();
}
template <typename T>
value_holder operator() (T const& lhs, T const& rhs) const
{
return lhs * rhs;
}
value_holder operator() (string const& lhs,string const& ) const
{
return lhs;
}
value_holder operator() (int lhs,int rhs) const
{
return lhs * rhs;
}
value_holder operator() (double lhs, double rhs) const
{
return lhs * rhs;
}
value_holder operator() (double lhs, int rhs) const
{
return lhs * rhs;
}
value_holder operator() (int lhs, double rhs) const
{
return lhs * rhs;
}
};
struct div: public boost::static_visitor<value_holder>
{
template <typename T1, typename T2>
value_holder operator() (T1 const&, T2 const&) const
{
return value_holder();
}
template <typename T>
value_holder operator() (T const& lhs, T const& rhs) const
{
return lhs / rhs;
}
value_holder operator() (string const& lhs,string const&) const
{
return lhs;
}
value_holder operator() (int lhs,int rhs) const
{
return lhs / rhs;
}
value_holder operator() (double lhs, double rhs) const
{
return lhs / rhs;
}
value_holder operator() (double lhs, int rhs) const
{
return lhs / rhs;
}
value_holder operator() (int lhs, double rhs) const
{
return lhs / rhs;
}
};
struct to_string : public boost::static_visitor<std::string>
{
template <typename T>
std::string operator() (T val) const
{
std::stringstream ss;
ss << val;
return ss.str();
}
std::string operator() (std::string const& val) const
{
return "'" + val + "'";
}
};
}
using namespace impl;
class value
{
public:
value(int i)
: v_(i) {}
value(double d)
: v_(d) {}
value(string const& str)
: v_(str) {}
value(value const& other)
: v_ (other.v_) {}
bool operator==(value const& other) const bool operator==(value const& other) const
{ {
return apply_visitor(equals(),v_,other.get()); return boost::apply_visitor(impl::equals(),*this,other);
} }
bool operator!=(value const& other) const bool operator!=(value const& other) const
{ {
return !(apply_visitor(equals(),v_,other.get())); return !(boost::apply_visitor(impl::equals(),*this,other));
} }
bool operator>(value const& other) const bool operator>(value const& other) const
{ {
return apply_visitor(greater_than(),v_,other.get()); return boost::apply_visitor(impl::greater_than(),*this,other);
} }
bool operator>=(value const& other) const bool operator>=(value const& other) const
{ {
return apply_visitor(greater_or_equal(),v_,other.get()); return boost::apply_visitor(impl::greater_or_equal(),*this,other);
} }
bool operator<(value const& other) const bool operator<(value const& other) const
{ {
return apply_visitor(less_than(),v_,other.get()); return boost::apply_visitor(impl::less_than(),*this,other);
} }
bool operator<=(value const& other) const bool operator<=(value const& other) const
{ {
return apply_visitor(less_or_equal(),v_,other.get()); return boost::apply_visitor(impl::less_or_equal(),*this,other);
} }
value& operator+=(value const& other) value& operator+=(value const& other)
{ {
v_ = apply_visitor(add(),v_,other.get()); *this = boost::apply_visitor(impl::add<value>(),*this,other);
return *this; return *this;
} }
value& operator-=(value const& other) value& operator-=(value const& other)
{ {
v_ = apply_visitor(sub(),v_,other.get()); *this = boost::apply_visitor(impl::sub<value>(),*this,other);
return *this; return *this;
} }
value& operator*=(value const& other) value& operator*=(value const& other)
{ {
v_ = apply_visitor(mult(),v_,other.get()); *this = boost::apply_visitor(impl::mult<value>(),*this,other);
return *this; return *this;
} }
value& operator/=(value const& other) value& operator/=(value const& other)
{ {
v_ = apply_visitor(div(),v_,other.get()); *this = boost::apply_visitor(impl::div<value>(),*this,other);
return *this; return *this;
} }
value_holder const& get() const std::string to_string() const
{ {
return v_; return boost::apply_visitor(impl::to_string(),*this);
} }
string to_string() const
{
return apply_visitor(impl::to_string(),v_);
}
private:
value_holder v_;
}; };
inline const value operator+(value const& p1,value const& p2) inline const value operator+(value const& p1,value const& p2)
@ -494,14 +425,14 @@ namespace mapnik { namespace impl {
return tmp; return tmp;
} }
template <typename charT, typename traits> //template <typename charT, typename traits>
inline std::basic_ostream<charT,traits>& //inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out, //operator << (std::basic_ostream<charT,traits>& out,/
value const& v) // value const& v)
{ // {
out << v.get(); // out << v.get();
return out; // return out;
} //}
} }
#endif //VALUE_HPP #endif //VALUE_HPP

View file

@ -49,10 +49,10 @@ feature_ptr postgis_featureset::next()
if (geom) if (geom)
{ {
feature->set_geometry(geom); feature->set_geometry(geom);
feature->reserve_props(num_attrs_);
unsigned start=2; unsigned start=2;
for (unsigned pos=0;pos<num_attrs_;++pos) for (unsigned pos=0;pos<num_attrs_;++pos)
{ {
std::string name = rs_->getFieldName(start + pos);
const char* buf=rs_->getValue(start + pos); const char* buf=rs_->getValue(start + pos);
//int field_size = rs_->getFieldLength(start + pos); //int field_size = rs_->getFieldLength(start + pos);
int oid = rs_->getTypeOID(start + pos); int oid = rs_->getTypeOID(start + pos);
@ -60,32 +60,32 @@ feature_ptr postgis_featureset::next()
if (oid==23) //int4 if (oid==23) //int4
{ {
int val = int4net(buf); int val = int4net(buf);
feature->add_property(val); boost::put(*feature,name,val);
} }
else if (oid==21) //int2 else if (oid==21) //int2
{ {
int val = int2net(buf); int val = int2net(buf);
feature->add_property(val); boost::put(*feature,name,val);
} }
else if (oid == 700) // float4 else if (oid == 700) // float4
{ {
float val; float val;
float4net(val,buf); float4net(val,buf);
feature->add_property((double)val); boost::put(*feature,name,val);
} }
else if (oid == 701) // float8 else if (oid == 701) // float8
{ {
double val; double val;
float8net(val,buf); float8net(val,buf);
feature->add_property(val); boost::put(*feature,name,val);
} }
else if (oid==1042 || oid==1043) //bpchar or varchar else if (oid==1042 || oid==1043) //bpchar or varchar
{ {
feature->add_property(string(buf)); boost::put(*feature,name,buf);
} }
else else
{ {
feature->add_property(string("null")); boost::put(*feature,name,0);
} }
} }
++count_; ++count_;

View file

@ -110,11 +110,11 @@ const field_descriptor& dbf_file::descriptor(int col) const
} }
void dbf_file::add_attribute(int col,Feature* f) const throw() void dbf_file::add_attribute(int col,Feature const& f) const throw()
{ {
if (col>=0 && col<num_fields_) if (col>=0 && col<num_fields_)
{ {
std::string name=fields_[col].name_;
std::string str=trim(std::string(record_+fields_[col].offset_,fields_[col].length_)); std::string str=trim(std::string(record_+fields_[col].offset_,fields_[col].length_));
switch (fields_[col].type_) switch (fields_[col].type_)
@ -123,27 +123,27 @@ void dbf_file::add_attribute(int col,Feature* f) const throw()
case 'D'://todo handle date? case 'D'://todo handle date?
case 'M': case 'M':
case 'L': case 'L':
f->add_property(str); f[name] = str;
break; break;
case 'N': case 'N':
case 'F': case 'F':
{ {
if (str[0]=='*') if (str[0]=='*')
{ {
f->add_property("null"); boost::put(f,name,0);
break; break;
} }
if (fields_[col].dec_>0) if (fields_[col].dec_>0)
{ {
double d; double d;
fromString(str,d); fromString(str,d);
f->add_property(d); boost::put(f,name,d);
} }
else else
{ {
int i; int i;
fromString(str,i); fromString(str,i);
f->add_property(i); boost::put(f,name,i);
} }
break; break;
} }

View file

@ -61,7 +61,7 @@ class dbf_file
field_descriptor const& descriptor(int col) const; field_descriptor const& descriptor(int col) const;
void move_to(int index); void move_to(int index);
std::string string_value(int col) const; std::string string_value(int col) const;
void add_attribute(int col,Feature* f) const throw(); void add_attribute(int col,Feature const& f) const throw();
private: private:
dbf_file(const dbf_file&); dbf_file(const dbf_file&);
dbf_file& operator=(const dbf_file&); dbf_file& operator=(const dbf_file&);

View file

@ -162,7 +162,7 @@ feature_ptr shape_featureset<filterT>::next()
{ {
try try
{ {
shape_.dbf().add_attribute(*pos,feature.get());//TODO optimize!!! shape_.dbf().add_attribute(*pos,*feature);//TODO optimize!!!
} }
catch (...) catch (...)
{ {

View file

@ -157,14 +157,14 @@ feature_ptr shape_index_featureset<filterT>::next()
} }
if (attr_ids_.size()) if (attr_ids_.size())
{ {
feature->reserve_props(attr_ids_.size()); //feature->reserve_props(attr_ids_.size());
shape_.dbf().move_to(shape_.id_); shape_.dbf().move_to(shape_.id_);
std::vector<int>::const_iterator pos=attr_ids_.begin(); std::vector<int>::const_iterator pos=attr_ids_.begin();
while (pos!=attr_ids_.end()) while (pos!=attr_ids_.end())
{ {
try try
{ {
shape_.dbf().add_attribute(*pos,feature.get()); shape_.dbf().add_attribute(*pos,*feature);
} }
catch (...) catch (...)
{ {

View file

@ -52,10 +52,10 @@
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <iostream>
namespace mapnik namespace mapnik
{ {
class pattern_source : private boost::noncopyable class pattern_source : private boost::noncopyable
{ {
public: public:
@ -79,16 +79,18 @@ namespace mapnik
ImageData32 const& pattern_; ImageData32 const& pattern_;
}; };
template <typename T>
agg_renderer::agg_renderer(Map const& m, Image32 & pixmap) agg_renderer<T>::agg_renderer(Map const& m, T & pixmap)
: feature_style_processor<agg_renderer>(m),pixmap_(pixmap), : feature_style_processor<agg_renderer>(m),
pixmap_(pixmap),
t_(m.getWidth(),m.getHeight(),m.getCurrentExtent()) t_(m.getWidth(),m.getHeight(),m.getCurrentExtent())
{ {
Color const& bg=m.getBackground(); Color const& bg=m.getBackground();
pixmap_.setBackground(bg); pixmap_.setBackground(bg);
std::cout << "scale="<<m.scale()<<std::endl;
} }
template <typename T>
void agg_renderer::process(polygon_symbolizer const& sym,Feature const& feature) void agg_renderer<T>::process(polygon_symbolizer const& sym,Feature const& feature)
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform<CoordTransform,geometry_type> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
@ -120,7 +122,9 @@ namespace mapnik
agg::render_scanlines(ras, sl, ren); agg::render_scanlines(ras, sl, ren);
} }
} }
void agg_renderer::process(line_symbolizer const& sym,Feature const& feature)
template <typename T>
void agg_renderer<T>::process(line_symbolizer const& sym,Feature const& feature)
{ {
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform<CoordTransform,geometry_type> path_type;
@ -186,7 +190,7 @@ namespace mapnik
ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
agg::render_scanlines(ras, sl, ren); agg::render_scanlines(ras, sl, ren);
} }
else if (0) //(stroke_.get_width() <= 1.0) else if (stroke_.get_width() <= 1.0)
{ {
//faster but clipping doesn't work //faster but clipping doesn't work
agg::line_profile_aa prof; agg::line_profile_aa prof;
@ -234,8 +238,9 @@ namespace mapnik
} }
} }
} }
void agg_renderer::process(point_symbolizer const& sym,Feature const& feature) template <typename T>
void agg_renderer<T>::process(point_symbolizer const& sym,Feature const& feature)
{ {
geometry_ptr const& geom=feature.get_geometry(); geometry_ptr const& geom=feature.get_geometry();
if (geom) if (geom)
@ -253,7 +258,9 @@ namespace mapnik
pixmap_.set_rectangle_alpha(px,py,data); pixmap_.set_rectangle_alpha(px,py,data);
} }
} }
void agg_renderer::process(line_pattern_symbolizer const& sym,Feature const& feature)
template <typename T>
void agg_renderer<T>::process(line_pattern_symbolizer const& sym,Feature const& feature)
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform<CoordTransform,geometry_type> path_type;
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type; typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
@ -281,7 +288,8 @@ namespace mapnik
} }
} }
void agg_renderer::process(polygon_pattern_symbolizer const& sym,Feature const& feature) template <typename T>
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,Feature const& feature)
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform<CoordTransform,geometry_type> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
@ -332,7 +340,9 @@ namespace mapnik
agg::render_scanlines(ras, sl, rp); agg::render_scanlines(ras, sl, rp);
} }
} }
void agg_renderer::process(raster_symbolizer const& ,Feature const& feature)
template <typename T>
void agg_renderer<T>::process(raster_symbolizer const& ,Feature const& feature)
{ {
// TODO -- at the moment raster_symbolizer is an empty class // TODO -- at the moment raster_symbolizer is an empty class
// used for type dispatching, but we can have some fancy raster // used for type dispatching, but we can have some fancy raster
@ -343,4 +353,14 @@ namespace mapnik
pixmap_.set_rectangle(raster->x_,raster->y_,raster->data_); pixmap_.set_rectangle(raster->x_,raster->y_,raster->data_);
} }
} }
template <typename T>
void agg_renderer<T>::process(text_symbolizer const& sym ,Feature const& feature)
{
//TODO - implement text
//std::cout << feature << std::endl;
std::cout << sym.get_name() <<":" << feature[sym.get_name()] << std::endl;
}
template class agg_renderer<Image32>;
} }