mirror of
https://github.com/mapnik/mapnik.git
synced 2025-12-08 20:13:09 +00:00
Restored support for the text displacement (point placement only at moment)
This commit is contained in:
parent
3edbb1f284
commit
d024c86b1b
@ -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_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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")
|
||||
{
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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_;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user