static grammars

- construct on first use
 - allows for faster map loading and unloading of xml loading tree
 - modified expression and transform grammars to not take args/not crash
 - simplifies interfaces, allows fast parsing from python without passing grammar instance
This commit is contained in:
Dane Springmeyer 2014-04-30 00:11:27 -07:00
parent ab7fc55535
commit 8c1e69fdb8
19 changed files with 70 additions and 97 deletions

View file

@ -39,8 +39,7 @@ public:
expr_("((([mapnik::geometry_type]=2) and ([oneway]=1)) and ([class]='path'))") {} expr_("((([mapnik::geometry_type]=2) and ([oneway]=1)) and ([class]='path'))") {}
bool validate() const bool validate() const
{ {
mapnik::transcoder tr("utf-8"); mapnik::expression_grammar<std::string::const_iterator> expr_grammar;;
mapnik::expression_grammar<std::string::const_iterator> expr_grammar(tr);
mapnik::expression_ptr expr = mapnik::parse_expression(expr_,expr_grammar); mapnik::expression_ptr expr = mapnik::parse_expression(expr_,expr_grammar);
std::string result = mapnik::to_expression_string(*expr); std::string result = mapnik::to_expression_string(*expr);
bool ret = (result == expr_); bool ret = (result == expr_);
@ -52,8 +51,7 @@ public:
} }
void operator()() const void operator()() const
{ {
mapnik::transcoder tr("utf-8"); mapnik::expression_grammar<std::string::const_iterator> expr_grammar;
mapnik::expression_grammar<std::string::const_iterator> expr_grammar(tr);
for (std::size_t i=0;i<iterations_;++i) { for (std::size_t i=0;i<iterations_;++i) {
mapnik::expression_ptr expr = mapnik::parse_expression(expr_,expr_grammar); mapnik::expression_ptr expr = mapnik::parse_expression(expr_,expr_grammar);
} }

View file

@ -33,9 +33,6 @@
#include <mapnik/color_factory.hpp> #include <mapnik/color_factory.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/expression.hpp>
#include <mapnik/expression_string.hpp>
#include <mapnik/expression_grammar.hpp>
#if defined(HAVE_CAIRO) #if defined(HAVE_CAIRO)
#include <mapnik/cairo_renderer.hpp> #include <mapnik/cairo_renderer.hpp>
@ -58,9 +55,6 @@ int main ( int argc , char** argv)
datasource_cache::instance().register_datasources("plugins/input/"); datasource_cache::instance().register_datasources("plugins/input/");
freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.33/ttf/DejaVuSans.ttf"); freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.33/ttf/DejaVuSans.ttf");
mapnik::transcoder tr("utf-8");
mapnik::expression_grammar<std::string::const_iterator> expr_grammar(tr);
Map m(800,600); Map m(800,600);
m.set_background(parse_color("white")); m.set_background(parse_color("white"));
m.set_srs(srs_merc); m.set_srs(srs_merc);
@ -70,7 +64,7 @@ int main ( int argc , char** argv)
feature_type_style provpoly_style; feature_type_style provpoly_style;
{ {
rule r; rule r;
r.set_filter(parse_expression("[NAME_EN] = 'Ontario'", expr_grammar)); r.set_filter(parse_expression("[NAME_EN] = 'Ontario'"));
{ {
polygon_symbolizer poly_sym; polygon_symbolizer poly_sym;
put(poly_sym, keys::fill, color(250, 190, 183)); put(poly_sym, keys::fill, color(250, 190, 183));
@ -80,7 +74,7 @@ int main ( int argc , char** argv)
} }
{ {
rule r; rule r;
r.set_filter(parse_expression("[NOM_FR] = 'Québec'", expr_grammar)); r.set_filter(parse_expression("[NOM_FR] = 'Québec'"));
{ {
polygon_symbolizer poly_sym; polygon_symbolizer poly_sym;
put(poly_sym, keys::fill, color(217, 235, 203)); put(poly_sym, keys::fill, color(217, 235, 203));
@ -113,7 +107,7 @@ int main ( int argc , char** argv)
feature_type_style qcdrain_style; feature_type_style qcdrain_style;
{ {
rule r; rule r;
r.set_filter(parse_expression("[HYC] = 8", expr_grammar)); r.set_filter(parse_expression("[HYC] = 8"));
{ {
polygon_symbolizer poly_sym; polygon_symbolizer poly_sym;
put(poly_sym, keys::fill, color(153, 204, 255)); put(poly_sym, keys::fill, color(153, 204, 255));
@ -127,7 +121,7 @@ int main ( int argc , char** argv)
feature_type_style roads34_style; feature_type_style roads34_style;
{ {
rule r; rule r;
r.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4", expr_grammar)); r.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(171,158,137)); put(line_sym,keys::stroke,color(171,158,137));
@ -144,7 +138,7 @@ int main ( int argc , char** argv)
feature_type_style roads2_style_1; feature_type_style roads2_style_1;
{ {
rule r; rule r;
r.set_filter(parse_expression("[CLASS] = 2", expr_grammar)); r.set_filter(parse_expression("[CLASS] = 2"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(171,158,137)); put(line_sym,keys::stroke,color(171,158,137));
@ -160,7 +154,7 @@ int main ( int argc , char** argv)
feature_type_style roads2_style_2; feature_type_style roads2_style_2;
{ {
rule r; rule r;
r.set_filter(parse_expression("[CLASS] = 2", expr_grammar)); r.set_filter(parse_expression("[CLASS] = 2"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(255,250,115)); put(line_sym,keys::stroke,color(255,250,115));
@ -177,7 +171,7 @@ int main ( int argc , char** argv)
feature_type_style roads1_style_1; feature_type_style roads1_style_1;
{ {
rule r; rule r;
r.set_filter(parse_expression("[CLASS] = 1", expr_grammar)); r.set_filter(parse_expression("[CLASS] = 1"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(188,149,28)); put(line_sym,keys::stroke,color(188,149,28));
@ -193,7 +187,7 @@ int main ( int argc , char** argv)
feature_type_style roads1_style_2; feature_type_style roads1_style_2;
{ {
rule r; rule r;
r.set_filter(parse_expression("[CLASS] = 1", expr_grammar)); r.set_filter(parse_expression("[CLASS] = 1"));
{ {
line_symbolizer line_sym; line_symbolizer line_sym;
put(line_sym,keys::stroke,color(242,191,36)); put(line_sym,keys::stroke,color(242,191,36));
@ -218,7 +212,7 @@ int main ( int argc , char** argv)
placement_finder->defaults.format->fill = color(0,0,0); placement_finder->defaults.format->fill = color(0,0,0);
placement_finder->defaults.format->halo_fill = color(255,255,200); placement_finder->defaults.format->halo_fill = color(255,255,200);
placement_finder->defaults.format->halo_radius = 1; placement_finder->defaults.format->halo_radius = 1;
placement_finder->defaults.set_old_style_expression(parse_expression("[GEONAME]", expr_grammar)); placement_finder->defaults.set_old_style_expression(parse_expression("[GEONAME]"));
put<text_placements_ptr>(text_sym, keys::text_placements_, placement_finder); put<text_placements_ptr>(text_sym, keys::text_placements_, placement_finder);
r.append(std::move(text_sym)); r.append(std::move(text_sym));
} }

View file

@ -127,10 +127,11 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
{ {
typedef qi::rule<Iterator, expr_node(), space_type> rule_type; typedef qi::rule<Iterator, expr_node(), space_type> rule_type;
explicit expression_grammar(mapnik::transcoder const& tr); explicit expression_grammar();
qi::real_parser<double, qi::strict_real_policies<double> > strict_double; qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
typename integer_parser<mapnik::value_integer>::type int__; typename integer_parser<mapnik::value_integer>::type int__;
mapnik::transcoder tr_;
boost::phoenix::function<unicode_impl> unicode_; boost::phoenix::function<unicode_impl> unicode_;
boost::phoenix::function<regex_match_impl> regex_match_; boost::phoenix::function<regex_match_impl> regex_match_;
boost::phoenix::function<regex_replace_impl> regex_replace_; boost::phoenix::function<regex_replace_impl> regex_replace_;

View file

@ -64,11 +64,12 @@ expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const
} }
template <typename Iterator> template <typename Iterator>
expression_grammar<Iterator>::expression_grammar(mapnik::transcoder const& tr) expression_grammar<Iterator>::expression_grammar()
: expression_grammar::base_type(expr), : expression_grammar::base_type(expr),
unicode_(unicode_impl(tr)), tr_("utf-8"),
regex_match_(regex_match_impl(tr)), unicode_(unicode_impl(tr_)),
regex_replace_(regex_replace_impl(tr)) regex_match_(regex_match_impl(tr_)),
regex_replace_(regex_replace_impl(tr_))
{ {
qi::_1_type _1; qi::_1_type _1;
qi::_a_type _a; qi::_a_type _a;

View file

@ -39,6 +39,9 @@ MAPNIK_DECL transform_list_ptr parse_transform(std::string const& str);
MAPNIK_DECL transform_list_ptr parse_transform(std::string const& str, MAPNIK_DECL transform_list_ptr parse_transform(std::string const& str,
std::string const& encoding); std::string const& encoding);
MAPNIK_DECL bool parse_transform(transform_list& list,
std::string const& str);
MAPNIK_DECL bool parse_transform(transform_list& list, MAPNIK_DECL bool parse_transform(transform_list& list,
std::string const& str, std::string const& str,
transform_expression_grammar_string const& g); transform_expression_grammar_string const& g);

View file

@ -38,7 +38,7 @@ namespace mapnik {
struct transform_expression_grammar struct transform_expression_grammar
: qi::grammar<Iterator, transform_list(), space_type> : qi::grammar<Iterator, transform_list(), space_type>
{ {
explicit transform_expression_grammar(expression_grammar<Iterator> const& g); explicit transform_expression_grammar();
typedef qi::rule<Iterator, transform_node(), space_type> node_rule; typedef qi::rule<Iterator, transform_node(), space_type> node_rule;
typedef qi::rule<Iterator, transform_list(), space_type> list_rule; typedef qi::rule<Iterator, transform_list(), space_type> list_rule;
@ -57,6 +57,7 @@ namespace mapnik {
qi::rule<Iterator, transform_node(), space_type> rotate; qi::rule<Iterator, transform_node(), space_type> rotate;
qi::rule<Iterator, transform_node(), space_type> skewX; qi::rule<Iterator, transform_node(), space_type> skewX;
qi::rule<Iterator, transform_node(), space_type> skewY; qi::rule<Iterator, transform_node(), space_type> skewY;
mapnik::expression_grammar<Iterator> g_;
}; };
} // namespace mapnik } // namespace mapnik

View file

@ -160,7 +160,7 @@ struct do_xml_attribute_cast<mapnik::color>
{ {
static inline boost::optional<mapnik::color> xml_attribute_cast_impl(xml_tree const& tree, std::string const& source) static inline boost::optional<mapnik::color> xml_attribute_cast_impl(xml_tree const& tree, std::string const& source)
{ {
return parse_color(source, tree.color_grammar); return parse_color(source);
} }
}; };
@ -187,7 +187,7 @@ struct do_xml_attribute_cast<mapnik::expression_ptr>
} }
else else
{ {
mapnik::expression_ptr expr = parse_expression(source, tree.expr_grammar); mapnik::expression_ptr expr = parse_expression(source);
tree.expr_cache_.insert(std::move(std::make_pair(source,expr))); tree.expr_cache_.insert(std::move(std::make_pair(source,expr)));
return expr; return expr;
} }

View file

@ -26,20 +26,15 @@
// mapnik // mapnik
#include <mapnik/xml_node.hpp> #include <mapnik/xml_node.hpp>
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
#include <mapnik/expression_grammar.hpp>
#include <mapnik/path_expression_grammar.hpp>
#include <mapnik/transform_expression_grammar.hpp>
#include <mapnik/image_filter_grammar.hpp>
#include <mapnik/image_filter.hpp>
#include <mapnik/css_color_grammar.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
//stl //stl
#include <string> #include <string>
#include <memory>
namespace mapnik namespace mapnik
{ {
class xml_tree class xml_tree
{ {
public: public:
@ -54,11 +49,6 @@ private:
transcoder tr_; transcoder tr_;
public: public:
mutable std::map<std::string,mapnik::expression_ptr> expr_cache_; mutable std::map<std::string,mapnik::expression_ptr> expr_cache_;
mapnik::css_color_grammar<std::string::const_iterator> color_grammar;
mapnik::expression_grammar<std::string::const_iterator> expr_grammar;
path_expression_grammar<std::string::const_iterator> path_expr_grammar;
transform_expression_grammar<std::string::const_iterator> transform_expr_grammar;
image_filter_grammar<std::string::const_iterator,std::vector<filter::filter_type> > image_filters_grammar;
}; };

View file

@ -423,8 +423,8 @@ void csv_datasource::parse_csv(T & stream,
} }
mapnik::transcoder tr(desc_.get_encoding()); mapnik::transcoder tr(desc_.get_encoding());
mapnik::wkt_parser parse_wkt; //mapnik::wkt_parser parse_wkt;
mapnik::json::geometry_parser<std::string::const_iterator> parse_json; //mapnik::json::geometry_parser<std::string::const_iterator> parse_json;
// handle rare case of a single line of data and user-provided headers // handle rare case of a single line of data and user-provided headers
// where a lack of a newline will mean that std::getline returns false // where a lack of a newline will mean that std::getline returns false
@ -543,7 +543,7 @@ void csv_datasource::parse_csv(T & stream,
break; break;
} }
if (parse_wkt.parse(value, feature->paths())) if (mapnik::from_wkt(value, feature->paths()))
{ {
parsed_wkt = true; parsed_wkt = true;
} }
@ -578,7 +578,7 @@ void csv_datasource::parse_csv(T & stream,
{ {
break; break;
} }
if (parse_json.parse(value.begin(),value.end(), feature->paths())) if (mapnik::json::from_geojson(value, feature->paths()))
{ {
parsed_json = true; parsed_json = true;
} }
@ -686,7 +686,7 @@ void csv_datasource::parse_csv(T & stream,
(value_length > 1 && !has_dot && value[0] == '0')) (value_length > 1 && !has_dot && value[0] == '0'))
{ {
matched = true; matched = true;
feature->put(fld_name,tr.transcode(value.c_str())); feature->put(fld_name,std::move(tr.transcode(value.c_str())));
if (feature_count == 1) if (feature_count == 1)
{ {
desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String));
@ -732,7 +732,7 @@ void csv_datasource::parse_csv(T & stream,
if (!matched) if (!matched)
{ {
// fallback to normal string // fallback to normal string
feature->put(fld_name,tr.transcode(value.c_str())); feature->put(fld_name,std::move(tr.transcode(value.c_str())));
if (feature_count == 1) if (feature_count == 1)
{ {
desc_.add_descriptor( desc_.add_descriptor(

View file

@ -30,7 +30,7 @@ namespace mapnik {
color parse_color(std::string const& str) color parse_color(std::string const& str)
{ {
css_color_grammar<std::string::const_iterator> g; static css_color_grammar<std::string::const_iterator> g;
return parse_color(str, g); return parse_color(str, g);
} }

View file

@ -35,8 +35,7 @@ namespace mapnik
expression_ptr parse_expression(std::string const& str, std::string const& encoding) expression_ptr parse_expression(std::string const& str, std::string const& encoding)
{ {
transcoder tr(encoding); static expression_grammar<std::string::const_iterator> g;
expression_grammar<std::string::const_iterator> g(tr);
return parse_expression(str, g); return parse_expression(str, g);
} }

View file

@ -46,7 +46,7 @@ bool parse_image_filters(std::string const& filters, std::vector<filter_type>& i
{ {
std::string::const_iterator itr = filters.begin(); std::string::const_iterator itr = filters.begin();
std::string::const_iterator end = filters.end(); std::string::const_iterator end = filters.end();
mapnik::image_filter_grammar<std::string::const_iterator, static mapnik::image_filter_grammar<std::string::const_iterator,
std::vector<mapnik::filter::filter_type> > filter_grammar; std::vector<mapnik::filter::filter_type> > filter_grammar;
boost::spirit::qi::ascii::space_type space; boost::spirit::qi::ascii::space_type space;
bool r = boost::spirit::qi::phrase_parse(itr,end, bool r = boost::spirit::qi::phrase_parse(itr,end,

View file

@ -52,7 +52,7 @@ bool geometry_parser<Iterator>::parse(iterator_type first, iterator_type last, b
bool from_geojson(std::string const& json, boost::ptr_vector<geometry_type> & paths) bool from_geojson(std::string const& json, boost::ptr_vector<geometry_type> & paths)
{ {
geometry_parser<std::string::const_iterator> parser; static geometry_parser<std::string::const_iterator> parser;
std::string::const_iterator start = json.begin(); std::string::const_iterator start = json.begin();
std::string::const_iterator end = json.end(); std::string::const_iterator end = json.end();
return parser.parse(start, end ,paths); return parser.parse(start, end ,paths);

View file

@ -55,7 +55,7 @@
#include <mapnik/image_filter_types.hpp> #include <mapnik/image_filter_types.hpp>
#include <mapnik/projection.hpp> #include <mapnik/projection.hpp>
#include <mapnik/group/group_rule.hpp> #include <mapnik/group/group_rule.hpp>
#include <mapnik/transform_expression.hpp>
// boost // boost
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -467,18 +467,9 @@ void map_parser::parse_style(Map & map, xml_node const& sty)
optional<std::string> filters = sty.get_opt_attr<std::string>("image-filters"); optional<std::string> filters = sty.get_opt_attr<std::string>("image-filters");
if (filters) if (filters)
{ {
std::string::const_iterator itr = filters->begin(); if (!parse_image_filters(*filters, style.image_filters())) {
std::string::const_iterator end = filters->end(); throw config_error("failed to parse image-filters: '" + *filters + "'");
boost::spirit::qi::ascii::space_type space;
bool result = boost::spirit::qi::phrase_parse(itr,end,
sty.get_tree().image_filters_grammar,
space,
style.image_filters());
if (!result || itr!=end)
{
throw config_error("failed to parse image-filters: '" + std::string(itr,end) + "'");
} }
} }
// direct image filters (applied directly on main image buffer // direct image filters (applied directly on main image buffer
@ -488,16 +479,8 @@ void map_parser::parse_style(Map & map, xml_node const& sty)
optional<std::string> direct_filters = sty.get_opt_attr<std::string>("direct-image-filters"); optional<std::string> direct_filters = sty.get_opt_attr<std::string>("direct-image-filters");
if (direct_filters) if (direct_filters)
{ {
std::string::const_iterator itr = direct_filters->begin(); if (!parse_image_filters(*direct_filters, style.direct_image_filters())) {
std::string::const_iterator end = direct_filters->end(); throw config_error("failed to parse direct-image-filters: '" + *direct_filters + "'");
boost::spirit::qi::ascii::space_type space;
bool result = boost::spirit::qi::phrase_parse(itr,end,
sty.get_tree().image_filters_grammar,
space,
style.direct_image_filters());
if (!result || itr!=end)
{
throw config_error("failed to parse direct-image-filters: '" + std::string(itr,end) + "'");
} }
} }
@ -926,7 +909,7 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
if (geometry_transform_wkt) if (geometry_transform_wkt)
{ {
mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>(); mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>();
if (!mapnik::parse_transform(*tl, *geometry_transform_wkt, pt.get_tree().transform_expr_grammar)) if (!mapnik::parse_transform(*tl, *geometry_transform_wkt))
{ {
std::string ss("Could not parse transform from '"); std::string ss("Could not parse transform from '");
ss += *geometry_transform_wkt + "', expected transform attribute"; ss += *geometry_transform_wkt + "', expected transform attribute";
@ -989,12 +972,12 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym)
*file = ensure_relative_to_xml(file); *file = ensure_relative_to_xml(file);
std::string filename = *file; std::string filename = *file;
ensure_exists(filename); ensure_exists(filename);
put(symbol, keys::file, parse_path(filename, sym.get_tree().path_expr_grammar)); put(symbol, keys::file, parse_path(filename));
if (image_transform_wkt) if (image_transform_wkt)
{ {
mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>(); mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>();
if (!mapnik::parse_transform(*tl, *image_transform_wkt, sym.get_tree().transform_expr_grammar)) if (!mapnik::parse_transform(*tl, *image_transform_wkt))
{ {
throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'"); throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'");
} }
@ -1058,7 +1041,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym)
if (!filename.empty()) if (!filename.empty())
{ {
ensure_exists(filename); ensure_exists(filename);
put(symbol,keys::file, parse_path(filename, sym.get_tree().path_expr_grammar)); put(symbol,keys::file, parse_path(filename));
} }
// overall opacity to be applied to all paths // overall opacity to be applied to all paths
@ -1071,7 +1054,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym)
if (image_transform_wkt) if (image_transform_wkt)
{ {
mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>(); mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>();
if (!mapnik::parse_transform(*tl, *image_transform_wkt, sym.get_tree().transform_expr_grammar)) if (!mapnik::parse_transform(*tl, *image_transform_wkt))
{ {
throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'"); throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'");
} }
@ -1139,7 +1122,7 @@ void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & sym
file = ensure_relative_to_xml(file); file = ensure_relative_to_xml(file);
ensure_exists(file); ensure_exists(file);
line_pattern_symbolizer symbol; line_pattern_symbolizer symbol;
put(symbol, keys::file, parse_path(file, sym.get_tree().path_expr_grammar)); put(symbol, keys::file, parse_path(file));
// offset value // offset value
optional<double> offset = sym.get_opt_attr<double>("offset"); optional<double> offset = sym.get_opt_attr<double>("offset");
@ -1181,7 +1164,7 @@ void map_parser::parse_polygon_pattern_symbolizer(rule & rule,
file = ensure_relative_to_xml(file); file = ensure_relative_to_xml(file);
ensure_exists(file); ensure_exists(file);
polygon_pattern_symbolizer symbol; polygon_pattern_symbolizer symbol;
put(symbol, keys::file, parse_path(file, sym.get_tree().path_expr_grammar)); put(symbol, keys::file, parse_path(file));
// pattern alignment // pattern alignment
optional<pattern_alignment_e> p_alignment = sym.get_opt_attr<pattern_alignment_e>("alignment"); optional<pattern_alignment_e> p_alignment = sym.get_opt_attr<pattern_alignment_e>("alignment");
@ -1239,7 +1222,7 @@ void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym)
if (halo_transform_wkt) if (halo_transform_wkt)
{ {
mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>(); mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>();
if (!mapnik::parse_transform(*tl, *halo_transform_wkt, sym.get_tree().transform_expr_grammar)) if (!mapnik::parse_transform(*tl, *halo_transform_wkt))
{ {
throw mapnik::config_error("Failed to parse halo-transform: '" + *halo_transform_wkt + "'"); throw mapnik::config_error("Failed to parse halo-transform: '" + *halo_transform_wkt + "'");
} }
@ -1279,7 +1262,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym)
if (image_transform_wkt) if (image_transform_wkt)
{ {
mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>(); mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>();
if (!mapnik::parse_transform(*tl, *image_transform_wkt, sym.get_tree().transform_expr_grammar)) if (!mapnik::parse_transform(*tl, *image_transform_wkt))
{ {
throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'"); throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'");
} }
@ -1332,7 +1315,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym)
file = ensure_relative_to_xml(file); file = ensure_relative_to_xml(file);
ensure_exists(file); ensure_exists(file);
put(shield_symbol, keys::file , parse_path(file, sym.get_tree().path_expr_grammar)); put(shield_symbol, keys::file , parse_path(file));
parse_symbolizer_base(shield_symbol, sym); parse_symbolizer_base(shield_symbol, sym);
optional<halo_rasterizer_e> halo_rasterizer_ = sym.get_opt_attr<halo_rasterizer_e>("halo-rasterizer"); optional<halo_rasterizer_e> halo_rasterizer_ = sym.get_opt_attr<halo_rasterizer_e>("halo-rasterizer");
if (halo_rasterizer_) put(shield_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_)); if (halo_rasterizer_) put(shield_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_));

View file

@ -40,7 +40,7 @@ namespace mapnik {
path_expression_ptr parse_path(std::string const& str) path_expression_ptr parse_path(std::string const& str)
{ {
path_expression_grammar<std::string::const_iterator> g; static path_expression_grammar<std::string::const_iterator> g;
return parse_path(str,g); return parse_path(str,g);
} }

View file

@ -36,10 +36,7 @@ transform_list_ptr parse_transform(std::string const& str)
transform_list_ptr parse_transform(std::string const& str, std::string const& encoding) transform_list_ptr parse_transform(std::string const& str, std::string const& encoding)
{ {
transform_list_ptr tl = std::make_shared<transform_list>(); transform_list_ptr tl = std::make_shared<transform_list>();
transcoder tc(encoding); static transform_expression_grammar_string gte;
expression_grammar<std::string::const_iterator> ge(tc);
transform_expression_grammar_string gte(ge);
if (!parse_transform(*tl, str, gte)) if (!parse_transform(*tl, str, gte))
{ {
tl.reset(); tl.reset();
@ -47,6 +44,13 @@ transform_list_ptr parse_transform(std::string const& str, std::string const& en
return tl; return tl;
} }
bool parse_transform(transform_list& tl,
std::string const& str)
{
static transform_expression_grammar_string gte;
return parse_transform(tl, str, gte);
}
bool parse_transform(transform_list& transform, bool parse_transform(transform_list& transform,
std::string const& str, std::string const& str,
transform_expression_grammar_string const& g) transform_expression_grammar_string const& g)

View file

@ -34,7 +34,7 @@ namespace mapnik {
namespace qi = boost::spirit::qi; namespace qi = boost::spirit::qi;
template <typename Iterator> template <typename Iterator>
transform_expression_grammar<Iterator>::transform_expression_grammar(expression_grammar<Iterator> const& g) transform_expression_grammar<Iterator>::transform_expression_grammar()
: transform_expression_grammar::base_type(start) : transform_expression_grammar::base_type(start)
{ {
using boost::phoenix::construct; using boost::phoenix::construct;
@ -123,8 +123,8 @@ transform_expression_grammar<Iterator>::transform_expression_grammar(expression_
// expressions are separated by a comma. // expressions are separated by a comma.
sep_expr = lit(',') >> expr [ _val = _1 ]; sep_expr = lit(',') >> expr [ _val = _1 ];
attr = g.attr.alias(); attr = g_.attr.alias();
expr = g.expr.alias(); expr = g_.expr.alias();
} }
template struct mapnik::transform_expression_grammar<std::string::const_iterator>; template struct mapnik::transform_expression_grammar<std::string::const_iterator>;

View file

@ -47,7 +47,7 @@ bool wkt_parser::parse(std::string const& wkt, boost::ptr_vector<geometry_type>
bool from_wkt(std::string const& wkt, boost::ptr_vector<geometry_type> & paths) bool from_wkt(std::string const& wkt, boost::ptr_vector<geometry_type> & paths)
{ {
wkt_parser parser; static wkt_parser parser;
return parser.parse(wkt,paths); return parser.parse(wkt,paths);
} }

View file

@ -21,6 +21,7 @@
*****************************************************************************/ *****************************************************************************/
//mapnik //mapnik
#include <mapnik/std.hpp>
#include <mapnik/xml_tree.hpp> #include <mapnik/xml_tree.hpp>
#include <mapnik/xml_attribute_cast.hpp> #include <mapnik/xml_attribute_cast.hpp>
#include <mapnik/util/conversions.hpp> #include <mapnik/util/conversions.hpp>
@ -32,6 +33,9 @@
#include <mapnik/text/text_properties.hpp> #include <mapnik/text/text_properties.hpp>
#include <mapnik/config_error.hpp> #include <mapnik/config_error.hpp>
#include <mapnik/raster_colorizer.hpp> #include <mapnik/raster_colorizer.hpp>
#include <mapnik/expression.hpp>
// stl // stl
#include <type_traits> #include <type_traits>
@ -96,12 +100,7 @@ struct name_trait< mapnik::enumeration<ENUM, MAX> >
xml_tree::xml_tree(std::string const& encoding) xml_tree::xml_tree(std::string const& encoding)
: node_(*this, "<root>"), : node_(*this, "<root>"),
file_(), file_(),
tr_(encoding), tr_(encoding)
color_grammar(),
expr_grammar(tr_),
path_expr_grammar(),
transform_expr_grammar(expr_grammar),
image_filters_grammar()
{ {
node_.set_processed(true); //root node is always processed node_.set_processed(true); //root node is always processed
} }