enable if/else type behavior in rules using style level keyword to control whether all rules will be evaluated or just the first that matches - closes #706 - thanks to original patch from kkaefer
This commit is contained in:
parent
1a2e1a7789
commit
7043c416fa
11 changed files with 138 additions and 22 deletions
1
AUTHORS
1
AUTHORS
|
@ -37,6 +37,7 @@ Patches
|
|||
- Beau Gunderson
|
||||
- John Hague
|
||||
- Aubrey Holland
|
||||
- Konstantin Käfer
|
||||
- Mak Kolybabi
|
||||
- Dennis Luxen
|
||||
- Tom MacWright
|
||||
|
|
|
@ -14,6 +14,8 @@ For a complete change history, see the SVN log.
|
|||
Mapnik Trunk
|
||||
------------
|
||||
|
||||
- Added support for drawing only first matching rule using filter-mode="first" in Style (#706)
|
||||
|
||||
- Added support to PointSymbolizer ('ignore_placement') for skipping adding placed points to collision detector (#564)
|
||||
|
||||
- Added ability to register fonts within XML using Map level 'font_directory' parameter (#168)
|
||||
|
|
|
@ -732,6 +732,7 @@ __all__ = [
|
|||
'horizontal_alignment',
|
||||
'justify_alignment',
|
||||
'pattern_alignment',
|
||||
'filter_mode',
|
||||
# functions
|
||||
# datasources
|
||||
'Datasource',
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <boost/python.hpp>
|
||||
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
|
||||
|
||||
#include "mapnik_enumeration.hpp"
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
|
||||
using mapnik::feature_type_style;
|
||||
|
@ -73,6 +74,11 @@ void export_style()
|
|||
{
|
||||
using namespace boost::python;
|
||||
|
||||
mapnik::enumeration_<mapnik::filter_mode_e>("filter_mode")
|
||||
.value("ALL",mapnik::FILTER_ALL)
|
||||
.value("FIRST",mapnik::FILTER_FIRST)
|
||||
;
|
||||
|
||||
class_<rules>("Rules",init<>("default ctor"))
|
||||
.def(vector_indexing_suite<rules>())
|
||||
;
|
||||
|
@ -92,6 +98,10 @@ void export_style()
|
|||
"<mapnik2._mapnik2.Rule object at 0x100549910>\n"
|
||||
"<mapnik2._mapnik2.Rule object at 0x100549980>\n"
|
||||
)
|
||||
.add_property("filter_mode",
|
||||
&feature_type_style::get_filter_mode,
|
||||
&feature_type_style::set_filter_mode,
|
||||
"Set/get the placement of the label")
|
||||
;
|
||||
|
||||
}
|
||||
|
|
|
@ -323,6 +323,11 @@ private:
|
|||
boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
|
||||
}
|
||||
}
|
||||
if (style->get_filter_mode() == FILTER_FIRST)
|
||||
{
|
||||
// Stop iterating over rules and proceed with next feature.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (do_else)
|
||||
|
|
|
@ -27,44 +27,44 @@
|
|||
// mapnik
|
||||
#include <mapnik/rule.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
// stl
|
||||
#include <vector>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
enum filter_mode_enum {
|
||||
FILTER_ALL,
|
||||
FILTER_FIRST,
|
||||
filter_mode_enum_MAX
|
||||
};
|
||||
|
||||
DEFINE_ENUM( filter_mode_e, filter_mode_enum );
|
||||
|
||||
typedef std::vector<rule> rules;
|
||||
class feature_type_style
|
||||
{
|
||||
private:
|
||||
rules rules_;
|
||||
filter_mode_e filter_mode_;
|
||||
public:
|
||||
feature_type_style() {}
|
||||
feature_type_style();
|
||||
|
||||
feature_type_style(feature_type_style const& rhs)
|
||||
: rules_(rhs.rules_) {}
|
||||
feature_type_style(feature_type_style const& rhs);
|
||||
|
||||
feature_type_style& operator=(feature_type_style const& rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
rules_=rhs.rules_;
|
||||
return *this;
|
||||
}
|
||||
feature_type_style& operator=(feature_type_style const& rhs);
|
||||
|
||||
void add_rule(rule const& rule)
|
||||
{
|
||||
rules_.push_back(rule);
|
||||
}
|
||||
void add_rule(rule const& rule);
|
||||
|
||||
rules const& get_rules() const
|
||||
{
|
||||
return rules_;
|
||||
}
|
||||
rules const& get_rules() const;
|
||||
|
||||
rules &get_rules_nonconst()
|
||||
{
|
||||
return rules_;
|
||||
}
|
||||
rules &get_rules_nonconst();
|
||||
|
||||
void set_filter_mode(filter_mode_e mode);
|
||||
|
||||
filter_mode_e get_filter_mode() const;
|
||||
|
||||
~feature_type_style() {}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ source = Split(
|
|||
expression_node.cpp
|
||||
expression_string.cpp
|
||||
filter_factory.cpp
|
||||
feature_type_style.cpp
|
||||
font_engine_freetype.cpp
|
||||
font_set.cpp
|
||||
gradient.cpp
|
||||
|
|
76
src/feature_type_style.cpp
Normal file
76
src/feature_type_style.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2010 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
static const char * filter_mode_strings[] = {
|
||||
"all",
|
||||
"first",
|
||||
""
|
||||
};
|
||||
|
||||
IMPLEMENT_ENUM( filter_mode_e, filter_mode_strings );
|
||||
|
||||
|
||||
feature_type_style::feature_type_style()
|
||||
: filter_mode_(FILTER_ALL) {}
|
||||
|
||||
feature_type_style::feature_type_style(feature_type_style const& rhs)
|
||||
: rules_(rhs.rules_),
|
||||
filter_mode_(rhs.filter_mode_) {}
|
||||
|
||||
feature_type_style& feature_type_style::operator=(feature_type_style const& rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
rules_=rhs.rules_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void feature_type_style::add_rule(rule const& rule)
|
||||
{
|
||||
rules_.push_back(rule);
|
||||
}
|
||||
|
||||
rules const& feature_type_style::get_rules() const
|
||||
{
|
||||
return rules_;
|
||||
}
|
||||
|
||||
rules &feature_type_style::get_rules_nonconst()
|
||||
{
|
||||
return rules_;
|
||||
}
|
||||
|
||||
void feature_type_style::set_filter_mode(filter_mode_e mode)
|
||||
{
|
||||
filter_mode_ = mode;
|
||||
}
|
||||
|
||||
filter_mode_e feature_type_style::get_filter_mode() const
|
||||
{
|
||||
return filter_mode_;
|
||||
}
|
||||
|
||||
}
|
|
@ -347,6 +347,9 @@ void map_parser::parse_style( Map & map, ptree const & sty )
|
|||
name = get_attr<string>(sty, "name");
|
||||
feature_type_style style;
|
||||
|
||||
filter_mode_e filter_mode = get_attr<filter_mode_e>(sty, "filter-mode", FILTER_ALL);
|
||||
style.set_filter_mode(filter_mode);
|
||||
|
||||
ptree::const_iterator ruleIter = sty.begin();
|
||||
ptree::const_iterator endRule = sty.end();
|
||||
|
||||
|
|
|
@ -632,11 +632,18 @@ void serialize_style( ptree & map_node, Map::const_style_iterator style_it, bool
|
|||
{
|
||||
const feature_type_style & style = style_it->second;
|
||||
const std::string & name = style_it->first;
|
||||
filter_mode_e filter_mode = style.get_filter_mode();
|
||||
|
||||
ptree & style_node = map_node.push_back(
|
||||
ptree::value_type("Style", ptree()))->second;
|
||||
|
||||
set_attr(style_node, "name", name);
|
||||
|
||||
feature_type_style dfl;
|
||||
if (filter_mode != dfl.get_filter_mode() || explicit_defaults)
|
||||
{
|
||||
set_attr(style_node, "filter-mode", filter_mode);
|
||||
}
|
||||
|
||||
rules::const_iterator it = style.get_rules().begin();
|
||||
rules::const_iterator end = style.get_rules().end();
|
||||
|
|
|
@ -42,6 +42,12 @@ map_ = '''<Map>
|
|||
</Rule>
|
||||
|
||||
</Style>
|
||||
<Style name="s2" filter-mode="first">
|
||||
<Rule>
|
||||
</Rule>
|
||||
<Rule>
|
||||
</Rule>
|
||||
</Style>
|
||||
</Map>'''
|
||||
|
||||
def test_filter_init():
|
||||
|
@ -80,4 +86,8 @@ def test_filter_init():
|
|||
|
||||
first = filters[0]
|
||||
for f in filters:
|
||||
eq_(str(first),str(f))
|
||||
eq_(str(first),str(f))
|
||||
|
||||
s = m.find_style('s2')
|
||||
|
||||
eq_(s.filter_mode,mapnik2.filter_mode.FIRST)
|
||||
|
|
Loading…
Reference in a new issue