Restored support for the text displacement (point placement only at moment)

This commit is contained in:
Artem Pavlenko 2007-02-09 16:32:44 +00:00
parent 3edbb1f284
commit d024c86b1b
5 changed files with 152 additions and 90 deletions

View File

@ -37,88 +37,98 @@
namespace mapnik
{
struct placement_element
{
double starting_x;
double starting_y;
struct placement_element
{
double starting_x;
double starting_y;
text_path path;
};
text_path path;
};
struct placement
{
typedef coord_transform2<CoordTransform,geometry_type> path_type;
struct placement
{
typedef coord_transform2<CoordTransform,geometry_type> path_type;
//For shields
placement(string_info *info_,
CoordTransform *ctrans_,
const proj_transform *proj_trans_,
geometry_ptr geom_,
std::pair<double, double> dimensions_);
//For text
placement(string_info *info_,
CoordTransform *ctrans_,
const proj_transform *proj_trans_,
geometry_ptr geom_,
position const& displacement,
label_placement_e placement_);
~placement();
unsigned path_size() const;
string_info *info;
CoordTransform *ctrans;
const proj_transform *proj_trans;
//For shields
placement(string_info *info_, CoordTransform *ctrans_, const proj_transform *proj_trans_, geometry_ptr geom_, std::pair<double, double> dimensions_);
//For text
placement(string_info *info_, CoordTransform *ctrans_, const proj_transform *proj_trans_, geometry_ptr geom_, label_placement_e placement_);
~placement();
geometry_ptr geom;
position displacement_;
label_placement_e label_placement;
std::pair<double, double> dimensions;
unsigned path_size() const;
string_info *info;
bool has_dimensions;
CoordTransform *ctrans;
const proj_transform *proj_trans;
path_type shape_path;
std::queue< Envelope<double> > envelopes;
//output
std::vector<placement_element> placements;
geometry_ptr geom;
label_placement_e label_placement;
std::pair<double, double> dimensions;
// caching output
placement_element current_placement;
//helpers
std::pair<double, double> get_position_at_distance(double target_distance);
double get_total_distance();
void clear_envelopes();
double total_distance_; //cache for distance
int wrap_width;
int text_ratio;
bool has_dimensions;
path_type shape_path;
std::queue< Envelope<double> > envelopes;
//output
std::vector<placement_element> placements;
int label_spacing; // distance between repeated labels on a single geometry
unsigned label_position_tolerance; //distance the label can be moved on the line to fit, if 0 the default is used
bool force_odd_labels; //Always try render an odd amount of labels
// caching output
placement_element current_placement;
double max_char_angle_delta;
//helpers
std::pair<double, double> get_position_at_distance(double target_distance);
double get_total_distance();
void clear_envelopes();
double total_distance_; //cache for distance
int wrap_width;
int text_ratio;
int label_spacing; // distance between repeated labels on a single geometry
unsigned label_position_tolerance; //distance the label can be moved on the line to fit, if 0 the default is used
bool force_odd_labels; //Always try render an odd amount of labels
double max_char_angle_delta;
bool avoid_edges;
};
bool avoid_edges;
};
class placement_finder : boost::noncopyable
{
public:
//E is the dimensions of the map, buffer is the buffer used for collission detection.
placement_finder(Envelope<double> e, unsigned buffer);
class placement_finder : boost::noncopyable
{
public:
//e is the dimensions of the map, buffer is the buffer used for collission detection.
placement_finder(Envelope<double> e, unsigned buffer);
bool find_placements(placement *p);
bool find_placements(placement *p);
protected:
bool find_placement_follow(placement *p);
bool find_placement_horizontal(placement *p);
protected:
bool find_placement_follow(placement *p);
bool find_placement_horizontal(placement *p);
bool build_path_follow(placement *p, double target_distance);
bool build_path_horizontal(placement *p, double target_distance);
bool build_path_follow(placement *p, double target_distance);
bool build_path_horizontal(placement *p, double target_distance);
void update_detector(placement *p);
void update_detector(placement *p);
Envelope<double> dimensions_;
label_collision_detector3 detector_;
};
Envelope<double> dimensions_;
label_collision_detector3 detector_;
};
}

View File

@ -521,7 +521,10 @@ namespace mapnik
ren.get_string_info(text, &info);
placement text_placement(&info, &t_, &prj_trans, geom, sym.get_label_placement());
placement text_placement(&info, &t_, &prj_trans, geom,
sym.get_displacement(),
sym.get_label_placement());
text_placement.text_ratio = sym.get_text_ratio();
text_placement.wrap_width = sym.get_wrap_width();
text_placement.label_spacing = sym.get_label_spacing();
@ -530,25 +533,22 @@ namespace mapnik
text_placement.max_char_angle_delta = sym.get_max_char_angle_delta();
text_placement.avoid_edges = sym.get_avoid_edges();
bool found = finder_.find_placements(&text_placement);
if (!found) {
return;
}
if ( !finder_.find_placements(&text_placement)) return;
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
{
double x = text_placement.placements[ii].starting_x;
double y = text_placement.placements[ii].starting_y;
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii].path);
Envelope<double> text_box(x + dim.minx() ,y - dim.maxy(), x + dim.maxx(),y - dim.miny());
//Envelope<double> text_box(x + dim.minx() ,y - dim.maxy(), x + dim.maxx(),y - dim.miny());
if (sym.get_halo_radius() > 0)
{
text_box.width(text_box.width() + sym.get_halo_radius()*2);
text_box.height(text_box.height() + sym.get_halo_radius()*2);
}
//if (sym.get_halo_radius() > 0)
//{
// text_box.width(text_box.width() + sym.get_halo_radius()*2);
// text_box.height(text_box.height() + sym.get_halo_radius()*2);
//}
ren.render(x,y);
}
}

View File

@ -187,6 +187,12 @@ namespace mapnik
std::string placement_str =
sym.second.get<std::string>("<xmlattr>.placement","point");
// displacement
int dx = sym.second.get<int>("<xmlattr>.dx",0);
int dy = sym.second.get<int>("<xmlattr>.dy",0);
text_symbol.set_displacement(dx,dy);
if (placement_str == "line")
{
text_symbol.set_label_placement(line_placement);
@ -400,10 +406,6 @@ namespace mapnik
}
}
rule.append(poly_sym);
}
else if ( sym.first == "TextSymbolizer")
{
std::cout << sym.first << "\n";
}
else if ( sym.first == "RasterSymbolizer")
{

View File

@ -32,6 +32,7 @@
#include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/tuple/tuple.hpp>
//mapnik
#include <mapnik/geometry.hpp>
@ -45,14 +46,53 @@
namespace mapnik
{
//For shields
placement::placement(string_info *info_, CoordTransform *ctrans_, const proj_transform *proj_trans_, geometry_ptr geom_, std::pair<double, double> dimensions_)
: info(info_), ctrans(ctrans_), proj_trans(proj_trans_), geom(geom_), label_placement(point_placement), dimensions(dimensions_), has_dimensions(true), shape_path(*ctrans_, *geom_, *proj_trans_), total_distance_(-1.0), wrap_width(0), text_ratio(0), label_spacing(0), label_position_tolerance(0), force_odd_labels(false), max_char_angle_delta(0.0), avoid_edges(false)
placement::placement(string_info *info_,
CoordTransform *ctrans_,
const proj_transform *proj_trans_,
geometry_ptr geom_,
std::pair<double, double> dimensions_)
: info(info_),
ctrans(ctrans_),
proj_trans(proj_trans_),
geom(geom_),
displacement_(0,0),
label_placement(point_placement),
dimensions(dimensions_),
has_dimensions(true),
shape_path(*ctrans_, *geom_, *proj_trans_),
total_distance_(-1.0),
wrap_width(0),
text_ratio(0),
label_spacing(0),
label_position_tolerance(0),
force_odd_labels(false),
max_char_angle_delta(0.0), avoid_edges(false)
{
}
//For text
placement::placement(string_info *info_, CoordTransform *ctrans_, const proj_transform *proj_trans_, geometry_ptr geom_, label_placement_e placement_)
: info(info_), ctrans(ctrans_), proj_trans(proj_trans_), geom(geom_), label_placement(placement_), has_dimensions(false), shape_path(*ctrans_, *geom_, *proj_trans_), total_distance_(-1.0), wrap_width(0), text_ratio(0), label_spacing(0), label_position_tolerance(0), force_odd_labels(false), max_char_angle_delta(0.0), avoid_edges(false)
placement::placement(string_info *info_,
CoordTransform *ctrans_,
const proj_transform *proj_trans_,
geometry_ptr geom_,
position const& displacement,
label_placement_e placement_)
: info(info_),
ctrans(ctrans_),
proj_trans(proj_trans_),
geom(geom_),
displacement_(displacement),
label_placement(placement_),
has_dimensions(false),
shape_path(*ctrans_, *geom_, *proj_trans_),
total_distance_(-1.0),
wrap_width(0),
text_ratio(0),
label_spacing(0),
label_position_tolerance(0),
force_odd_labels(false),
max_char_angle_delta(0.0),
avoid_edges(false)
{
}
@ -143,7 +183,8 @@ namespace mapnik
placement_finder::placement_finder(Envelope<double> e, unsigned buffer)
: dimensions_(e), detector_(Envelope<double>(e.minx() - buffer, e.miny() - buffer, e.maxx() + buffer, e.maxy() + buffer))
: dimensions_(e),
detector_(Envelope<double>(e.minx() - buffer, e.miny() - buffer, e.maxx() + buffer, e.maxy() + buffer))
{
}
@ -574,6 +615,9 @@ namespace mapnik
double z=0;
p->proj_trans->backward(p->current_placement.starting_x, p->current_placement.starting_y, z);
p->ctrans->forward(&p->current_placement.starting_x, &p->current_placement.starting_y);
// apply displacement ( in pixels )
p->current_placement.starting_x += boost::tuples::get<0>(p->displacement_);
p->current_placement.starting_y += boost::tuples::get<1>(p->displacement_);
}
double line_height = 0;
@ -606,11 +650,17 @@ namespace mapnik
Envelope<double> e;
if (p->has_dimensions)
{
e.init(p->current_placement.starting_x - (p->dimensions.first/2.0), p->current_placement.starting_y - (p->dimensions.second/2.0), p->current_placement.starting_x + (p->dimensions.first/2.0), p->current_placement.starting_y + (p->dimensions.second/2.0));
e.init(p->current_placement.starting_x - (p->dimensions.first/2.0),
p->current_placement.starting_y - (p->dimensions.second/2.0),
p->current_placement.starting_x + (p->dimensions.first/2.0),
p->current_placement.starting_y + (p->dimensions.second/2.0));
}
else
{
e.init(p->current_placement.starting_x + x, p->current_placement.starting_y - y, p->current_placement.starting_x + x + ci.width, p->current_placement.starting_y - y - ci.height);
e.init(p->current_placement.starting_x + x,
p->current_placement.starting_y - y,
p->current_placement.starting_x + x + ci.width,
p->current_placement.starting_y - y - ci.height);
}
if (!detector_.has_placement(e))

View File

@ -213,7 +213,7 @@ namespace mapnik
displacement_ = boost::make_tuple(x,y);
}
position const& text_symbolizer::get_displacement() const
position const& text_symbolizer::get_displacement() const
{
return displacement_;
}