convert remaining text properties to expressions

This commit is contained in:
artemp 2014-07-29 14:43:26 +01:00
parent 0c5c01d9a3
commit 08c3dd1f88
8 changed files with 106 additions and 64 deletions

View file

@ -24,6 +24,7 @@
#define MAPNIK_EVALUATE_GLOBAL_ATTRIBUTES_HPP #define MAPNIK_EVALUATE_GLOBAL_ATTRIBUTES_HPP
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
#include <mapnik/rule.hpp>
#include <mapnik/feature_type_style.hpp> #include <mapnik/feature_type_style.hpp>
#include <mapnik/symbolizer.hpp> #include <mapnik/symbolizer.hpp>
#include <mapnik/attribute.hpp> #include <mapnik/attribute.hpp>

View file

@ -146,7 +146,8 @@ enum class property_types : std::uint8_t
target_text_transform, target_text_transform,
target_horizontal_alignment, target_horizontal_alignment,
target_justify_alignment, target_justify_alignment,
target_vertical_alignment target_vertical_alignment,
target_upright
}; };
inline bool operator==(symbolizer_base const& lhs, symbolizer_base const& rhs) inline bool operator==(symbolizer_base const& lhs, symbolizer_base const& rhs)

View file

@ -172,17 +172,17 @@ enum justify_alignment_enum
DEFINE_ENUM(justify_alignment_e, justify_alignment_enum); DEFINE_ENUM(justify_alignment_e, justify_alignment_enum);
enum text_upright enum text_upright_enum
{ {
UPRIGHT_AUTO, UPRIGHT_AUTO,
UPRIGHT_LEFT, UPRIGHT_LEFT,
UPRIGHT_RIGHT, UPRIGHT_RIGHT,
UPRIGHT_LEFT_ONLY, UPRIGHT_LEFT_ONLY,
UPRIGHT_RIGHT_ONLY, UPRIGHT_RIGHT_ONLY,
text_upright_MAX text_upright_enum_MAX
}; };
DEFINE_ENUM(text_upright_e, text_upright); DEFINE_ENUM(text_upright_e, text_upright_enum);
} }

View file

@ -72,6 +72,7 @@ enum class keys : std::uint8_t
simplify_tolerance, simplify_tolerance,
halo_rasterizer, halo_rasterizer,
text_placements_, text_placements_,
label_placement,
markers_placement_type, markers_placement_type,
markers_multipolicy, markers_multipolicy,
point_placement_type, point_placement_type,
@ -88,6 +89,7 @@ enum class keys : std::uint8_t
horizontal_alignment, horizontal_alignment,
justify_alignment, justify_alignment,
vertical_alignment, vertical_alignment,
upright,
MAX_SYMBOLIZER_KEY MAX_SYMBOLIZER_KEY
}; };

View file

@ -122,7 +122,21 @@ struct MAPNIK_DECL text_layout_properties
class text_layout; class text_layout;
struct text_properties_expressions : symbolizer_base {}; struct text_properties_expressions
{
symbolizer_base::value_type label_placement = enumeration_wrapper(POINT_PLACEMENT);
symbolizer_base::value_type label_spacing = 0.0;
symbolizer_base::value_type label_position_tolerance = 0.0;
symbolizer_base::value_type avoid_edges = false;
symbolizer_base::value_type minimum_distance = 0.0;
symbolizer_base::value_type minimum_padding = 0.0;
symbolizer_base::value_type minimum_path_length = 0.0;
symbolizer_base::value_type max_char_angle_delta = 22.5;
symbolizer_base::value_type force_odd_labels = false;
symbolizer_base::value_type allow_overlap = false;
symbolizer_base::value_type largest_bbox_only = true;
symbolizer_base::value_type upright = enumeration_wrapper(UPRIGHT_AUTO);
};
// Contains all text symbolizer properties which are not directly related to text formatting and layout. // Contains all text symbolizer properties which are not directly related to text formatting and layout.
struct MAPNIK_DECL text_symbolizer_properties struct MAPNIK_DECL text_symbolizer_properties
@ -138,7 +152,8 @@ struct MAPNIK_DECL text_symbolizer_properties
// Takes a feature and produces formated text as output. // Takes a feature and produces formated text as output.
// The output object has to be created by the caller and passed in for thread safety. // The output object has to be created by the caller and passed in for thread safety.
void process(text_layout &output, feature_impl const& feature, attributes const& vars) const; void process(text_layout &output, feature_impl const& feature, attributes const& vars);
void evaluate_text_properties(feature_impl const& feature, attributes const& attrs);
// Automatically create processing instructions for a single expression. // Automatically create processing instructions for a single expression.
void set_old_style_expression(expression_ptr expr); void set_old_style_expression(expression_ptr expr);
// Sets new format tree. // Sets new format tree.

View file

@ -83,11 +83,14 @@ static const property_meta_type key_meta[to_integral(keys::MAX_SYMBOLIZER_KEY)]
property_meta_type{ "halo-rasterizer", enumeration_wrapper(HALO_RASTERIZER_FULL), property_meta_type{ "halo-rasterizer", enumeration_wrapper(HALO_RASTERIZER_FULL),
[](enumeration_wrapper e) { return enumeration<halo_rasterizer_enum,halo_rasterizer_enum_MAX>(halo_rasterizer_enum(e.value)).as_string();}, property_types::target_halo_rasterizer }, [](enumeration_wrapper e) { return enumeration<halo_rasterizer_enum,halo_rasterizer_enum_MAX>(halo_rasterizer_enum(e.value)).as_string();}, property_types::target_halo_rasterizer },
property_meta_type{ "text-placements", false, nullptr, property_types::target_double }, property_meta_type{ "text-placements", false, nullptr, property_types::target_double },
property_meta_type{ "placement", enumeration_wrapper(MARKER_POINT_PLACEMENT), property_meta_type{ "placement", enumeration_wrapper(POINT_PLACEMENT),
[](enumeration_wrapper e) { return enumeration<marker_placement_enum,marker_placement_enum_MAX>(marker_placement_enum(e.value)).as_string();}, property_types::target_markers_placement }, // FIXME - rename to "markers-placement-type" [](enumeration_wrapper e)
{ return enumeration<label_placement_enum,label_placement_enum_MAX>(label_placement_enum(e.value)).as_string();}, property_types::target_placement },
property_meta_type{ "placement", enumeration_wrapper(MARKER_POINT_PLACEMENT), // FIXME - change property name
[](enumeration_wrapper e) { return enumeration<marker_placement_enum,marker_placement_enum_MAX>(marker_placement_enum(e.value)).as_string();}, property_types::target_markers_placement },
property_meta_type{ "multi-policy", enumeration_wrapper(MARKER_EACH_MULTI), property_meta_type{ "multi-policy", enumeration_wrapper(MARKER_EACH_MULTI),
[](enumeration_wrapper e) { return enumeration<marker_multi_policy_enum,marker_multi_policy_enum_MAX>(marker_multi_policy_enum(e.value)).as_string();}, property_types::target_markers_multipolicy }, [](enumeration_wrapper e) { return enumeration<marker_multi_policy_enum,marker_multi_policy_enum_MAX>(marker_multi_policy_enum(e.value)).as_string();}, property_types::target_markers_multipolicy },
property_meta_type{ "placement", enumeration_wrapper(CENTROID_POINT_PLACEMENT), property_meta_type{ "placement", enumeration_wrapper(CENTROID_POINT_PLACEMENT), // FIXME - change property name
[](enumeration_wrapper e) { return enumeration<point_placement_enum,point_placement_enum_MAX>(point_placement_enum(e.value)).as_string();}, property_types::target_double }, [](enumeration_wrapper e) { return enumeration<point_placement_enum,point_placement_enum_MAX>(point_placement_enum(e.value)).as_string();}, property_types::target_double },
property_meta_type{ "colorizer", nullptr, nullptr, property_types::target_colorizer}, property_meta_type{ "colorizer", nullptr, nullptr, property_types::target_colorizer},
property_meta_type{ "halo-transform", false, nullptr, property_types::target_transform }, property_meta_type{ "halo-transform", false, nullptr, property_types::target_transform },
@ -109,7 +112,10 @@ static const property_meta_type key_meta[to_integral(keys::MAX_SYMBOLIZER_KEY)]
property_types::target_justify_alignment}, property_types::target_justify_alignment},
property_meta_type{ "vertical-alignment", enumeration_wrapper(V_TOP), [](enumeration_wrapper e) property_meta_type{ "vertical-alignment", enumeration_wrapper(V_TOP), [](enumeration_wrapper e)
{return enumeration<vertical_alignment_enum,vertical_alignment_enum_MAX>(vertical_alignment_enum(e.value)).as_string();}, {return enumeration<vertical_alignment_enum,vertical_alignment_enum_MAX>(vertical_alignment_enum(e.value)).as_string();},
property_types::target_vertical_alignment} property_types::target_vertical_alignment},
property_meta_type{ "upright", enumeration_wrapper(UPRIGHT_AUTO), [](enumeration_wrapper e)
{return enumeration<text_upright_enum,text_upright_enum_MAX>(text_upright_enum(e.value)).as_string();},
property_types::target_upright}
}; };

View file

@ -58,6 +58,7 @@ base_symbolizer_helper::base_symbolizer_helper(
clipped_(get<bool>(sym_, keys::clip, feature_, vars_, false)), clipped_(get<bool>(sym_, keys::clip, feature_, vars_, false)),
placement_(get<text_placements_ptr>(sym_, keys::text_placements_)->get_placement_info(scale_factor)) placement_(get<text_placements_ptr>(sym_, keys::text_placements_)->get_placement_info(scale_factor))
{ {
placement_->properties.evaluate_text_properties(feature_, vars_);
initialize_geometries(); initialize_geometries();
if (!geometries_to_process_.size()) return; // FIXME - bad practise if (!geometries_to_process_.size()) return; // FIXME - bad practise
initialize_points(); initialize_points();

View file

@ -53,14 +53,33 @@ text_symbolizer_properties::text_symbolizer_properties()
largest_bbox_only(true), largest_bbox_only(true),
upright(UPRIGHT_AUTO), upright(UPRIGHT_AUTO),
layout_defaults(), layout_defaults(),
format_defaults(),//std::make_shared<format_defaults>()), format_defaults(),
tree_() {} tree_() {}
void text_symbolizer_properties::process(text_layout & output, feature_impl const& feature, attributes const& attrs) const
void text_symbolizer_properties::evaluate_text_properties(feature_impl const& feature, attributes const& attrs)
{
label_placement = boost::apply_visitor(extract_value<label_placement_enum>(feature,attrs), expressions.label_placement);
label_spacing = boost::apply_visitor(extract_value<value_double>(feature,attrs), expressions.label_spacing);
label_position_tolerance = boost::apply_visitor(extract_value<value_double>(feature,attrs), expressions.label_position_tolerance);
avoid_edges = boost::apply_visitor(extract_value<value_bool>(feature,attrs), expressions.avoid_edges);
minimum_distance = boost::apply_visitor(extract_value<value_double>(feature,attrs), expressions.minimum_distance);
minimum_padding = boost::apply_visitor(extract_value<value_double>(feature,attrs), expressions.minimum_padding);
minimum_path_length = boost::apply_visitor(extract_value<value_double>(feature,attrs), expressions.minimum_path_length);
max_char_angle_delta = boost::apply_visitor(extract_value<value_double>(feature,attrs), expressions.max_char_angle_delta) * M_PI/180;
force_odd_labels = boost::apply_visitor(extract_value<value_bool>(feature,attrs), expressions.force_odd_labels);
allow_overlap = boost::apply_visitor(extract_value<value_bool>(feature,attrs), expressions.allow_overlap);
largest_bbox_only = boost::apply_visitor(extract_value<value_bool>(feature,attrs), expressions.largest_bbox_only);
upright = boost::apply_visitor(extract_value<text_upright_enum>(feature,attrs), expressions.upright);
}
void text_symbolizer_properties::process(text_layout & output, feature_impl const& feature, attributes const& attrs) //const
{ {
output.clear(); output.clear();
if (tree_) if (tree_)
{ {
evaluate_text_properties(feature, attrs);
//evaluate format properties //evaluate format properties
evaluated_format_properties_ptr format = std::make_shared<detail::evaluated_format_properties>(); evaluated_format_properties_ptr format = std::make_shared<detail::evaluated_format_properties>();
@ -97,33 +116,18 @@ formatting::node_ptr text_symbolizer_properties::format_tree() const
void text_symbolizer_properties::text_properties_from_xml(xml_node const& node) void text_symbolizer_properties::text_properties_from_xml(xml_node const& node)
{ {
optional<label_placement_e> placement_ = node.get_opt_attr<label_placement_e>("placement"); set_property_from_xml<label_placement_e>(expressions.label_placement, "placement", node);
if (placement_) label_placement = *placement_; set_property_from_xml<value_double>(expressions.label_spacing, "spacing", node);
optional<double> label_position_tolerance_ = node.get_opt_attr<double>("label-position-tolerance"); set_property_from_xml<value_double>(expressions.label_position_tolerance, "label-position-tolerance", node);
if (label_position_tolerance_) label_position_tolerance = *label_position_tolerance_; set_property_from_xml<value_double>(expressions.minimum_distance, "minimum-distance", node);
optional<double> spacing_ = node.get_opt_attr<double>("spacing"); set_property_from_xml<value_double>(expressions.minimum_padding, "minimum-padding", node);
if (spacing_) label_spacing = *spacing_; set_property_from_xml<value_double>(expressions.minimum_path_length, "minimum-path-length", node);
else { set_property_from_xml<boolean_type>(expressions.avoid_edges, "avoid-edges", node);
// https://github.com/mapnik/mapnik/issues/1427 set_property_from_xml<boolean_type>(expressions.allow_overlap, "allow-overlap", node);
spacing_ = node.get_opt_attr<double>("label-spacing"); set_property_from_xml<boolean_type>(expressions.largest_bbox_only, "largest-bbox-only", node);
if (spacing_) label_spacing = *spacing_; set_property_from_xml<boolean_type>(expressions.force_odd_labels, "force-odd-labels", node);
} set_property_from_xml<value_double>(expressions.max_char_angle_delta, "max-char-angle-delta", node);
optional<double> minimum_distance_ = node.get_opt_attr<double>("minimum-distance"); set_property_from_xml<text_upright_e>(expressions.upright, "upright", node);
if (minimum_distance_) minimum_distance = *minimum_distance_;
optional<double> min_padding_ = node.get_opt_attr<double>("minimum-padding");
if (min_padding_) minimum_padding = *min_padding_;
optional<double> min_path_length_ = node.get_opt_attr<double>("minimum-path-length");
if (min_path_length_) minimum_path_length = *min_path_length_;
optional<mapnik::boolean_type> avoid_edges_ = node.get_opt_attr<mapnik::boolean_type>("avoid-edges");
if (avoid_edges_) avoid_edges = *avoid_edges_;
optional<mapnik::boolean_type> allow_overlap_ = node.get_opt_attr<mapnik::boolean_type>("allow-overlap");
if (allow_overlap_) allow_overlap = *allow_overlap_;
optional<mapnik::boolean_type> largest_bbox_only_ = node.get_opt_attr<mapnik::boolean_type>("largest-bbox-only");
if (largest_bbox_only_) largest_bbox_only = *largest_bbox_only_;
optional<double> max_char_angle_delta_ = node.get_opt_attr<double>("max-char-angle-delta");
if (max_char_angle_delta_) max_char_angle_delta=(*max_char_angle_delta_)*(M_PI/180);
optional<text_upright_e> upright_ = node.get_opt_attr<text_upright_e>("upright");
if (upright_) upright = *upright_;
} }
void text_symbolizer_properties::from_xml(xml_node const& node, fontset_map const& fontsets) void text_symbolizer_properties::from_xml(xml_node const& node, fontset_map const& fontsets)
@ -146,49 +150,49 @@ void text_symbolizer_properties::to_xml(boost::property_tree::ptree &node,
bool explicit_defaults, bool explicit_defaults,
text_symbolizer_properties const& dfl) const text_symbolizer_properties const& dfl) const
{ {
if (label_placement != dfl.label_placement || explicit_defaults) if (!(expressions.label_placement == dfl.expressions.label_placement) || explicit_defaults)
{ {
set_attr(node, "placement", label_placement); serialize_property("placement", expressions.label_placement, node);
} }
if (label_position_tolerance != dfl.label_position_tolerance || explicit_defaults) if (!(expressions.label_position_tolerance == dfl.expressions.label_position_tolerance) || explicit_defaults)
{ {
set_attr(node, "label-position-tolerance", label_position_tolerance); serialize_property("label-position-tolerance", expressions.label_position_tolerance,node);
} }
if (label_spacing != dfl.label_spacing || explicit_defaults) if (!(expressions.label_spacing == dfl.expressions.label_spacing) || explicit_defaults)
{ {
set_attr(node, "spacing", label_spacing); serialize_property("spacing", expressions.label_spacing, node);
} }
if (minimum_distance != dfl.minimum_distance || explicit_defaults) if (!(expressions.minimum_distance == dfl.expressions.minimum_distance) || explicit_defaults)
{ {
set_attr(node, "minimum-distance", minimum_distance); serialize_property("minimum-distance", expressions.minimum_distance, node);
} }
if (minimum_padding != dfl.minimum_padding || explicit_defaults) if (!(expressions.minimum_padding == dfl.expressions.minimum_padding) || explicit_defaults)
{ {
set_attr(node, "minimum-padding", minimum_padding); serialize_property("minimum-padding", expressions.minimum_padding, node);
} }
if (minimum_path_length != dfl.minimum_path_length || explicit_defaults) if (!(expressions.minimum_path_length == dfl.expressions.minimum_path_length) || explicit_defaults)
{ {
set_attr(node, "minimum-path-length", minimum_path_length); serialize_property("minimum-path-length", expressions.minimum_path_length, node);
} }
if (avoid_edges != dfl.avoid_edges || explicit_defaults) if (!(expressions.avoid_edges == dfl.expressions.avoid_edges) || explicit_defaults)
{ {
set_attr(node, "avoid-edges", avoid_edges); serialize_property("avoid-edges", expressions.avoid_edges, node);
} }
if (allow_overlap != dfl.allow_overlap || explicit_defaults) if (!(expressions.allow_overlap == dfl.expressions.allow_overlap) || explicit_defaults)
{ {
set_attr(node, "allow-overlap", allow_overlap); serialize_property("allow-overlap", expressions.allow_overlap, node);
} }
if (largest_bbox_only != dfl.largest_bbox_only || explicit_defaults) if (!(expressions.largest_bbox_only == dfl.expressions.largest_bbox_only) || explicit_defaults)
{ {
set_attr(node, "largest-bbox-only", largest_bbox_only); serialize_property("largest-bbox-only", expressions.largest_bbox_only, node);
} }
if (max_char_angle_delta != dfl.max_char_angle_delta || explicit_defaults) if (!(expressions.max_char_angle_delta == dfl.expressions.max_char_angle_delta) || explicit_defaults)
{ {
set_attr(node, "max-char-angle-delta", max_char_angle_delta/(M_PI/180)); serialize_property("max-char-angle-delta", expressions.max_char_angle_delta, node);
} }
if (upright != dfl.upright || explicit_defaults) if (!(expressions.upright == dfl.expressions.upright) || explicit_defaults)
{ {
set_attr(node, "upright", upright); serialize_property("upright", expressions.upright, node);
} }
layout_defaults.to_xml(node, explicit_defaults, dfl.layout_defaults); layout_defaults.to_xml(node, explicit_defaults, dfl.layout_defaults);
@ -199,6 +203,19 @@ void text_symbolizer_properties::to_xml(boost::property_tree::ptree &node,
void text_symbolizer_properties::add_expressions(expression_set & output) const void text_symbolizer_properties::add_expressions(expression_set & output) const
{ {
if (is_expression(expressions.label_placement)) output.insert(boost::get<expression_ptr>(expressions.label_placement));
if (is_expression(expressions.label_spacing)) output.insert(boost::get<expression_ptr>(expressions.label_spacing));
if (is_expression(expressions.label_position_tolerance)) output.insert(boost::get<expression_ptr>(expressions.label_position_tolerance));
if (is_expression(expressions.avoid_edges)) output.insert(boost::get<expression_ptr>(expressions.avoid_edges));
if (is_expression(expressions.minimum_distance)) output.insert(boost::get<expression_ptr>(expressions.minimum_distance));
if (is_expression(expressions.minimum_padding)) output.insert(boost::get<expression_ptr>(expressions.minimum_padding));
if (is_expression(expressions.minimum_path_length)) output.insert(boost::get<expression_ptr>(expressions.minimum_path_length));
if (is_expression(expressions.max_char_angle_delta)) output.insert(boost::get<expression_ptr>(expressions.max_char_angle_delta));
if (is_expression(expressions.force_odd_labels)) output.insert(boost::get<expression_ptr>(expressions.force_odd_labels));
if (is_expression(expressions.allow_overlap)) output.insert(boost::get<expression_ptr>(expressions.allow_overlap));
if (is_expression(expressions.largest_bbox_only)) output.insert(boost::get<expression_ptr>(expressions.largest_bbox_only));
if (is_expression(expressions.upright)) output.insert(boost::get<expression_ptr>(expressions.upright));
layout_defaults.add_expressions(output); layout_defaults.add_expressions(output);
format_defaults.add_expressions(output); format_defaults.add_expressions(output);
if (tree_) tree_->add_expressions(output); if (tree_) tree_->add_expressions(output);
@ -220,8 +237,8 @@ void text_layout_properties::from_xml(xml_node const &node)
set_property_from_xml<double>(dy, "dy", node); set_property_from_xml<double>(dy, "dy", node);
set_property_from_xml<double>(text_ratio, "text-ratio", node); set_property_from_xml<double>(text_ratio, "text-ratio", node);
set_property_from_xml<double>(wrap_width, "wrap-width", node); set_property_from_xml<double>(wrap_width, "wrap-width", node);
set_property_from_xml<mapnik::boolean_type>(wrap_before, "wrap-before", node); set_property_from_xml<boolean_type>(wrap_before, "wrap-before", node);
set_property_from_xml<mapnik::boolean_type>(rotate_displacement, "rotate-displacement", node); set_property_from_xml<boolean_type>(rotate_displacement, "rotate-displacement", node);
set_property_from_xml<double>(orientation, "orientation", node); set_property_from_xml<double>(orientation, "orientation", node);
set_property_from_xml<vertical_alignment_e>(valign, "vertical-alignment", node); set_property_from_xml<vertical_alignment_e>(valign, "vertical-alignment", node);
set_property_from_xml<horizontal_alignment_e>(halign, "horizontal-alignment", node); set_property_from_xml<horizontal_alignment_e>(halign, "horizontal-alignment", node);
@ -260,7 +277,6 @@ void text_layout_properties::add_expressions(expression_set & output) const
} }
// text format properties // text format properties
format_properties::format_properties() format_properties::format_properties()
: face_name(), : face_name(),
fontset(), fontset(),