diff --git a/include/mapnik/rule.hpp b/include/mapnik/rule.hpp index eb5a02c7e..c4aa79209 100644 --- a/include/mapnik/rule.hpp +++ b/include/mapnik/rule.hpp @@ -39,6 +39,7 @@ #include // boost +#include #include #include #include @@ -125,6 +126,8 @@ typedef boost::variant symbolizer; + + class rule { public: @@ -138,6 +141,104 @@ private: expression_ptr filter_; bool else_filter_; bool also_filter_; + + struct deepcopy_symbolizer : public boost::static_visitor<> + { + + void operator () (markers_symbolizer & sym) const + { + copy_path_ptr(sym); + } + + void operator () (point_symbolizer & sym) const + { + copy_path_ptr(sym); + } + + void operator () (polygon_pattern_symbolizer & sym) const + { + copy_path_ptr(sym); + } + + void operator () (line_pattern_symbolizer & sym) const + { + copy_path_ptr(sym); + } + + void operator () (raster_symbolizer & sym) const + { + raster_colorizer_ptr old_colorizer = sym.get_colorizer(); + raster_colorizer_ptr new_colorizer = raster_colorizer_ptr(); + new_colorizer->set_stops(old_colorizer->get_stops()); + new_colorizer->set_default_mode(old_colorizer->get_default_mode()); + new_colorizer->set_default_color(old_colorizer->get_default_color()); + new_colorizer->set_epsilon(old_colorizer->get_epsilon()); + sym.set_colorizer(new_colorizer); + } + + void operator () (text_symbolizer & sym) const + { + copy_text_ptr(sym); + } + + void operator () (shield_symbolizer & sym) const + { + copy_path_ptr(sym); + copy_text_ptr(sym); + } + + void operator () (building_symbolizer & sym) const + { + copy_height_ptr(sym); + } + + + template void operator () (T &sym) const + { + boost::ignore_unused_variable_warning(sym); + } + + private: + template + void copy_path_ptr(T & sym) const + { + std::string path = path_processor_type::to_string(*sym.get_filename()); + sym.set_filename( parse_path(path) ); + } + + template + void copy_text_ptr(T & sym) const + { + std::string name = to_expression_string(*sym.get_name()); + sym.set_name( parse_expression(name) ); + + // FIXME - orientation doesn't appear to be initialized in constructor? + //std::string orientation = to_expression_string(*sym->get_orientation()); + //sym->set_orientation( parse_expression(orientation) ); + + float text_size = sym.get_text_size(); + position displace = sym.get_displacement(); + vertical_alignment_e valign = sym.get_vertical_alignment(); + horizontal_alignment_e halign = sym.get_horizontal_alignment(); + justify_alignment_e jalign = sym.get_justify_alignment(); + + text_placements_ptr placements = text_placements_ptr(boost::make_shared()); + sym.set_placement_options( placements ); + sym.set_text_size(text_size); + sym.set_displacement(displace); + sym.set_vertical_alignment(valign); + sym.set_horizontal_alignment(halign); + sym.set_justify_alignment(jalign); + } + + template + void copy_height_ptr(T & sym) const + { + std::string height_expr = to_expression_string(sym.height()); + sym.set_height(parse_expression(height_expr,"utf8")); + } + }; + public: rule() : name_(), @@ -169,48 +270,18 @@ public: also_filter_(rhs.also_filter_) { if (deep_copy) { - //std::string expr = to_expression_string(rhs.filter_); - //filter_ = parse_expression(expr,"utf8"); + + std::string expr = to_expression_string(rhs.filter_); + filter_ = parse_expression(expr,"utf8"); symbolizers::iterator it = syms_.begin(), end = syms_.end(); // FIXME - metawriter_ptr? - for(; it != end; ++it) { - - /*if (polygon_symbolizer *sym = boost::get(&(*it))) { - // no shared pointers - } else if (line_symbolizer *sym = boost::get(&(*it))) { - // no shared pointers - } else if (building_symbolizer *sym = boost::get(&(*it))) { - // no shared pointers - }*/ - - if (markers_symbolizer *sym = boost::get(&(*it))) { - copy_path_ptr(sym); - } else if (point_symbolizer *sym = boost::get(&(*it))) { - copy_path_ptr(sym); - } else if (polygon_pattern_symbolizer *sym = boost::get(&(*it))) { - copy_path_ptr(sym); - } else if (line_pattern_symbolizer *sym = boost::get(&(*it))) { - copy_path_ptr(sym); - } else if (raster_symbolizer *sym = boost::get(&(*it))) { - raster_colorizer_ptr old_colorizer = sym->get_colorizer(), - new_colorizer = raster_colorizer_ptr(); - - new_colorizer->set_stops( old_colorizer->get_stops()); - new_colorizer->set_default_mode( old_colorizer->get_default_mode() ); - new_colorizer->set_default_color( old_colorizer->get_default_color() ); - new_colorizer->set_epsilon( old_colorizer->get_epsilon() ); - - sym->set_colorizer(new_colorizer); - } else if (shield_symbolizer *sym = boost::get(&(*it))) { - copy_path_ptr(sym); - copy_text_ptr(sym); - } else if (text_symbolizer *sym = boost::get(&(*it))) { - copy_text_ptr(sym); - } + for(; it != end; ++it) + { + boost::apply_visitor(deepcopy_symbolizer(),*it); } } } @@ -340,40 +411,7 @@ private: filter_=rhs.filter_; else_filter_=rhs.else_filter_; also_filter_=rhs.also_filter_; - } - - template - void copy_path_ptr(T* sym) - { - std::string path = path_processor_type::to_string(*sym->get_filename()); - sym->set_filename( parse_path(path) ); - } - - template - void copy_text_ptr(T* sym) - { - std::string name = to_expression_string(*sym->get_name()); - sym->set_name( parse_expression(name) ); - - // FIXME - orientation doesn't appear to be initialized in constructor? - //std::string orientation = to_expression_string(*sym->get_orientation()); - //sym->set_orientation( parse_expression(orientation) ); - - float text_size = sym->get_text_size(); - position displace = sym->get_displacement(); - vertical_alignment_e valign = sym->get_vertical_alignment(); - horizontal_alignment_e halign = sym->get_horizontal_alignment(); - justify_alignment_e jalign = sym->get_justify_alignment(); - - text_placements_ptr placements = text_placements_ptr(boost::make_shared()); - sym->set_placement_options( placements ); - - sym->set_text_size(text_size); - sym->set_displacement(displace); - sym->set_vertical_alignment(valign); - sym->set_horizontal_alignment(halign); - sym->set_justify_alignment(jalign); - } + } }; }