From 9fe4a94c98febafc6ed49802e30f0f110246fe9d Mon Sep 17 00:00:00 2001 From: vspader Date: Mon, 2 Jul 2007 13:39:08 +0000 Subject: [PATCH] Added minimum_distance property to text symbolizers. This prevents the same label from appearing within N pixels (across features). Shield symbolizer is now a subclass of text symbolizer. Some small improvements to text rendering. Fixed up placement finder for horizontal placement. Cleaned up placement finder. --- bindings/python/mapnik_python.cpp | 4 +- bindings/python/mapnik_shield_symbolizer.cpp | 13 +- bindings/python/mapnik_text_symbolizer.cpp | 3 + include/mapnik/agg_renderer.hpp | 4 +- include/mapnik/font_engine_freetype.hpp | 6 +- include/mapnik/label_collision_detector.hpp | 71 ++++++ include/mapnik/placement_finder.hpp | 43 ++-- include/mapnik/shield_symbolizer.hpp | 51 ++--- include/mapnik/text_path.hpp | 13 +- include/mapnik/text_symbolizer.hpp | 6 +- src/agg_renderer.cpp | 47 ++-- src/placement_finder.cpp | 228 ++++++++----------- src/shield_symbolizer.cpp | 73 +----- src/text_symbolizer.cpp | 51 +++-- 14 files changed, 293 insertions(+), 320 deletions(-) diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index 90f3b38ff..c6d1ff429 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -49,8 +49,8 @@ void export_line_pattern_symbolizer(); void export_polygon_symbolizer(); void export_polygon_pattern_symbolizer(); void export_raster_symbolizer(); -void export_shield_symbolizer(); void export_text_symbolizer(); +void export_shield_symbolizer(); void export_font_engine(); void export_projection(); @@ -124,8 +124,8 @@ BOOST_PYTHON_MODULE(_mapnik) export_polygon_symbolizer(); export_polygon_pattern_symbolizer(); export_raster_symbolizer(); - export_shield_symbolizer(); export_text_symbolizer(); + export_shield_symbolizer(); export_font_engine(); export_projection(); export_coord(); diff --git a/bindings/python/mapnik_shield_symbolizer.cpp b/bindings/python/mapnik_shield_symbolizer.cpp index 4617192b8..da0a0c3a7 100644 --- a/bindings/python/mapnik_shield_symbolizer.cpp +++ b/bindings/python/mapnik_shield_symbolizer.cpp @@ -29,14 +29,11 @@ void export_shield_symbolizer() { using namespace boost::python; using mapnik::shield_symbolizer; - - class_("ShieldSymbolizer", - init<>("Default Shield Symbolizer - 4x4 black square")) - .def (init< std::string const&, std::string const&, unsigned, mapnik::Color const&, - std::string const&, std::string const&,unsigned,unsigned>("TODO")) - .add_property("avoid_edges", - &shield_symbolizer::get_avoid_edges, - &shield_symbolizer::set_avoid_edges) + using mapnik::text_symbolizer; + + class_< shield_symbolizer, bases >("ShieldSymbolizer", + init< std::string const&, std::string const&, unsigned, mapnik::Color const&, + std::string const&, std::string const&,unsigned,unsigned>("TODO")) ; } diff --git a/bindings/python/mapnik_text_symbolizer.cpp b/bindings/python/mapnik_text_symbolizer.cpp index fc979e470..db73e8a9a 100644 --- a/bindings/python/mapnik_text_symbolizer.cpp +++ b/bindings/python/mapnik_text_symbolizer.cpp @@ -67,6 +67,9 @@ void export_text_symbolizer() .add_property("avoid_edges", &text_symbolizer::get_avoid_edges, &text_symbolizer::set_avoid_edges) + .add_property("minimum_distance", + &text_symbolizer::get_minimum_distance, + &text_symbolizer::set_minimum_distance) .add_property("label_placement", &text_symbolizer::get_label_placement, diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index bc1f5ef03..ad18b551e 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.hpp @@ -75,8 +75,8 @@ namespace mapnik { T & pixmap_; CoordTransform t_; face_manager font_manager_; - label_collision_detector3 detector_; - placement_finder finder_; + label_collision_detector4 detector_; + placement_finder finder_; }; } diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index 4ac62880f..a9239dd43 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -304,11 +304,13 @@ namespace mapnik return dimension_t(slot->advance.x >> 6, glyph_bbox.yMax - glyph_bbox.yMin); } - void get_string_info(std::wstring const& text, string_info *info) + void get_string_info(string_info *info) { unsigned width = 0; unsigned height = 0; - + + std::wstring text = info->get_string(); + for (std::wstring::const_iterator i=text.begin();i!=text.end();++i) { dimension_t char_dim = character_dimensions(*i); diff --git a/include/mapnik/label_collision_detector.hpp b/include/mapnik/label_collision_detector.hpp index a5e468e32..85a8e9e22 100644 --- a/include/mapnik/label_collision_detector.hpp +++ b/include/mapnik/label_collision_detector.hpp @@ -131,6 +131,77 @@ namespace mapnik tree_.clear(); } }; + + + //quad tree based label collission detector so labels dont appear within a given distance + class label_collision_detector4 : boost::noncopyable + { + struct label + { + label(Envelope const& b) : box(b) {} + label(Envelope const& b, std::wstring const& t) : box(b), text(t) {} + + Envelope box; + std::wstring text; + }; + + typedef quad_tree< label > tree_t; + tree_t tree_; + public: + + explicit label_collision_detector4(Envelope const& extent) + : tree_(extent) {} + + bool has_placement(Envelope const& box) + { + tree_t::query_iterator itr = tree_.query_in_box(box); + tree_t::query_iterator end = tree_.query_end(); + + for ( ;itr != end; ++itr) + { + if (itr->box.intersects(box)) + { + return false; + } + } + + return true; + } + + bool has_placement(Envelope const& box, std::wstring const& text, double distance) + { + Envelope bigger_box(box.minx() - distance, box.miny() - distance, box.maxx() + distance, box.maxy() + distance); + + tree_t::query_iterator itr = tree_.query_in_box(bigger_box); + tree_t::query_iterator end = tree_.query_end(); + + for ( ;itr != end; ++itr) + { + if (itr->box.intersects(box) || (text == itr->text && itr->box.intersects(bigger_box))) + { + return false; + } + } + + return true; + } + + + void insert(Envelope const& box) + { + tree_.insert(label(box), box); + } + + void insert(Envelope const& box, std::wstring const& text) + { + tree_.insert(label(box, text), box); + } + + void clear() + { + tree_.clear(); + } + }; } #endif diff --git a/include/mapnik/placement_finder.hpp b/include/mapnik/placement_finder.hpp index 93ee6e448..63b16d50e 100644 --- a/include/mapnik/placement_finder.hpp +++ b/include/mapnik/placement_finder.hpp @@ -49,37 +49,34 @@ namespace mapnik { 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 + template placement(string_info *info_, CoordTransform *ctrans_, const proj_transform *proj_trans_, geometry_ptr geom_, - position const& displacement, - label_placement_e placement_); + SymbolizerT sym); ~placement(); + //helpers + std::pair get_position_at_distance(double target_distance); + double get_total_distance(); + void clear_envelopes(); + unsigned path_size() const; + string_info *info; CoordTransform *ctrans; const proj_transform *proj_trans; - geometry_ptr geom; + path_type shape_path; + + double total_distance_; //cache for distance + position displacement_; label_placement_e label_placement; - std::pair dimensions; - bool has_dimensions; - - path_type shape_path; std::queue< Envelope > envelopes; //output @@ -88,13 +85,6 @@ namespace mapnik // 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; @@ -103,8 +93,12 @@ namespace mapnik bool force_odd_labels; //Always try render an odd amount of labels double max_char_angle_delta; + double minimum_distance; bool avoid_edges; + + bool has_dimensions; + std::pair dimensions; }; @@ -115,7 +109,7 @@ namespace mapnik public: //e is the dimensions of the map, buffer is the buffer used for collission detection. placement_finder(DetectorT & detector,Envelope const& e); - bool find_placements(placement *p); + void find_placements(placement *p); void clear(); protected: @@ -123,9 +117,10 @@ namespace mapnik bool find_placement_horizontal(placement *p); bool build_path_follow(placement *p, double target_distance); bool build_path_horizontal(placement *p, double target_distance); + std::vector get_ideal_placements(placement *p); void update_detector(placement *p); - Envelope dimensions_; DetectorT & detector_; + Envelope dimensions_; }; } diff --git a/include/mapnik/shield_symbolizer.hpp b/include/mapnik/shield_symbolizer.hpp index 6cb5e6586..891fca32c 100644 --- a/include/mapnik/shield_symbolizer.hpp +++ b/include/mapnik/shield_symbolizer.hpp @@ -27,43 +27,28 @@ #include #include +#include namespace mapnik { - struct MAPNIK_DECL shield_symbolizer - { - explicit shield_symbolizer(); - shield_symbolizer(std::string const& name, - std::string const& face_name, - unsigned size, - Color const& fill, - std::string const& file, - std::string const& type, - unsigned width,unsigned height); - shield_symbolizer(shield_symbolizer const& rhs); - void set_data (boost::shared_ptr symbol); - boost::shared_ptr const& get_data() const; - - std::string const& get_name() const; - std::string const& get_face_name() const; + struct MAPNIK_DECL shield_symbolizer : public text_symbolizer + { + shield_symbolizer(std::string const& name, + std::string const& face_name, + unsigned size, + Color const& fill, + std::string const& file, + std::string const& type, + unsigned width,unsigned height); + + + void set_background_image(boost::shared_ptr); + boost::shared_ptr const& get_background_image() const; - unsigned get_text_size() const; - Color const& get_fill() const; - - void set_allow_overlap(bool overlap); - bool get_allow_overlap() const; - - void set_avoid_edges(bool avoid); - bool get_avoid_edges() const; - private: - std::string name_; - std::string face_name_; - unsigned size_; - Color fill_; - boost::shared_ptr symbol_; - bool overlap_; - bool avoid_edges_; - }; + private: + boost::shared_ptr background_image_; + + }; } #endif // SHIELD_SYMBOLIZER_HPP diff --git a/include/mapnik/text_path.hpp b/include/mapnik/text_path.hpp index e2dfbd16b..8e15f0d7c 100644 --- a/include/mapnik/text_path.hpp +++ b/include/mapnik/text_path.hpp @@ -53,14 +53,17 @@ namespace mapnik typedef boost::ptr_vector characters_t; + std::wstring string_; characters_t characters_; - unsigned itr_; double width_; double height_; public: - string_info() : itr_(0), width_(0), height_(0) {} - + string_info(std::wstring string) + : string_(string), + width_(0), + height_(0) {} + void add_info(int c, double width, double height) { characters_.push_back(new character_info(c, width, height)); @@ -91,6 +94,10 @@ namespace mapnik { return std::pair(width_, height_); } + + std::wstring get_string() { + return string_; + } }; struct text_path diff --git a/include/mapnik/text_symbolizer.hpp b/include/mapnik/text_symbolizer.hpp index e91ea9084..47816342e 100644 --- a/include/mapnik/text_symbolizer.hpp +++ b/include/mapnik/text_symbolizer.hpp @@ -28,8 +28,10 @@ #include // boost #include +#include // mapnik #include +#include namespace mapnik { @@ -74,9 +76,10 @@ namespace mapnik position const& get_displacement() const; void set_avoid_edges(bool avoid); bool get_avoid_edges() const; + void set_minimum_distance(double distance); + double get_minimum_distance() const; void set_allow_overlap(bool overlap); bool get_allow_overlap() const; - private: std::string name_; std::string face_name_; @@ -94,6 +97,7 @@ namespace mapnik position anchor_; position displacement_; bool avoid_edges_; + double minimum_distance_; bool overlap_; }; } diff --git a/src/agg_renderer.cpp b/src/agg_renderer.cpp index 3e4406064..cc4e3f9b2 100644 --- a/src/agg_renderer.cpp +++ b/src/agg_renderer.cpp @@ -340,39 +340,35 @@ namespace mapnik if (geom && geom->num_points() > 0) { std::wstring text = feature[sym.get_name()].to_unicode(); - boost::shared_ptr const& data = sym.get_data(); + boost::shared_ptr const& data = sym.get_background_image(); if (text.length() > 0 && data) { face_ptr face = font_manager_.get_face(sym.get_face_name()); if (face) { - int w = data->width(); - int h = data->height(); - text_renderer ren(pixmap_,face); ren.set_pixel_size(sym.get_text_size()); ren.set_fill(sym.get_fill()); - string_info info; - ren.get_string_info(text, &info); + string_info info(text); + ren.get_string_info(&info); - placement text_placement(&info, &t_, &prj_trans, geom, std::pair(w, h) ); + placement text_placement(&info, &t_, &prj_trans, geom, sym); text_placement.avoid_edges = sym.get_avoid_edges(); - bool found = finder_.find_placements(&text_placement); - if (!found) { - return; - } - + finder_.find_placements(&text_placement); for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) - { + { + int w = data->width(); + int h = data->height(); + double x = text_placement.placements[ii].starting_x; double y = text_placement.placements[ii].starting_y; - int px=int(floor(x - 0.5 * w)); - int py=int(floor(y - 0.5 * h)); + int px=int(x - (w/2)); + int py=int(y - (h/2)); pixmap_.set_rectangle_alpha(px,py,*data); @@ -512,25 +508,12 @@ namespace mapnik ren.set_halo_fill(sym.get_halo_fill()); ren.set_halo_radius(sym.get_halo_radius()); - string_info info; + string_info info(text); + ren.get_string_info(&info); - ren.get_string_info(text, &info); - - placement text_placement(&info, &t_, &prj_trans, geom, - sym.get_displacement(), - sym.get_label_placement()); + placement text_placement(&info, &t_, &prj_trans, geom, sym); - text_placement.text_ratio = sym.get_text_ratio(); - text_placement.wrap_width = sym.get_wrap_width(); - text_placement.label_spacing = sym.get_label_spacing(); - text_placement.label_position_tolerance = sym.get_label_position_tolerance(); - text_placement.force_odd_labels = sym.get_force_odd_labels(); - text_placement.max_char_angle_delta = sym.get_max_char_angle_delta(); - text_placement.avoid_edges = sym.get_avoid_edges(); - - bool allow_overlap = sym.get_allow_overlap(); //FIXME!!! - - if ( !finder_.find_placements(&text_placement)) return; + finder_.find_placements(&text_placement); for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) { diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index adc64ed5e..409e42ca1 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#include #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -45,56 +47,61 @@ namespace mapnik { - //For shields + template<> placement::placement(string_info *info_, - CoordTransform *ctrans_, - const proj_transform *proj_trans_, - geometry_ptr geom_, - std::pair dimensions_) + CoordTransform *ctrans_, + const proj_transform *proj_trans_, + geometry_ptr geom_, + shield_symbolizer sym) : 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) + displacement_(sym.get_displacement()), + label_placement(sym.get_label_placement()), + wrap_width(sym.get_wrap_width()), + text_ratio(sym.get_text_ratio()), + label_spacing(sym.get_label_spacing()), + label_position_tolerance(sym.get_label_position_tolerance()), + force_odd_labels(sym.get_force_odd_labels()), + max_char_angle_delta(sym.get_max_char_angle_delta()), + minimum_distance(sym.get_minimum_distance()), + avoid_edges(sym.get_avoid_edges()), + has_dimensions(true), + dimensions(std::make_pair(sym.get_background_image()->width(), + sym.get_background_image()->height())) { } - - //For text + + template<> placement::placement(string_info *info_, - CoordTransform *ctrans_, - const proj_transform *proj_trans_, - geometry_ptr geom_, - position const& displacement, - label_placement_e placement_) + CoordTransform *ctrans_, + const proj_transform *proj_trans_, + geometry_ptr geom_, + text_symbolizer sym) : info(info_), ctrans(ctrans_), proj_trans(proj_trans_), - geom(geom_), - displacement_(displacement), - label_placement(placement_), - has_dimensions(false), + geom(geom_), 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) + displacement_(sym.get_displacement()), + label_placement(sym.get_label_placement()), + wrap_width(sym.get_wrap_width()), + text_ratio(sym.get_text_ratio()), + label_spacing(sym.get_label_spacing()), + label_position_tolerance(sym.get_label_position_tolerance()), + force_odd_labels(sym.get_force_odd_labels()), + max_char_angle_delta(sym.get_max_char_angle_delta()), + minimum_distance(sym.get_minimum_distance()), + avoid_edges(sym.get_avoid_edges()), + has_dimensions(false), + dimensions() { } + placement::~placement() { @@ -185,50 +192,43 @@ namespace mapnik placement_finder::placement_finder(DetectorT & detector,Envelope const& e) : detector_(detector), dimensions_(e) - //detector_(Envelope(e.minx() - buffer, e.miny() - buffer, e.maxx() + buffer, e.maxy() + buffer)) { } template - bool placement_finder::find_placements(placement *p) + std::vector placement_finder::get_ideal_placements(placement *p) { - if (p->label_placement == point_placement) - { - return find_placement_horizontal(p); - } - else if (p->label_placement == line_placement) - { - return find_placement_follow(p); - } - - return false; - } + std::vector ideal_label_distances; - template - bool placement_finder::find_placement_follow(placement *p) - { std::pair string_dimensions = p->info->get_dimensions(); double string_width = string_dimensions.first; double distance = p->get_total_distance(); - if (string_width > distance) + if (p->label_placement == line_placement && string_width > distance) { - return false; + //Empty! + return ideal_label_distances; } int num_labels = 0; - if (p->label_spacing) + if (p->label_spacing && p->label_placement == line_placement) num_labels = static_cast (floor(distance / (p->label_spacing + string_width))); + else if (p->label_spacing && p->label_placement == point_placement) + num_labels = static_cast (floor(distance / p->label_spacing)); + if (p->force_odd_labels && num_labels%2 == 0) num_labels--; if (num_labels <= 0) num_labels = 1; double ideal_spacing = distance/num_labels; - std::vector ideal_label_distances; - double middle = (distance / 2.0) - (string_width/2.0); //try draw text centered + double middle; //try draw text centered + if (p->label_placement == line_placement) + middle = (distance / 2.0) - (string_width/2.0); + else if (p->label_placement == point_placement) + middle = distance / 2.0; if (num_labels % 2) //odd amount of labels { @@ -248,91 +248,59 @@ namespace mapnik ideal_label_distances.push_back(middle + (ideal_spacing/2.0) + (a*ideal_spacing)); } } - - double delta; - double tolerance; - - if (p->label_position_tolerance > 0) + + if (p->label_position_tolerance == 0) { - tolerance = p->label_position_tolerance; - delta = std::max ( 1.0, p->label_position_tolerance/100.0); - } - else - { - tolerance = ideal_spacing/2.0; - delta = ideal_spacing/100.0; + p->label_position_tolerance = unsigned(ideal_spacing/2.0); } - - bool FoundPlacement = false; - std::vector::const_iterator itr = ideal_label_distances.begin(); - std::vector::const_iterator end = ideal_label_distances.end(); - for (; itr != end; ++itr) - { - //std::clog << "Trying to find txt placement at distance: " << *itr << std::endl; - for (double i = 0; i < tolerance; i += delta) - { - if (*itr + i > distance || *itr -i < 0.0) - continue; - - p->clear_envelopes(); - - // check position +- delta for valid placement - if ( build_path_follow(p, *itr + i) ) { - update_detector(p); - FoundPlacement = true; - break; - } - - p->clear_envelopes(); - if ( build_path_follow(p, *itr - i) ) { - update_detector(p); - FoundPlacement = true; - break; - } - } - } - - // if (FoundPlacement) - // std::clog << "Found Placement" << string_width << " " << distance << std::endl; - - return FoundPlacement; + return ideal_label_distances; } - + template - bool placement_finder::find_placement_horizontal(placement *p) + void placement_finder::find_placements(placement *p) { if (p->path_size() == 1) // point geometry { if ( build_path_horizontal(p, 0) ) { update_detector(p); - return true; } - return false; + return; } - - double distance = p->get_total_distance(); - //~ double delta = string_width/distance; - double delta = distance/100.0; - - for (double i = 0; i < distance/2.0; i += delta) + + std::vector ideal_label_distances = get_ideal_placements(p); + + double delta, tolerance, distance; + distance = p->get_total_distance(); + tolerance = p->label_position_tolerance; + delta = std::max ( 1.0, tolerance/100.0); + + std::vector::const_iterator itr = ideal_label_distances.begin(); + std::vector::const_iterator end = ideal_label_distances.end(); + for (; itr != end; ++itr) { - p->clear_envelopes(); - - if ( build_path_horizontal(p, distance/2.0 + i) ) { - update_detector(p); - return true; + bool placed = false; + for (double i = 0; i < tolerance && !placed; i += delta) + { + for (int s = 1; s != -1; s-=2) { + if (*itr + i*s > distance || *itr + i*s < 0.0) { + continue; + } + p->clear_envelopes(); + // check position +- delta for valid placement + if ((p->label_placement == line_placement && + build_path_follow(p, *itr + (i*s)) ) || + (p->label_placement == point_placement && + build_path_horizontal(p, *itr + (i*s))) ) + { + update_detector(p); + placed = true; + break; + } + } } - - p->clear_envelopes(); - - if ( build_path_horizontal(p, distance/2.0 - i) ) { - update_detector(p); - return true; - } - } - return false; + } } template @@ -342,7 +310,7 @@ namespace mapnik { Envelope e = p->envelopes.front(); - detector_.insert(e); + detector_.insert(e, p->info->get_string()); p->envelopes.pop(); } @@ -493,7 +461,7 @@ namespace mapnik e.expand_to_include(render_x + (ci.width*cos(render_angle) - ci.height*sin(render_angle)), render_y - (ci.width*sin(render_angle) + ci.height*cos(render_angle))); } - if (!detector_.has_placement(e)) + if (!detector_.has_placement(e, p->info->get_string(), p->minimum_distance)) { return false; } @@ -529,7 +497,7 @@ namespace mapnik bool placement_finder::build_path_horizontal(placement *p, double target_distance) { double x, y; - + p->current_placement.path.clear(); std::pair string_dimensions = p->info->get_dimensions(); @@ -630,7 +598,7 @@ namespace mapnik unsigned int index_to_wrap_at = line_breaks[line_number]; double line_width = line_widths[line_number]; - x = -line_width/2.0; + x = -line_width/2.0 - 1.0; y = -string_height/2.0 + 1.0; for (unsigned i = 0; i < p->info->num_characters(); i++) @@ -668,7 +636,7 @@ namespace mapnik p->current_placement.starting_y - y - ci.height); } - if (!detector_.has_placement(e)) + if (!detector_.has_placement(e, p->info->get_string(), p->minimum_distance)) { return false; } @@ -694,6 +662,6 @@ namespace mapnik detector_.clear(); } - template class placement_finder; + template class placement_finder; } // namespace diff --git a/src/shield_symbolizer.cpp b/src/shield_symbolizer.cpp index 123d56424..1096ff1e8 100644 --- a/src/shield_symbolizer.cpp +++ b/src/shield_symbolizer.cpp @@ -34,14 +34,6 @@ namespace mapnik { - shield_symbolizer::shield_symbolizer() - : symbol_(new ImageData32(4,4)), - overlap_(false) - { - //default point symbol is black 4x4px square - symbol_->set(0xff000000); - } - shield_symbolizer::shield_symbolizer( std::string const& name, std::string const& face_name, @@ -50,14 +42,15 @@ namespace mapnik std::string const& file, std::string const& type, unsigned width,unsigned height) - : name_(name), face_name_(face_name), size_(size), fill_(fill), symbol_(new ImageData32(width,height)), avoid_edges_(false) + : text_symbolizer(name, face_name, size, fill), + background_image_(new ImageData32(width, height)) { try { boost::scoped_ptr reader(get_image_reader(type,file)); if (reader.get()) { - reader->read(0,0,*symbol_); + reader->read(0,0,*background_image_); } } catch (...) @@ -65,65 +58,15 @@ namespace mapnik std::clog << "exception caught..." << std::endl; } } - - shield_symbolizer::shield_symbolizer(shield_symbolizer const& rhs) - : name_(rhs.name_), - face_name_(rhs.face_name_), - size_(rhs.size_), - fill_(rhs.fill_), - symbol_(rhs.symbol_), - overlap_(rhs.overlap_), - avoid_edges_(rhs.avoid_edges_) - {} - - void shield_symbolizer::set_data( boost::shared_ptr symbol) + + void shield_symbolizer::set_background_image(boost::shared_ptr background_image) { - symbol_ = symbol; + background_image_ = background_image; } - boost::shared_ptr const& shield_symbolizer::get_data() const + boost::shared_ptr const& shield_symbolizer::get_background_image() const { - return symbol_; - } - - std::string const& shield_symbolizer::get_name() const - { - return name_; - } - - std::string const& shield_symbolizer::get_face_name() const - { - return face_name_; - } - - void shield_symbolizer::set_allow_overlap(bool overlap) - { - overlap_ = overlap; - } - - bool shield_symbolizer::get_allow_overlap() const - { - return overlap_; - } - - unsigned shield_symbolizer::get_text_size() const - { - return size_; - } - - Color const& shield_symbolizer::get_fill() const - { - return fill_; - } - - bool shield_symbolizer::get_avoid_edges() const - { - return avoid_edges_; - } - - void shield_symbolizer::set_avoid_edges(bool avoid) - { - avoid_edges_ = avoid; + return background_image_; } } diff --git a/src/text_symbolizer.cpp b/src/text_symbolizer.cpp index 7be997615..1b0f6977f 100644 --- a/src/text_symbolizer.cpp +++ b/src/text_symbolizer.cpp @@ -22,32 +22,34 @@ //$Id$ - +//stl #include - +// boost +#include +//mapnik #include namespace mapnik { text_symbolizer::text_symbolizer(std::string const& name, std::string const& face_name, unsigned size,Color const& fill) - : name_(name), + : name_(name), face_name_(face_name), - size_(size), + size_(size), text_ratio_(0), wrap_width_(0), label_spacing_(0), label_position_tolerance_(0), force_odd_labels_(false), max_char_angle_delta_(0), - fill_(fill), - halo_fill_(Color(255,255,255)), - halo_radius_(0), - label_p_(point_placement), - anchor_(0.0,0.5), - displacement_(0.0,0.0), + fill_(fill), + halo_fill_(Color(255,255,255)), + halo_radius_(0), + label_p_(point_placement), + anchor_(0.0,0.5), + displacement_(0.0,0.0), avoid_edges_(false), + minimum_distance_(0.0), overlap_(false) {} - text_symbolizer::text_symbolizer(text_symbolizer const& rhs) : name_(rhs.name_), face_name_(rhs.face_name_), @@ -65,6 +67,7 @@ namespace mapnik anchor_(rhs.anchor_), displacement_(rhs.displacement_), avoid_edges_(rhs.avoid_edges_), + minimum_distance_(rhs.minimum_distance_), overlap_(rhs.overlap_) {} text_symbolizer& text_symbolizer::operator=(text_symbolizer const& other) @@ -87,7 +90,9 @@ namespace mapnik anchor_ = other.anchor_; displacement_ = other.displacement_; avoid_edges_ = other.avoid_edges_; + minimum_distance_ = other.minimum_distance_; overlap_ = other.overlap_; + return *this; } @@ -230,13 +235,23 @@ namespace mapnik avoid_edges_ = avoid; } - void text_symbolizer::set_allow_overlap(bool overlap) - { - overlap_ = overlap; - } + double text_symbolizer::get_minimum_distance() const + { + return minimum_distance_; + } + + void text_symbolizer::set_minimum_distance(double distance) + { + minimum_distance_ = distance; + } + + void text_symbolizer::set_allow_overlap(bool overlap) + { + overlap_ = overlap; + } - bool text_symbolizer::get_allow_overlap() const - { + bool text_symbolizer::get_allow_overlap() const + { return overlap_; - } + } }