Handle text-margin, repeat-distance, and backward compatible minimum-distance in placement_finder. Update visual tests.

This commit is contained in:
Jordan Hollinger 2014-08-21 20:49:00 -04:00
parent c8c792277d
commit a28d3dd99c
7 changed files with 27 additions and 16 deletions

View file

@ -72,7 +72,7 @@ private:
// Adjusts user defined spacing to place an integer number of labels. // Adjusts user defined spacing to place an integer number of labels.
double get_spacing(double path_length, double layout_width) const; double get_spacing(double path_length, double layout_width) const;
// Checks for collision. // Checks for collision.
bool collision(box2d<double> const& box, const value_unicode_string &repeat_key = "") const; bool collision(box2d<double> const& box, const value_unicode_string &repeat_key, bool line_placement) const;
// Adds marker to glyph_positions and to collision detector. Returns false if there is a collision. // Adds marker to glyph_positions and to collision detector. Returns false if there is a collision.
bool add_marker(glyph_positions_ptr glyphs, pixel_position const& pos) const; bool add_marker(glyph_positions_ptr glyphs, pixel_position const& pos) const;
// Maps upright==auto, left_only and right_only to left,right to simplify processing. // Maps upright==auto, left_only and right_only to left,right to simplify processing.

View file

@ -121,7 +121,7 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
bbox.re_center(layout_center.x, layout_center.y); bbox.re_center(layout_center.x, layout_center.y);
/* For point placements it is faster to just check the bounding box. */ /* For point placements it is faster to just check the bounding box. */
if (collision(bbox, layouts_.text())) return false; if (collision(bbox, layouts_.text(), false)) return false;
if (layout.num_lines()) bboxes.push_back(std::move(bbox)); if (layout.num_lines()) bboxes.push_back(std::move(bbox));
@ -244,7 +244,7 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
cluster_offset.y -= rot.sin * glyph.advance(); cluster_offset.y -= rot.sin * glyph.advance();
box2d<double> bbox = get_bbox(layout, glyph, pos, rot); box2d<double> bbox = get_bbox(layout, glyph, pos, rot);
if (collision(bbox, layouts_.text())) return false; if (collision(bbox, layouts_.text(), true)) return false;
bboxes.push_back(std::move(bbox)); bboxes.push_back(std::move(bbox));
glyphs->push_back(glyph, pos, rot); glyphs->push_back(glyph, pos, rot);
} }
@ -311,8 +311,19 @@ double placement_finder::get_spacing(double path_length, double layout_width) co
return path_length / num_labels; return path_length / num_labels;
} }
bool placement_finder::collision(const box2d<double> &box, const value_unicode_string &repeat_key) const bool placement_finder::collision(const box2d<double> &box, const value_unicode_string &repeat_key, bool line_placement) const
{ {
double text_margin, repeat_distance;
if (line_placement)
{
text_margin = info_.properties.text_margin * scale_factor_;
repeat_distance = (info_.properties.repeat_distance != 0 ? info_.properties.repeat_distance : info_.properties.minimum_distance) * scale_factor_;
}
else
{
text_margin = (info_.properties.text_margin != 0 ? info_.properties.text_margin : info_.properties.minimum_distance) * scale_factor_;
repeat_distance = info_.properties.repeat_distance * scale_factor_;
}
return !detector_.extent().intersects(box) return !detector_.extent().intersects(box)
|| ||
(info_.properties.avoid_edges && !extent_.contains(box)) (info_.properties.avoid_edges && !extent_.contains(box))
@ -321,10 +332,9 @@ bool placement_finder::collision(const box2d<double> &box, const value_unicode_s
!extent_.contains(box + (scale_factor_ * info_.properties.minimum_padding))) !extent_.contains(box + (scale_factor_ * info_.properties.minimum_padding)))
|| ||
(!info_.properties.allow_overlap && (!info_.properties.allow_overlap &&
((repeat_key.length() == 0 && !detector_.has_placement(box, info_.properties.text_margin * scale_factor_)) ((repeat_key.length() == 0 && !detector_.has_placement(box, text_margin))
|| ||
(repeat_key.length() > 0 && !detector_.has_placement(box, info_.properties.text_margin * scale_factor_, (repeat_key.length() > 0 && !detector_.has_placement(box, text_margin, repeat_key, repeat_distance))));
repeat_key, info_.properties.repeat_distance * scale_factor_))));
} }
void placement_finder::set_marker(marker_info_ptr m, box2d<double> box, bool marker_unlocked, pixel_position const& marker_displacement) void placement_finder::set_marker(marker_info_ptr m, box2d<double> box, bool marker_unlocked, pixel_position const& marker_displacement)
@ -343,7 +353,7 @@ bool placement_finder::add_marker(glyph_positions_ptr glyphs, pixel_position con
box2d<double> bbox = marker_box_; box2d<double> bbox = marker_box_;
bbox.move(real_pos.x, real_pos.y); bbox.move(real_pos.x, real_pos.y);
glyphs->set_marker(marker_, real_pos); glyphs->set_marker(marker_, real_pos);
if (collision(bbox, layouts_.text())) return false; if (collision(bbox, layouts_.text(), false)) return false;
detector_.insert(bbox); detector_.insert(bbox);
return true; return true;
} }

View file

@ -64,6 +64,7 @@ void text_symbolizer_properties::evaluate_text_properties(feature_impl const& fe
label_spacing = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.label_spacing); label_spacing = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.label_spacing);
label_position_tolerance = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.label_position_tolerance); label_position_tolerance = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.label_position_tolerance);
avoid_edges = util::apply_visitor(extract_value<value_bool>(feature,attrs), expressions.avoid_edges); avoid_edges = util::apply_visitor(extract_value<value_bool>(feature,attrs), expressions.avoid_edges);
text_margin = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.text_margin);
repeat_distance = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.repeat_distance); repeat_distance = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.repeat_distance);
minimum_distance = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.minimum_distance); minimum_distance = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.minimum_distance);
minimum_padding = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.minimum_padding); minimum_padding = util::apply_visitor(extract_value<value_double>(feature,attrs), expressions.minimum_padding);

View file

@ -18,14 +18,14 @@
<Style name="shield"> <Style name="shield">
<Rule> <Rule>
<Filter>[type] = 'motorway'</Filter> <Filter>[type] = 'motorway'</Filter>
<ShieldSymbolizer minimum-distance="0" spacing="120" placement="line" face-name="DejaVu Sans Book" size="10" fill="white" file="../../data/svg/rect.svg" transform="scale(0.75)">[ref]</ShieldSymbolizer> <ShieldSymbolizer text-margin="0" spacing="120" placement="line" face-name="DejaVu Sans Book" size="10" fill="white" file="../../data/svg/rect.svg" transform="scale(0.75)">[ref]</ShieldSymbolizer>
</Rule> </Rule>
</Style> </Style>
<Style name="text"> <Style name="text">
<Rule> <Rule>
<Filter>[type] != 'poi'</Filter> <Filter>[type] != 'poi'</Filter>
<TextSymbolizer minimum-distance="0" spacing="70" placement="line" face-name="DejaVu Sans Book" size="12">[name]</TextSymbolizer> <TextSymbolizer text-margin="0" spacing="70" placement="line" face-name="DejaVu Sans Book" size="12">[name]</TextSymbolizer>
</Rule> </Rule>
</Style> </Style>

View file

@ -18,14 +18,14 @@
<Style name="shield"> <Style name="shield">
<Rule> <Rule>
<Filter>[type] = 'motorway'</Filter> <Filter>[type] = 'motorway'</Filter>
<ShieldSymbolizer minimum-distance="60" spacing="120" placement="line" face-name="DejaVu Sans Book" size="10" fill="white" file="../../data/svg/rect.svg" transform="scale(0.75)">[ref]</ShieldSymbolizer> <ShieldSymbolizer text-margin="60" spacing="120" placement="line" face-name="DejaVu Sans Book" size="10" fill="white" file="../../data/svg/rect.svg" transform="scale(0.75)">[ref]</ShieldSymbolizer>
</Rule> </Rule>
</Style> </Style>
<Style name="text"> <Style name="text">
<Rule> <Rule>
<Filter>[type] != 'poi'</Filter> <Filter>[type] != 'poi'</Filter>
<TextSymbolizer minimum-distance="50" spacing="70" placement="line" face-name="DejaVu Sans Book" size="12">[name]</TextSymbolizer> <TextSymbolizer text-margin="50" spacing="70" placement="line" face-name="DejaVu Sans Book" size="12">[name]</TextSymbolizer>
</Rule> </Rule>
</Style> </Style>

View file

@ -18,14 +18,14 @@
<Style name="shield"> <Style name="shield">
<Rule> <Rule>
<Filter>[type] = 'motorway'</Filter> <Filter>[type] = 'motorway'</Filter>
<ShieldSymbolizer minimum-distance="0" repeat-distance="60" spacing="120" placement="line" face-name="DejaVu Sans Book" size="10" fill="white" file="../../data/svg/rect.svg" transform="scale(0.75)">[ref]</ShieldSymbolizer> <ShieldSymbolizer text-margin="0" repeat-distance="60" spacing="120" placement="line" face-name="DejaVu Sans Book" size="10" fill="white" file="../../data/svg/rect.svg" transform="scale(0.75)">[ref]</ShieldSymbolizer>
</Rule> </Rule>
</Style> </Style>
<Style name="text"> <Style name="text">
<Rule> <Rule>
<Filter>[type] != 'poi'</Filter> <Filter>[type] != 'poi'</Filter>
<TextSymbolizer minimum-distance="0" repeat-distance="40" spacing="70" placement="line" face-name="DejaVu Sans Book" size="12">[name]</TextSymbolizer> <TextSymbolizer text-margin="0" repeat-distance="40" spacing="70" placement="line" face-name="DejaVu Sans Book" size="12">[name]</TextSymbolizer>
</Rule> </Rule>
</Style> </Style>

View file

@ -18,14 +18,14 @@
<Style name="shield"> <Style name="shield">
<Rule> <Rule>
<Filter>[type] = 'motorway'</Filter> <Filter>[type] = 'motorway'</Filter>
<ShieldSymbolizer minimum-distance="10" repeat-distance="60" spacing="120" placement="line" face-name="DejaVu Sans Book" size="10" fill="white" file="../../data/svg/rect.svg" transform="scale(0.75)">[ref]</ShieldSymbolizer> <ShieldSymbolizer text-margin="10" repeat-distance="60" spacing="120" placement="line" face-name="DejaVu Sans Book" size="10" fill="white" file="../../data/svg/rect.svg" transform="scale(0.75)">[ref]</ShieldSymbolizer>
</Rule> </Rule>
</Style> </Style>
<Style name="text"> <Style name="text">
<Rule> <Rule>
<Filter>[type] != 'poi'</Filter> <Filter>[type] != 'poi'</Filter>
<TextSymbolizer minimum-distance="3" repeat-distance="40" spacing="70" placement="line" face-name="DejaVu Sans Book" size="12">[name]</TextSymbolizer> <TextSymbolizer text-margin="3" repeat-distance="40" spacing="70" placement="line" face-name="DejaVu Sans Book" size="12">[name]</TextSymbolizer>
</Rule> </Rule>
</Style> </Style>