add option to collect the total extent of all placement bboxs to enable passing along to metawriters - modified patch from kevin.kreaiser - closes #755

This commit is contained in:
Dane Springmeyer 2011-04-30 00:06:27 +00:00
parent 6df1dd31dd
commit 157d52e38f
4 changed files with 32 additions and 18 deletions

View file

@ -76,6 +76,8 @@ struct placement : boost::noncopyable
bool allow_overlap; bool allow_overlap;
std::pair<double, double> dimensions; std::pair<double, double> dimensions;
int text_size; int text_size;
bool collect_extents;
box2d<double> extents;
}; };

View file

@ -88,6 +88,8 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
string_info info(text); string_info info(text);
faces->get_string_info(info); faces->get_string_info(info);
metawriter_with_properties writer = sym.get_metawriter();
unsigned num_geom = feature.num_geometries(); unsigned num_geom = feature.num_geometries();
for (unsigned i=0; i<num_geom; ++i) for (unsigned i=0; i<num_geom; ++i)
{ {
@ -97,6 +99,9 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
{ {
placement text_placement(info, sym, placement_options, scale_factor_); placement text_placement(info, sym, placement_options, scale_factor_);
text_placement.avoid_edges = sym.get_avoid_edges(); text_placement.avoid_edges = sym.get_avoid_edges();
if (writer.first)
text_placement.collect_extents =true; // needed for inmem metawriter
if (sym.get_label_placement() == POINT_PLACEMENT || if (sym.get_label_placement() == POINT_PLACEMENT ||
sym.get_label_placement() == INTERIOR_PLACEMENT) sym.get_label_placement() == INTERIOR_PLACEMENT)
{ {
@ -121,7 +126,6 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
angle, sym.get_vertical_alignment(),sym.get_line_spacing(), angle, sym.get_vertical_alignment(),sym.get_line_spacing(),
sym.get_character_spacing(),sym.get_horizontal_alignment(), sym.get_character_spacing(),sym.get_horizontal_alignment(),
sym.get_justify_alignment()); sym.get_justify_alignment());
finder.update_detector(text_placement); finder.update_detector(text_placement);
} }
else if ( geom.num_points() > 1 && sym.get_label_placement() == LINE_PLACEMENT) else if ( geom.num_points() > 1 && sym.get_label_placement() == LINE_PLACEMENT)
@ -141,7 +145,6 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
ren.render(x,y); ren.render(x,y);
} }
metawriter_with_properties writer = sym.get_metawriter();
if (writer.first) writer.first->add_text(text_placement, faces, feature, t_, writer.second); if (writer.first) writer.first->add_text(text_placement, faces, feature, t_, writer.second);
} }
} }

View file

@ -79,20 +79,10 @@ metawriter_inmem::add_text(placement const& p,
Feature const& feature, Feature const& feature,
CoordTransform const& /*t*/, CoordTransform const& /*t*/,
metawriter_properties const& properties) { metawriter_properties const& properties) {
// there's more than one bbox for the text (one for each char), so keeping it if (p.extents.valid()) {
// simple for the moment and merging them all together...
if (p.envelopes.size() > 0) {
// stupid queue - doesn't expose begin() and end(), so forced to iterate by
// taking a copy...
std::queue<box2d<double> > env_copy = p.envelopes;
meta_instance inst; meta_instance inst;
box2d<double> box = env_copy.front();
while (env_copy.size() > 1) {
env_copy.pop();
box.expand_to_include(env_copy.front());
}
inst.properties = intersect_properties(feature, properties); inst.properties = intersect_properties(feature, properties);
inst.box = box; inst.box = p.extents;
instances_.push_back(inst); instances_.push_back(inst);
} }
} }

View file

@ -72,7 +72,9 @@ placement::placement(string_info & info_,
has_dimensions(has_dimensions_), has_dimensions(has_dimensions_),
allow_overlap(false), allow_overlap(false),
dimensions(std::make_pair(w,h)), dimensions(std::make_pair(w,h)),
text_size(placement_options->text_size) text_size(placement_options->text_size),
collect_extents(false),
extents()
{} {}
placement::placement(string_info & info_, placement::placement(string_info & info_,
@ -97,7 +99,9 @@ placement::placement(string_info & info_,
has_dimensions(false), has_dimensions(false),
allow_overlap(sym.get_allow_overlap()), allow_overlap(sym.get_allow_overlap()),
dimensions(), dimensions(),
text_size(placement_options->text_size) text_size(placement_options->text_size),
collect_extents(false),
extents()
{} {}
@ -960,11 +964,27 @@ void placement_finder<DetectorT>::find_line_circle_intersection(
template <typename DetectorT> template <typename DetectorT>
void placement_finder<DetectorT>::update_detector(placement & p) void placement_finder<DetectorT>::update_detector(placement & p)
{ {
bool first = true;
// add the bboxes to the detector and remove from the placement
while (!p.envelopes.empty()) while (!p.envelopes.empty())
{ {
box2d<double> e = p.envelopes.front(); box2d<double> e = p.envelopes.front();
detector_.insert(e, p.info.get_string()); detector_.insert(e, p.info.get_string());
p.envelopes.pop(); p.envelopes.pop();
if (p.collect_extents)
{
if(first)
{
first = false;
p.extents = e;
}
else
{
p.extents.expand_to_include(e);
}
}
} }
} }
@ -974,7 +994,6 @@ void placement_finder<DetectorT>::clear()
detector_.clear(); detector_.clear();
} }
typedef coord_transform2<CoordTransform,geometry_type> PathType; typedef coord_transform2<CoordTransform,geometry_type> PathType;
typedef label_collision_detector4 DetectorType; typedef label_collision_detector4 DetectorType;