+ fix feature caching implementation - collect

attributes names from all active styles

+ use BOOST_FOREACH to improve readability

 TODO - move 'filter_factor' to raster_symbolizer
This commit is contained in:
Artem Pavlenko 2010-07-20 22:21:14 +00:00
parent 34d5fcf963
commit 1ecdba1965

View file

@ -40,11 +40,14 @@
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
//#include <mapnik/wall_clock_timer.hpp> //#include <mapnik/wall_clock_timer.hpp>
#endif #endif
// boost
#include <boost/foreach.hpp>
//stl //stl
#include <vector> #include <vector>
namespace mapnik namespace mapnik
{ {
template <typename Processor> template <typename Processor>
class feature_style_processor class feature_style_processor
{ {
@ -101,16 +104,12 @@ public:
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
std::clog << "scale denominator = " << scale_denom << "\n"; std::clog << "scale denominator = " << scale_denom << "\n";
#endif #endif
std::vector<layer>::const_iterator itr = m_.layers().begin(); BOOST_FOREACH ( layer const& lyr, m_.layers() )
std::vector<layer>::const_iterator end = m_.layers().end();
while (itr != end)
{ {
if (itr->isVisible(scale_denom)) if (lyr.isVisible(scale_denom))
{ {
apply_to_layer(*itr, p, proj, scale_denom); apply_to_layer(lyr, p, proj, scale_denom);
} }
++itr;
} }
} }
catch (proj_init_error& ex) catch (proj_init_error& ex)
@ -176,63 +175,85 @@ private:
query::resolution_type res(m_.width()/m_.get_current_extent().width(),m_.height()/m_.get_current_extent().height()); query::resolution_type res(m_.width()/m_.get_current_extent().width(),m_.height()/m_.get_current_extent().height());
query q(bbox,res,scale_denom); //BBOX query query q(bbox,res,scale_denom); //BBOX query
std::vector<std::string> const& style_names = lay.styles(); std::vector<feature_type_style*> active_styles;
std::vector<std::string>::const_iterator stylesIter = style_names.begin();
std::vector<std::string>::const_iterator stylesEnd = style_names.end();
memory_datasource cache;
bool cache_features = style_names.size()>1?true:false;
bool first = true;
for (;stylesIter != stylesEnd; ++stylesIter)
{
std::set<std::string> names; std::set<std::string> names;
attribute_collector collector(names); attribute_collector collector(names);
std::vector<rule_type*> if_rules;
std::vector<rule_type*> else_rules;
bool active_rules=false; std::vector<std::string> const& style_names = lay.styles();
// iterate through all named styles collecting active styles and attribute names
boost::optional<feature_type_style const&> style=m_.find_style(*stylesIter); BOOST_FOREACH(std::string const& style_name, style_names)
if (!style) { {
std::clog << "WARNING: style '" << *stylesIter << "' required for layer '" << lay.name() << "' does not exist.\n"; boost::optional<feature_type_style const&> style=m_.find_style(style_name);
if (!style)
{
std::clog << "WARNING: style '" << style_name << "' required for layer '" << lay.name() << "' does not exist.\n";
continue; continue;
} }
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(); bool active_rules=false;
std::vector<rule_type>::const_iterator ruleEnd=rules.end();
for (;ruleIter!=ruleEnd;++ruleIter) BOOST_FOREACH(rule_type const& rule, rules)
{ {
if (ruleIter->active(scale_denom)) if (rule.active(scale_denom))
{ {
active_rules = true; active_rules = true;
// collect unique attribute names
// TODO - in the future rasters should be able to be filtered...
if (ds->type() == datasource::Vector) if (ds->type() == datasource::Vector)
{ {
collector(*ruleIter); collector(rule);
} }
if (ruleIter->has_else_filter()) // TODO - in the future rasters should be able to be filtered.
}
}
if (active_rules)
{ {
else_rules.push_back(const_cast<rule_type*>(&(*ruleIter))); active_styles.push_back(const_cast<feature_type_style*>(&(*style)));
}
}
// push all property names
BOOST_FOREACH(std::string const& name, names)
{
q.add_property_name(name);
}
memory_datasource cache;
bool cache_features = style_names.size()>1?true:false;
bool first = true;
BOOST_FOREACH (feature_type_style * style, active_styles)
{
std::vector<rule_type*> if_rules;
std::vector<rule_type*> else_rules;
std::vector<rule_type> const& rules=style->get_rules();
BOOST_FOREACH(rule_type const& rule, rules)
{
if (rule.active(scale_denom))
{
if (rule.has_else_filter())
{
else_rules.push_back(const_cast<rule_type*>(&rule));
} }
else else
{ {
if_rules.push_back(const_cast<rule_type*>(&(*ruleIter))); if_rules.push_back(const_cast<rule_type*>(&rule));
} }
if (ds->type() == datasource::Raster) if (ds->type() == datasource::Raster)
{ {
if (ds->params().get<double>("filter_factor",0.0) == 0.0) if (ds->params().get<double>("filter_factor",0.0) == 0.0)
{ {
const rule_type::symbolizers& symbols = ruleIter->get_symbolizers(); rule_type::symbolizers const& symbols = rule.get_symbolizers();
rule_type::symbolizers::const_iterator symIter = symbols.begin(); rule_type::symbolizers::const_iterator symIter = symbols.begin();
rule_type::symbolizers::const_iterator symEnd = symbols.end(); rule_type::symbolizers::const_iterator symEnd = symbols.end();
for (;symIter != symEnd;++symIter) for (;symIter != symEnd;++symIter)
{ {
try try
{ {
raster_symbolizer sym = boost::get<raster_symbolizer>(*symIter); raster_symbolizer const& sym = boost::get<raster_symbolizer>(*symIter);
std::string scaling = sym.get_scaling(); std::string const& scaling = sym.get_scaling();
if (scaling == "bilinear" || scaling == "bilinear8" ) if (scaling == "bilinear" || scaling == "bilinear8" )
{ {
// todo - allow setting custom value in symbolizer property? // todo - allow setting custom value in symbolizer property?
@ -246,20 +267,11 @@ private:
} }
} }
} }
}
}
}
} // process features
}
}
std::set<std::string>::const_iterator namesIter=names.begin();
std::set<std::string>::const_iterator namesEnd =names.end();
// push all property names
for (;namesIter!=namesEnd;++namesIter)
{
q.add_property_name(*namesIter);
}
if (active_rules)
{
featureset_ptr fs; featureset_ptr fs;
if (first) if (first)
{ {
@ -270,6 +282,7 @@ private:
{ {
fs = cache.features(q); fs = cache.features(q);
} }
if (fs) if (fs)
{ {
feature_ptr feature; feature_ptr feature;
@ -282,42 +295,30 @@ private:
cache.push(feature); cache.push(feature);
} }
std::vector<rule_type*>::const_iterator itr=if_rules.begin(); BOOST_FOREACH(rule_type * rule, if_rules )
std::vector<rule_type*>::const_iterator end=if_rules.end();
for (;itr != end;++itr)
{ {
expression_ptr const& expr=(*itr)->get_filter(); expression_ptr const& expr=rule->get_filter();
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr); value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
if (result.to_bool()) if (result.to_bool())
{ {
do_else=false; do_else=false;
const rule_type::symbolizers& symbols = (*itr)->get_symbolizers(); rule_type::symbolizers const& symbols = rule->get_symbolizers();
rule_type::symbolizers::const_iterator symIter=symbols.begin(); BOOST_FOREACH (symbolizer const& sym, symbols)
rule_type::symbolizers::const_iterator symEnd =symbols.end();
for (;symIter != symEnd;++symIter)
{ {
boost::apply_visitor boost::apply_visitor
(symbol_dispatch(p,*feature,prj_trans),*symIter); (symbol_dispatch(p,*feature,prj_trans),sym);
} }
} }
} }
if (do_else) if (do_else)
{ {
//else filter BOOST_FOREACH( rule_type * rule, else_rules )
std::vector<rule_type*>::const_iterator itr=
else_rules.begin();
std::vector<rule_type*>::const_iterator end=
else_rules.end();
for (;itr != end;++itr)
{ {
const rule_type::symbolizers& symbols = (*itr)->get_symbolizers(); rule_type::symbolizers const& symbols = rule->get_symbolizers();
rule_type::symbolizers::const_iterator symIter= symbols.begin(); BOOST_FOREACH (symbolizer const& sym, symbols)
rule_type::symbolizers::const_iterator symEnd = symbols.end();
for (;symIter!=symEnd;++symIter)
{ {
boost::apply_visitor boost::apply_visitor
(symbol_dispatch(p,*feature,prj_trans),*symIter); (symbol_dispatch(p,*feature,prj_trans),sym);
} }
} }
} }
@ -326,9 +327,10 @@ private:
} }
} }
} }
}
p.end_layer_processing(lay); p.end_layer_processing(lay);
} }
Map const& m_; Map const& m_;
double scale_factor_; double scale_factor_;
}; };