diff --git a/include/mapnik/feature_style_processor.hpp b/include/mapnik/feature_style_processor.hpp index c2e7923c7..3d41540d4 100644 --- a/include/mapnik/feature_style_processor.hpp +++ b/include/mapnik/feature_style_processor.hpp @@ -40,11 +40,14 @@ #ifdef MAPNIK_DEBUG //#include #endif +// boost +#include //stl #include namespace mapnik -{ +{ + template class feature_style_processor { @@ -87,7 +90,7 @@ public: p.start_map_processing(m_); Map::const_metawriter_iterator metaItr = m_.begin_metawriters(); Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters(); - + for (;metaItr!=metaItrEnd; ++metaItr) { metaItr->second->start(); @@ -101,16 +104,12 @@ public: #ifdef MAPNIK_DEBUG std::clog << "scale denominator = " << scale_denom << "\n"; #endif - std::vector::const_iterator itr = m_.layers().begin(); - std::vector::const_iterator end = m_.layers().end(); - - while (itr != end) + BOOST_FOREACH ( layer const& lyr, m_.layers() ) { - 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) @@ -123,7 +122,7 @@ public: { metaItr->second->stop(); } - + p.end_map_processing(m_); } private: @@ -168,71 +167,93 @@ private: ly0 = std::max(ext.miny(),ly0); lx1 = std::min(ext.maxx(),lx1); ly1 = std::min(ext.maxy(),ly1); - + prj_trans.forward(lx0,ly0,lz0); prj_trans.forward(lx1,ly1,lz1); box2d bbox(lx0,ly0,lx1,ly1); - + 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 - - std::vector const& style_names = lay.styles(); - std::vector::const_iterator stylesIter = style_names.begin(); - std::vector::const_iterator stylesEnd = style_names.end(); + + std::vector active_styles; + std::set names; + attribute_collector collector(names); + + std::vector const& style_names = lay.styles(); + // iterate through all named styles collecting active styles and attribute names + BOOST_FOREACH(std::string const& style_name, style_names) + { + boost::optional style=m_.find_style(style_name); + if (!style) + { + std::clog << "WARNING: style '" << style_name << "' required for layer '" << lay.name() << "' does not exist.\n"; + continue; + } + + const std::vector& rules=(*style).get_rules(); + bool active_rules=false; + + BOOST_FOREACH(rule_type const& rule, rules) + { + if (rule.active(scale_denom)) + { + active_rules = true; + if (ds->type() == datasource::Vector) + { + collector(rule); + } + // TODO - in the future rasters should be able to be filtered. + } + } + if (active_rules) + { + active_styles.push_back(const_cast(&(*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; - for (;stylesIter != stylesEnd; ++stylesIter) + + BOOST_FOREACH (feature_type_style * style, active_styles) { - std::set names; - attribute_collector collector(names); std::vector if_rules; std::vector else_rules; - - bool active_rules=false; - - boost::optional style=m_.find_style(*stylesIter); - if (!style) { - std::clog << "WARNING: style '" << *stylesIter << "' required for layer '" << lay.name() << "' does not exist.\n"; - continue; - } - const std::vector& rules=(*style).get_rules(); - std::vector::const_iterator ruleIter=rules.begin(); - std::vector::const_iterator ruleEnd=rules.end(); - - for (;ruleIter!=ruleEnd;++ruleIter) + std::vector const& rules=style->get_rules(); + + BOOST_FOREACH(rule_type const& rule, rules) { - if (ruleIter->active(scale_denom)) + if (rule.active(scale_denom)) { - active_rules=true; - // collect unique attribute names - // TODO - in the future rasters should be able to be filtered... - if (ds->type() == datasource::Vector) + if (rule.has_else_filter()) { - collector(*ruleIter); - } - if (ruleIter->has_else_filter()) - { - else_rules.push_back(const_cast(&(*ruleIter))); + else_rules.push_back(const_cast(&rule)); } else { - if_rules.push_back(const_cast(&(*ruleIter))); + if_rules.push_back(const_cast(&rule)); } + if (ds->type() == datasource::Raster) { if (ds->params().get("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 symEnd = symbols.end(); for (;symIter != symEnd;++symIter) { try { - raster_symbolizer sym = boost::get(*symIter); - std::string scaling = sym.get_scaling(); + raster_symbolizer const& sym = boost::get(*symIter); + std::string const& scaling = sym.get_scaling(); if (scaling == "bilinear" || scaling == "bilinear8" ) { // todo - allow setting custom value in symbolizer property? @@ -246,89 +267,70 @@ private: } } } - } } } - std::set::const_iterator namesIter=names.begin(); - std::set::const_iterator namesEnd =names.end(); - - // push all property names - for (;namesIter!=namesEnd;++namesIter) + + // process features + featureset_ptr fs; + if (first) { - q.add_property_name(*namesIter); + first = false; + fs = ds->features(q); } - if (active_rules) + else { - featureset_ptr fs; - if (first) - { - first = false; - fs = ds->features(q); - } - else - { - fs = cache.features(q); - } - if (fs) - { - feature_ptr feature; - while ((feature = fs->next())) - { - bool do_else=true; - - if (cache_features) - { - cache.push(feature); - } - - std::vector::const_iterator itr=if_rules.begin(); - std::vector::const_iterator end=if_rules.end(); - for (;itr != end;++itr) - { - expression_ptr const& expr=(*itr)->get_filter(); - value_type result = boost::apply_visitor(evaluate(*feature),*expr); - if (result.to_bool()) + fs = cache.features(q); + } + + if (fs) + { + feature_ptr feature; + while ((feature = fs->next())) + { + bool do_else=true; + + if (cache_features) + { + cache.push(feature); + } + + BOOST_FOREACH(rule_type * rule, if_rules ) + { + expression_ptr const& expr=rule->get_filter(); + value_type result = boost::apply_visitor(evaluate(*feature),*expr); + if (result.to_bool()) + { + do_else=false; + rule_type::symbolizers const& symbols = rule->get_symbolizers(); + BOOST_FOREACH (symbolizer const& sym, symbols) { - do_else=false; - const rule_type::symbolizers& symbols = (*itr)->get_symbolizers(); - rule_type::symbolizers::const_iterator symIter=symbols.begin(); - rule_type::symbolizers::const_iterator symEnd =symbols.end(); - for (;symIter != symEnd;++symIter) - { - boost::apply_visitor - (symbol_dispatch(p,*feature,prj_trans),*symIter); - } - } - } - if (do_else) - { - //else filter - std::vector::const_iterator itr= - else_rules.begin(); - std::vector::const_iterator end= - else_rules.end(); - for (;itr != end;++itr) - { - const rule_type::symbolizers& symbols = (*itr)->get_symbolizers(); - rule_type::symbolizers::const_iterator symIter= symbols.begin(); - rule_type::symbolizers::const_iterator symEnd = symbols.end(); - - for (;symIter!=symEnd;++symIter) - { - boost::apply_visitor - (symbol_dispatch(p,*feature,prj_trans),*symIter); - } + boost::apply_visitor + (symbol_dispatch(p,*feature,prj_trans),sym); } - } + } } - cache_features = false; + if (do_else) + { + BOOST_FOREACH( rule_type * rule, else_rules ) + { + rule_type::symbolizers const& symbols = rule->get_symbolizers(); + BOOST_FOREACH (symbolizer const& sym, symbols) + { + boost::apply_visitor + (symbol_dispatch(p,*feature,prj_trans),sym); + } + } + } } + cache_features = false; } - } - } + } + } + p.end_layer_processing(lay); - } + } + Map const& m_; double scale_factor_; };