From 157d52e38fb2c39d93c2a9dec3b68926d1506406 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Sat, 30 Apr 2011 00:06:27 +0000 Subject: [PATCH] add option to collect the total extent of all placement bboxs to enable passing along to metawriters - modified patch from kevin.kreaiser - closes #755 --- include/mapnik/placement_finder.hpp | 4 +++- src/agg/process_text_symbolizer.cpp | 7 +++++-- src/metawriter_inmem.cpp | 14 ++------------ src/placement_finder.cpp | 25 ++++++++++++++++++++++--- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/include/mapnik/placement_finder.hpp b/include/mapnik/placement_finder.hpp index 50925da4b..0c44bdd3d 100644 --- a/include/mapnik/placement_finder.hpp +++ b/include/mapnik/placement_finder.hpp @@ -76,6 +76,8 @@ struct placement : boost::noncopyable bool allow_overlap; std::pair dimensions; int text_size; + bool collect_extents; + box2d extents; }; @@ -101,7 +103,7 @@ public: void update_detector(placement & p); void clear(); - + private: ///Helpers for find_line_placement diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp index 42e398e85..62fb6e29a 100644 --- a/src/agg/process_text_symbolizer.cpp +++ b/src/agg/process_text_symbolizer.cpp @@ -88,6 +88,8 @@ void agg_renderer::process(text_symbolizer const& sym, string_info info(text); faces->get_string_info(info); + metawriter_with_properties writer = sym.get_metawriter(); + unsigned num_geom = feature.num_geometries(); for (unsigned i=0; i::process(text_symbolizer const& sym, { placement text_placement(info, sym, placement_options, scale_factor_); 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 || sym.get_label_placement() == INTERIOR_PLACEMENT) { @@ -121,7 +126,6 @@ void agg_renderer::process(text_symbolizer const& sym, angle, sym.get_vertical_alignment(),sym.get_line_spacing(), sym.get_character_spacing(),sym.get_horizontal_alignment(), sym.get_justify_alignment()); - finder.update_detector(text_placement); } else if ( geom.num_points() > 1 && sym.get_label_placement() == LINE_PLACEMENT) @@ -141,7 +145,6 @@ void agg_renderer::process(text_symbolizer const& sym, 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); } } diff --git a/src/metawriter_inmem.cpp b/src/metawriter_inmem.cpp index a65919846..926212fa9 100644 --- a/src/metawriter_inmem.cpp +++ b/src/metawriter_inmem.cpp @@ -79,20 +79,10 @@ metawriter_inmem::add_text(placement const& p, Feature const& feature, CoordTransform const& /*t*/, metawriter_properties const& properties) { - // there's more than one bbox for the text (one for each char), so keeping it - // 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 > env_copy = p.envelopes; + if (p.extents.valid()) { meta_instance inst; - box2d 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.box = box; + inst.box = p.extents; instances_.push_back(inst); } } diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index cecbf98a3..bd8ca518b 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -72,7 +72,9 @@ placement::placement(string_info & info_, has_dimensions(has_dimensions_), allow_overlap(false), 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_, @@ -97,7 +99,9 @@ placement::placement(string_info & info_, has_dimensions(false), allow_overlap(sym.get_allow_overlap()), dimensions(), - text_size(placement_options->text_size) + text_size(placement_options->text_size), + collect_extents(false), + extents() {} @@ -960,11 +964,27 @@ void placement_finder::find_line_circle_intersection( template void placement_finder::update_detector(placement & p) { + bool first = true; + + // add the bboxes to the detector and remove from the placement while (!p.envelopes.empty()) { box2d e = p.envelopes.front(); detector_.insert(e, p.info.get_string()); 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::clear() detector_.clear(); } - typedef coord_transform2 PathType; typedef label_collision_detector4 DetectorType;