Move next_position() to placement finder.

This commit is contained in:
Hermann Kraus 2012-07-28 01:43:11 +02:00
parent f6ad3243ef
commit 716dd1c79e
4 changed files with 44 additions and 61 deletions

View file

@ -25,7 +25,6 @@
//mapnik
#include <mapnik/text_symbolizer.hpp>
#include <mapnik/shield_symbolizer.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
@ -39,7 +38,6 @@
namespace mapnik {
/** Helper object that does all the TextSymbolizer placment finding
* work except actually rendering the object. */
template <typename FaceManagerT, typename DetectorT>
@ -75,7 +73,6 @@ protected:
Feature const& feature_;
proj_transform const& prj_trans_;
CoordTransform const& t_;
FaceManagerT & font_manager_;
DetectorT & detector_;
metawriter_with_properties writer_;
box2d<double> dims_;
@ -90,10 +87,6 @@ protected:
std::list<position> points_;
/** Point currently being processed. */
std::list<position>::iterator point_itr_;
/** Text rotation. */
double angle_;
/** Did last call to next_placement return true? */
bool placement_valid_;
/** Use point placement. Otherwise line placement is used. */
bool point_placement_;
/** Place text at points on a line instead of following the line (used for ShieldSymbolizer) .*/
@ -152,22 +145,17 @@ protected:
using text_symbolizer_helper<FaceManagerT, DetectorT>::geometries_to_process_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::placement_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::next_placement;
using text_symbolizer_helper<FaceManagerT, DetectorT>::geo_itr_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::point_itr_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::points_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::writer_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::font_manager_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::feature_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::t_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::detector_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::dims_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::prj_trans_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::placement_valid_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::point_placement_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::angle_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::finder_;
using text_symbolizer_helper<FaceManagerT, DetectorT>::layout_;
};
} //namespace
#endif // SYMBOLIZER_HELPERS_HPP

View file

@ -26,6 +26,9 @@
#include <mapnik/box2d.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/text/glyph_info.hpp>
#include <mapnik/text/layout.hpp>
#include <mapnik/text_placements/base.hpp>
#include <mapnik/expression_evaluator.hpp>
//stl
#include <vector>
@ -43,9 +46,6 @@ typedef label_collision_detector4 DetectorType;
class feature_impl;
typedef feature_impl Feature;
class text_layout;
typedef boost::shared_ptr<text_layout> text_layout_ptr;
struct glyph_position
{
glyph_position(glyph_info const& glyph, pixel_position const& pos, double angle)
@ -92,21 +92,26 @@ class placement_finder_ng : boost::noncopyable
public:
placement_finder_ng(Feature const& feature,
DetectorType & detector,
box2d<double> const& extent);
box2d<double> const& extent,
text_placement_info_ptr placement_info,
face_manager_freetype & font_manager);
/** Try to place a single label at the given point. */
glyph_positions_ptr find_point_placement(text_layout_ptr layout, double pos_x, double pos_y);
glyph_positions_ptr find_point_placement(double pos_x, double pos_y);
void apply_settings(text_symbolizer_properties const* properties);
bool next_position();
private:
Feature const& feature_;
DetectorType const& detector_;
box2d<double> const& extent_;
double angle_;
text_symbolizer_properties *properties_;
text_layout_ptr layout_;
text_layout layout_;
text_placement_info_ptr info_;
bool valid_;
};
typedef boost::shared_ptr<placement_finder_ng> placement_finder_ng_ptr;
}//ns mapnik
#endif // PLACEMENT_FINDER_NG_HPP

View file

@ -35,16 +35,12 @@ text_symbolizer_helper<FaceManagerT, DetectorT>::text_symbolizer_helper(const te
feature_(feature),
prj_trans_(prj_trans),
t_(t),
font_manager_(font_manager),
detector_(detector),
writer_(sym.get_metawriter()),
dims_(0, 0, width, height),
query_extent_(query_extent),
layout_(new text_layout(font_manager)),
angle_(0.0),
placement_valid_(false),
points_on_line_(false),
finder_(feature, detector, dims_)
finder_(feature, detector, dims_, placement_, font_manager)
{
initialize_geometries();
if (!geometries_to_process_.size()) return;
@ -56,7 +52,6 @@ text_symbolizer_helper<FaceManagerT, DetectorT>::text_symbolizer_helper(const te
template <typename FaceManagerT, typename DetectorT>
glyph_positions_ptr text_symbolizer_helper<FaceManagerT, DetectorT>::next()
{
if (!placement_valid_) return glyph_positions_ptr();
if (point_placement_)
return next_point_placement();
else
@ -252,35 +247,6 @@ void text_symbolizer_helper<FaceManagerT, DetectorT>::update_detector(glyph_posi
}
template <typename FaceManagerT, typename DetectorT>
bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_placement()
{
if (!placement_->next()) {
placement_valid_ = false;
return false;
}
// placement_->properties.process(*layout_, feature_);
// layout_->layout(placement_->properties.wrap_width, placement_->properties.text_ratio);
if (placement_->properties.orientation)
{
angle_ = boost::apply_visitor(
evaluate<Feature, value_type>(feature_),
*(placement_->properties.orientation)).to_double();
} else {
angle_ = 0.0;
}
finder_.apply_settings(&(placement_->properties));
#if 0
if (writer_.first) finder_->set_collect_extents(true);
#endif
placement_valid_ = true;
return true;
}
/*****************************************************************************/
@ -299,7 +265,7 @@ shield_symbolizer_helper<FaceManagerT, DetectorT>::shield_symbolizer_helper(cons
template <typename FaceManagerT, typename DetectorT>
bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next()
{
if (!placement_valid_ || !marker_) return false;
if (!marker_) return false;
if (point_placement_)
return next_point_placement();
else
@ -315,7 +281,7 @@ bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next_point_placement()
if (point_itr_ == points_.end())
{
//Just processed the last point. Try next placement.
if (!next_placement()) return false; //No more placements
if (!finder_.next_position()) return false; //No more placements
//Start again from begin of list
point_itr_ = points_.begin();
continue; //Reexecute size check

View file

@ -23,6 +23,7 @@
#include <mapnik/text/placement_finder_ng.hpp>
#include <mapnik/text/layout.hpp>
#include <mapnik/text_properties.hpp>
#include <mapnik/debug.hpp>
//boost
#include <boost/make_shared.hpp>
@ -30,12 +31,12 @@
namespace mapnik
{
placement_finder_ng::placement_finder_ng(Feature const& feature, DetectorType &detector, box2d<double> const& extent)
: feature_(feature), detector_(detector), extent_(extent)
placement_finder_ng::placement_finder_ng(Feature const& feature, DetectorType &detector, box2d<double> const& extent, text_placement_info_ptr placement_info, face_manager_freetype &font_manager)
: feature_(feature), detector_(detector), extent_(extent), layout_(font_manager), info_(placement_info), valid_(true)
{
}
glyph_positions_ptr placement_finder_ng::find_point_placement(text_layout_ptr layout, double pos_x, double pos_y)
glyph_positions_ptr placement_finder_ng::find_point_placement(double pos_x, double pos_y)
{
glyph_positions_ptr glyphs = boost::make_shared<glyph_positions>();
// glyphs->point_placement(pixel_position(pos_x, pos_y));
@ -44,10 +45,33 @@ glyph_positions_ptr placement_finder_ng::find_point_placement(text_layout_ptr la
return glyphs;
}
void placement_finder_ng::apply_settings(text_symbolizer_properties const* properties)
bool placement_finder_ng::next_position()
{
if (!valid_)
{
MAPNIK_LOG_WARN(placement_finder_ng) << "next_position() called while last call already returned false!\n";
return false;
}
if (!info_->next())
{
valid_ = false;
return false;
}
info_->properties.process(layout_, feature_);
layout_.layout(info_->properties.wrap_width, info_->properties.text_ratio);
if (info_->properties.orientation)
{
angle_ = boost::apply_visitor(
evaluate<Feature, value_type>(feature_),
*(info_->properties.orientation)).to_double();
} else {
angle_ = 0.0;
}
return true;
}
glyph_positions::glyph_positions()
: base_point_(), const_angle_(true)
{