apply patch from Peter Körner adding AlsoFilter functionality - closes #820

This commit is contained in:
Dane Springmeyer 2011-08-30 17:38:27 +00:00
parent fa1ab31c2c
commit 9e87c9f914
8 changed files with 91 additions and 6 deletions

View file

@ -39,6 +39,7 @@ Patches
- Aubrey Holland
- Konstantin Käfer
- Mak Kolybabi
- Peter Körner
- Stella Laurenzo
- Dennis Luxen
- Tom MacWright
@ -67,4 +68,4 @@ Patches
Community Wiki
==============
- http://trac.mapnik.org/stractistics
- http://trac.mapnik.org/stractistics

View file

@ -14,6 +14,8 @@ For a complete change history, see the SVN log.
Mapnik Trunk
------------
- Add AlsoFilter functionality - http://trac.mapnik.org/wiki/AlsoFilter
- SQLite Plugin: optimize io using shared cache and no mutexes (#797)
- Directly link input plugins to libmapnik to avoid having to set dlopen flags from binding languages (#790)

View file

@ -102,7 +102,7 @@ struct rule_pickle_suite : boost::python::pickle_suite
// We serialize filter expressions AST as strings
std::string filter_expr = to_expression_string(*r.get_filter());
return boost::python::make_tuple(r.get_abstract(),filter_expr,r.has_else_filter(),syms);
return boost::python::make_tuple(r.get_abstract(),filter_expr,r.has_else_filter(),r.has_also_filter(),syms);
}
static void
@ -138,8 +138,13 @@ struct rule_pickle_suite : boost::python::pickle_suite
{
r.set_else(true);
}
if (state[3])
{
r.set_also(true);
}
boost::python::list syms=extract<boost::python::list>(state[3]);
boost::python::list syms=extract<boost::python::list>(state[4]);
extract_symbolizer serializer( r );
for (int i=0;i<len(syms);++i)
{
@ -190,6 +195,8 @@ void export_rule()
.add_property("max_scale",&rule::get_max_scale,&rule::set_max_scale)
.def("set_else",&rule::set_else)
.def("has_else",&rule::has_else_filter)
.def("set_also",&rule::set_also)
.def("has_also",&rule::has_also_filter)
.def("active",&rule::active)
.add_property("symbols",make_function
(&rule::get_symbolizers,return_value_policy<reference_existing_object>()))

View file

@ -310,6 +310,7 @@ private:
{
std::vector<rule*> if_rules;
std::vector<rule*> else_rules;
std::vector<rule*> also_rules;
std::vector<rule> const& rules=style->get_rules();
@ -321,6 +322,10 @@ private:
{
else_rules.push_back(const_cast<rule*>(&r));
}
else if (r.has_also_filter())
{
also_rules.push_back(const_cast<rule*>(&r));
}
else
{
if_rules.push_back(const_cast<rule*>(&r));
@ -362,6 +367,7 @@ private:
while ((feature = fs->next()))
{
bool do_else=true;
bool do_also=false;
if (cache_features)
{
@ -375,6 +381,7 @@ private:
if (result.to_bool())
{
do_else=false;
do_also=true;
rule::symbolizers const& symbols = r->get_symbolizers();
// if the underlying renderer is not able to process the complete set of symbolizers,
@ -405,6 +412,24 @@ private:
// process one by one.
#ifdef SVG_RENDERER
if(!p.process(symbols,*feature,prj_trans))
#endif
{
BOOST_FOREACH (symbolizer const& sym, symbols)
{
boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
}
}
}
}
if (do_also)
{
BOOST_FOREACH( rule * r, also_rules )
{
rule::symbolizers const& symbols = r->get_symbolizers();
// if the underlying renderer is not able to process the complete set of symbolizers,
// process one by one.
#ifdef SVG_RENDERER
if(!p.process(symbols,*feature,prj_trans))
#endif
{
BOOST_FOREACH (symbolizer const& sym, symbols)

View file

@ -138,6 +138,7 @@ private:
symbolizers syms_;
expression_ptr filter_;
bool else_filter_;
bool also_filter_;
public:
rule()
: name_(),
@ -147,7 +148,8 @@ public:
max_scale_(std::numeric_limits<double>::infinity()),
syms_(),
filter_(boost::make_shared<mapnik::expr_node>(true)),
else_filter_(false) {}
else_filter_(false),
also_filter_(false) {}
rule(const std::string& name,
const std::string& title="",
@ -159,7 +161,8 @@ public:
max_scale_(max_scale_denominator),
syms_(),
filter_(boost::make_shared<mapnik::expr_node>(true)),
else_filter_(false) {}
else_filter_(false),
also_filter_(false) {}
rule(const rule& rhs)
: name_(rhs.name_),
@ -169,7 +172,8 @@ public:
max_scale_(rhs.max_scale_),
syms_(rhs.syms_),
filter_(rhs.filter_),
else_filter_(rhs.else_filter_) {}
else_filter_(rhs.else_filter_),
also_filter_(rhs.also_filter_) {}
rule& operator=(rule const& rhs)
{
@ -290,6 +294,16 @@ public:
return else_filter_;
}
void set_also(bool also_filter)
{
also_filter_=also_filter;
}
bool has_also_filter() const
{
return also_filter_;
}
bool active(double scale) const
{
return ( scale >= min_scale_ - 1e-6 && scale < max_scale_ + 1e-6);
@ -307,6 +321,7 @@ private:
syms_=rhs.syms_;
filter_=rhs.filter_;
else_filter_=rhs.else_filter_;
also_filter_=rhs.also_filter_;
}
};

View file

@ -733,6 +733,13 @@ void map_parser::parse_rule( feature_type_style & style, ptree const & r )
rule.set_else(true);
}
optional<std::string> also_filter =
get_opt_child<std::string>(r, "AlsoFilter");
if (also_filter)
{
rule.set_also(true);
}
optional<double> min_scale =
get_opt_child<double>(r, "MinScaleDenominator");
if (min_scale)
@ -803,6 +810,7 @@ void map_parser::parse_rule( feature_type_style & style, ptree const & r )
sym.first != "MaxScaleDenominator" &&
sym.first != "Filter" &&
sym.first != "ElseFilter" &&
sym.first != "AlsoFilter" &&
sym.first != "<xmlcomment>" &&
sym.first != "<xmlattr>" )
{

View file

@ -639,6 +639,11 @@ void serialize_rule( ptree & style_node, const rule & r, bool explicit_defaults)
rule_node.push_back( ptree::value_type(
"ElseFilter", ptree()));
}
else if ( r.has_also_filter() )
{
rule_node.push_back( ptree::value_type(
"AlsoFilter", ptree()));
}
else
{
// filters were not comparable, perhaps should now compare expressions?

View file

@ -539,6 +539,20 @@ def test_rule_init():
eq_(r.title, '')
eq_(r.min_scale, 0)
eq_(r.max_scale, float('inf'))
eq_(r.has_else(), False)
eq_(r.has_also(), False)
r = mapnik2.Rule()
r.set_else(True)
eq_(r.has_else(), True)
eq_(r.has_also(), False)
r = mapnik2.Rule()
r.set_also(True)
eq_(r.has_else(), False)
eq_(r.has_also(), True)
r = mapnik2.Rule("Name")
@ -546,6 +560,8 @@ def test_rule_init():
eq_(r.title, '')
eq_(r.min_scale, 0)
eq_(r.max_scale, float('inf'))
eq_(r.has_else(), False)
eq_(r.has_also(), False)
r = mapnik2.Rule("Name", "Title")
@ -553,6 +569,8 @@ def test_rule_init():
eq_(r.title, 'Title')
eq_(r.min_scale, 0)
eq_(r.max_scale, float('inf'))
eq_(r.has_else(), False)
eq_(r.has_also(), False)
r = mapnik2.Rule("Name", "Title", min_scale)
@ -560,6 +578,8 @@ def test_rule_init():
eq_(r.title, 'Title')
eq_(r.min_scale, min_scale)
eq_(r.max_scale, float('inf'))
eq_(r.has_else(), False)
eq_(r.has_also(), False)
r = mapnik2.Rule("Name", "Title", min_scale, max_scale)
@ -567,6 +587,8 @@ def test_rule_init():
eq_(r.title, 'Title')
eq_(r.min_scale, min_scale)
eq_(r.max_scale, max_scale)
eq_(r.has_else(), False)
eq_(r.has_also(), False)
# Coordinate initialization
def test_coord_init():