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.
This commit is contained in:
vspader 2007-07-02 13:39:08 +00:00
parent 560de0b9b1
commit 9fe4a94c98
14 changed files with 293 additions and 320 deletions

View file

@ -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();

View file

@ -29,14 +29,11 @@ void export_shield_symbolizer()
{
using namespace boost::python;
using mapnik::shield_symbolizer;
class_<shield_symbolizer>("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<text_symbolizer> >("ShieldSymbolizer",
init< std::string const&, std::string const&, unsigned, mapnik::Color const&,
std::string const&, std::string const&,unsigned,unsigned>("TODO"))
;
}

View file

@ -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,

View file

@ -75,8 +75,8 @@ namespace mapnik {
T & pixmap_;
CoordTransform t_;
face_manager<freetype_engine> font_manager_;
label_collision_detector3 detector_;
placement_finder<label_collision_detector3> finder_;
label_collision_detector4 detector_;
placement_finder<label_collision_detector4> finder_;
};
}

View file

@ -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);

View file

@ -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<double> const& b) : box(b) {}
label(Envelope<double> const& b, std::wstring const& t) : box(b), text(t) {}
Envelope<double> box;
std::wstring text;
};
typedef quad_tree< label > tree_t;
tree_t tree_;
public:
explicit label_collision_detector4(Envelope<double> const& extent)
: tree_(extent) {}
bool has_placement(Envelope<double> 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<double> const& box, std::wstring const& text, double distance)
{
Envelope<double> 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<double> const& box)
{
tree_.insert(label(box), box);
}
void insert(Envelope<double> const& box, std::wstring const& text)
{
tree_.insert(label(box, text), box);
}
void clear()
{
tree_.clear();
}
};
}
#endif

View file

@ -49,37 +49,34 @@ namespace mapnik
{
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
template <typename SymbolizerT>
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<double, double> 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<double, double> dimensions;
bool has_dimensions;
path_type shape_path;
std::queue< Envelope<double> > envelopes;
//output
@ -88,13 +85,6 @@ namespace mapnik
// 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;
@ -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<double, double> 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<double> 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<double> get_ideal_placements(placement *p);
void update_detector(placement *p);
Envelope<double> dimensions_;
DetectorT & detector_;
Envelope<double> dimensions_;
};
}

View file

@ -27,43 +27,28 @@
#include <boost/shared_ptr.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/text_symbolizer.hpp>
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<ImageData32> symbol);
boost::shared_ptr<ImageData32> 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<ImageData32>);
boost::shared_ptr<ImageData32> 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<ImageData32> symbol_;
bool overlap_;
bool avoid_edges_;
};
private:
boost::shared_ptr<ImageData32> background_image_;
};
}
#endif // SHIELD_SYMBOLIZER_HPP

View file

@ -53,14 +53,17 @@ namespace mapnik
typedef boost::ptr_vector<character_info> 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<double, double>(width_, height_);
}
std::wstring get_string() {
return string_;
}
};
struct text_path

View file

@ -28,8 +28,10 @@
#include <string>
// boost
#include <boost/tuple/tuple.hpp>
#include <boost/shared_ptr.hpp>
// mapnik
#include <mapnik/color.hpp>
#include <mapnik/graphics.hpp>
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_;
};
}

View file

@ -340,39 +340,35 @@ namespace mapnik
if (geom && geom->num_points() > 0)
{
std::wstring text = feature[sym.get_name()].to_unicode();
boost::shared_ptr<ImageData32> const& data = sym.get_data();
boost::shared_ptr<ImageData32> 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<mapnik::Image32> 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<double, double>(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)
{

View file

@ -38,6 +38,8 @@
#include <mapnik/geometry.hpp>
#include <mapnik/placement_finder.hpp>
#include <mapnik/text_path.hpp>
#include <mapnik/shield_symbolizer.hpp>
#include <mapnik/text_symbolizer.hpp>
#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<double, double> 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<DetectorT>::placement_finder(DetectorT & detector,Envelope<double> const& e)
: detector_(detector),
dimensions_(e)
//detector_(Envelope<double>(e.minx() - buffer, e.miny() - buffer, e.maxx() + buffer, e.maxy() + buffer))
{
}
template <typename DetectorT>
bool placement_finder<DetectorT>::find_placements(placement *p)
std::vector<double> placement_finder<DetectorT>::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<double> ideal_label_distances;
template <typename DetectorT>
bool placement_finder<DetectorT>::find_placement_follow(placement *p)
{
std::pair<double, double> 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<int> (floor(distance / (p->label_spacing + string_width)));
else if (p->label_spacing && p->label_placement == point_placement)
num_labels = static_cast<int> (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<double> 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<double>::const_iterator itr = ideal_label_distances.begin();
std::vector<double>::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 <typename DetectorT>
bool placement_finder<DetectorT>::find_placement_horizontal(placement *p)
void placement_finder<DetectorT>::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<double> 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<double>::const_iterator itr = ideal_label_distances.begin();
std::vector<double>::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 <typename DetectorT>
@ -342,7 +310,7 @@ namespace mapnik
{
Envelope<double> 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<DetectorT>::build_path_horizontal(placement *p, double target_distance)
{
double x, y;
p->current_placement.path.clear();
std::pair<double, double> 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<label_collision_detector3>;
template class placement_finder<label_collision_detector4>;
} // namespace

View file

@ -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<ImageReader> 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<ImageData32> symbol)
void shield_symbolizer::set_background_image(boost::shared_ptr<ImageData32> background_image)
{
symbol_ = symbol;
background_image_ = background_image;
}
boost::shared_ptr<ImageData32> const& shield_symbolizer::get_data() const
boost::shared_ptr<ImageData32> 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_;
}
}

View file

@ -22,32 +22,34 @@
//$Id$
//stl
#include <iostream>
// boost
#include <boost/scoped_ptr.hpp>
//mapnik
#include <mapnik/text_symbolizer.hpp>
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_;
}
}
}