diff --git a/include/mapnik/placement_finder.hpp b/include/mapnik/placement_finder.hpp index 76b1da5a7..cd97579cc 100644 --- a/include/mapnik/placement_finder.hpp +++ b/include/mapnik/placement_finder.hpp @@ -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 path_type; + struct placement + { + typedef coord_transform2 path_type; + + //For shields + placement(string_info *info_, + CoordTransform *ctrans_, + const proj_transform *proj_trans_, + geometry_ptr geom_, + std::pair 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 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 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 > envelopes; + + //output + std::vector placements; - geometry_ptr geom; - label_placement_e label_placement; - std::pair dimensions; + // caching output + placement_element current_placement; + + //helpers + std::pair 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 > envelopes; - - //output - std::vector 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 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 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 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 dimensions_; - label_collision_detector3 detector_; - }; + Envelope dimensions_; + label_collision_detector3 detector_; + }; } diff --git a/src/agg_renderer.cpp b/src/agg_renderer.cpp index 00c44e7a8..cb7480c10 100644 --- a/src/agg_renderer.cpp +++ b/src/agg_renderer.cpp @@ -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 dim = ren.prepare_glyphs(&text_placement.placements[ii].path); - - Envelope text_box(x + dim.minx() ,y - dim.maxy(), x + dim.maxx(),y - dim.miny()); + + //Envelope 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); } } diff --git a/src/load_map.cpp b/src/load_map.cpp index a80ccdb31..60e9f5e34 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -187,6 +187,12 @@ namespace mapnik std::string placement_str = sym.second.get(".placement","point"); + // displacement + + int dx = sym.second.get(".dx",0); + int dy = sym.second.get(".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") { diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index dd448388f..853fb04fc 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -32,6 +32,7 @@ #include #include #include +#include //mapnik #include @@ -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 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 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 e, unsigned buffer) - : dimensions_(e), detector_(Envelope(e.minx() - buffer, e.miny() - buffer, e.maxx() + buffer, e.maxy() + buffer)) + : dimensions_(e), + detector_(Envelope(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 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)) diff --git a/src/text_symbolizer.cpp b/src/text_symbolizer.cpp index 015aa44cc..9dacc6760 100644 --- a/src/text_symbolizer.cpp +++ b/src/text_symbolizer.cpp @@ -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_; }