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
|
- Beau Gunderson
|
||||||
- John Hague
|
- John Hague
|
||||||
- Aubrey Holland
|
- Aubrey Holland
|
||||||
|
- Konstantin Käfer
|
||||||
- Mak Kolybabi
|
- Mak Kolybabi
|
||||||
- Dennis Luxen
|
- Dennis Luxen
|
||||||
- Tom MacWright
|
- Tom MacWright
|
||||||
|
|
|
@ -14,6 +14,8 @@ For a complete change history, see the SVN log.
|
||||||
Mapnik Trunk
|
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 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)
|
- Added ability to register fonts within XML using Map level 'font_directory' parameter (#168)
|
||||||
|
|
|
@ -732,6 +732,7 @@ __all__ = [
|
||||||
'horizontal_alignment',
|
'horizontal_alignment',
|
||||||
'justify_alignment',
|
'justify_alignment',
|
||||||
'pattern_alignment',
|
'pattern_alignment',
|
||||||
|
'filter_mode',
|
||||||
# functions
|
# functions
|
||||||
# datasources
|
# datasources
|
||||||
'Datasource',
|
'Datasource',
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
|
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
|
||||||
|
|
||||||
|
#include "mapnik_enumeration.hpp"
|
||||||
#include <mapnik/feature_type_style.hpp>
|
#include <mapnik/feature_type_style.hpp>
|
||||||
|
|
||||||
using mapnik::feature_type_style;
|
using mapnik::feature_type_style;
|
||||||
|
@ -73,6 +74,11 @@ void export_style()
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
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"))
|
class_<rules>("Rules",init<>("default ctor"))
|
||||||
.def(vector_indexing_suite<rules>())
|
.def(vector_indexing_suite<rules>())
|
||||||
;
|
;
|
||||||
|
@ -92,6 +98,10 @@ void export_style()
|
||||||
"<mapnik2._mapnik2.Rule object at 0x100549910>\n"
|
"<mapnik2._mapnik2.Rule object at 0x100549910>\n"
|
||||||
"<mapnik2._mapnik2.Rule object at 0x100549980>\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);
|
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)
|
if (do_else)
|
||||||
|
|
|
@ -27,43 +27,43 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/rule.hpp>
|
#include <mapnik/rule.hpp>
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/enumeration.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace mapnik
|
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;
|
typedef std::vector<rule> rules;
|
||||||
class feature_type_style
|
class feature_type_style
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
rules rules_;
|
rules rules_;
|
||||||
|
filter_mode_e filter_mode_;
|
||||||
public:
|
public:
|
||||||
feature_type_style() {}
|
feature_type_style();
|
||||||
|
|
||||||
feature_type_style(feature_type_style const& rhs)
|
feature_type_style(feature_type_style const& rhs);
|
||||||
: rules_(rhs.rules_) {}
|
|
||||||
|
|
||||||
feature_type_style& operator=(feature_type_style const& rhs)
|
feature_type_style& operator=(feature_type_style const& rhs);
|
||||||
{
|
|
||||||
if (this == &rhs) return *this;
|
|
||||||
rules_=rhs.rules_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_rule(rule const& rule)
|
void add_rule(rule const& rule);
|
||||||
{
|
|
||||||
rules_.push_back(rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
rules const& get_rules() const
|
rules const& get_rules() const;
|
||||||
{
|
|
||||||
return rules_;
|
|
||||||
}
|
|
||||||
|
|
||||||
rules &get_rules_nonconst()
|
rules &get_rules_nonconst();
|
||||||
{
|
|
||||||
return rules_;
|
void set_filter_mode(filter_mode_e mode);
|
||||||
}
|
|
||||||
|
filter_mode_e get_filter_mode() const;
|
||||||
|
|
||||||
~feature_type_style() {}
|
~feature_type_style() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,6 +102,7 @@ source = Split(
|
||||||
expression_node.cpp
|
expression_node.cpp
|
||||||
expression_string.cpp
|
expression_string.cpp
|
||||||
filter_factory.cpp
|
filter_factory.cpp
|
||||||
|
feature_type_style.cpp
|
||||||
font_engine_freetype.cpp
|
font_engine_freetype.cpp
|
||||||
font_set.cpp
|
font_set.cpp
|
||||||
gradient.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");
|
name = get_attr<string>(sty, "name");
|
||||||
feature_type_style style;
|
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 ruleIter = sty.begin();
|
||||||
ptree::const_iterator endRule = sty.end();
|
ptree::const_iterator endRule = sty.end();
|
||||||
|
|
||||||
|
|
|
@ -632,12 +632,19 @@ void serialize_style( ptree & map_node, Map::const_style_iterator style_it, bool
|
||||||
{
|
{
|
||||||
const feature_type_style & style = style_it->second;
|
const feature_type_style & style = style_it->second;
|
||||||
const std::string & name = style_it->first;
|
const std::string & name = style_it->first;
|
||||||
|
filter_mode_e filter_mode = style.get_filter_mode();
|
||||||
|
|
||||||
ptree & style_node = map_node.push_back(
|
ptree & style_node = map_node.push_back(
|
||||||
ptree::value_type("Style", ptree()))->second;
|
ptree::value_type("Style", ptree()))->second;
|
||||||
|
|
||||||
set_attr(style_node, "name", name);
|
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 it = style.get_rules().begin();
|
||||||
rules::const_iterator end = style.get_rules().end();
|
rules::const_iterator end = style.get_rules().end();
|
||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
|
|
|
@ -42,6 +42,12 @@ map_ = '''<Map>
|
||||||
</Rule>
|
</Rule>
|
||||||
|
|
||||||
</Style>
|
</Style>
|
||||||
|
<Style name="s2" filter-mode="first">
|
||||||
|
<Rule>
|
||||||
|
</Rule>
|
||||||
|
<Rule>
|
||||||
|
</Rule>
|
||||||
|
</Style>
|
||||||
</Map>'''
|
</Map>'''
|
||||||
|
|
||||||
def test_filter_init():
|
def test_filter_init():
|
||||||
|
@ -81,3 +87,7 @@ def test_filter_init():
|
||||||
first = filters[0]
|
first = filters[0]
|
||||||
for f in filters:
|
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