Revert previous fix for #89 and add a new improved fix that enhances the
value class to have a proper null type and do comparisions SQL style so that null is neither equal nor not equal to other things.
This commit is contained in:
parent
a27bde741e
commit
4483d59797
5 changed files with 259 additions and 178 deletions
|
@ -47,6 +47,11 @@ namespace boost { namespace python {
|
||||||
{
|
{
|
||||||
return ::PyUnicode_FromWideChar((wchar_t*)s.getBuffer(),implicit_cast<ssize_t>(s.length()));
|
return ::PyUnicode_FromWideChar((wchar_t*)s.getBuffer(),implicit_cast<ssize_t>(s.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject * operator() (mapnik::value_null const& s) const
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mapnik_value_to_python
|
struct mapnik_value_to_python
|
||||||
|
|
|
@ -120,11 +120,6 @@ namespace mapnik {
|
||||||
return props_.end();
|
return props_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exists(const std::string &k) const
|
|
||||||
{
|
|
||||||
return props_.find(k) != props_.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string() const
|
std::string to_string() const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
|
@ -39,14 +39,18 @@
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
typedef boost::variant<bool,int,double,UnicodeString> value_base;
|
struct value_null
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boost::variant<value_null,bool,int,double,UnicodeString> value_base;
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
struct equals
|
struct equals
|
||||||
: public boost::static_visitor<bool>
|
: public boost::static_visitor<bool>
|
||||||
{
|
{
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
bool operator() (const T &, const U & ) const
|
bool operator() (const T &, const U &) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -72,19 +76,73 @@ namespace mapnik {
|
||||||
{
|
{
|
||||||
return lhs == rhs;
|
return lhs == rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator() (value_null, value_null) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct not_equals
|
||||||
|
: public boost::static_visitor<bool>
|
||||||
|
{
|
||||||
|
template <typename T, typename U>
|
||||||
|
bool operator() (const T &, const U &) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool operator() (T lhs, T rhs) const
|
||||||
|
{
|
||||||
|
return lhs != rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator() (int lhs, double rhs) const
|
||||||
|
{
|
||||||
|
return lhs != rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator() (double lhs, int rhs) const
|
||||||
|
{
|
||||||
|
return lhs != rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator() (UnicodeString const& lhs,
|
||||||
|
UnicodeString const& rhs) const
|
||||||
|
{
|
||||||
|
return lhs != rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator() (value_null, value_null) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool operator() (value_null, const T &) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool operator() (const T &, value_null) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct greater_than
|
struct greater_than
|
||||||
: public boost::static_visitor<bool>
|
: public boost::static_visitor<bool>
|
||||||
{
|
{
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
bool operator()( const T &, const U & ) const
|
bool operator()(const T &, const U &) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool operator()( T lhs, T rhs ) const
|
bool operator()(T lhs, T rhs) const
|
||||||
{
|
{
|
||||||
return lhs > rhs;
|
return lhs > rhs;
|
||||||
}
|
}
|
||||||
|
@ -103,13 +161,18 @@ namespace mapnik {
|
||||||
{
|
{
|
||||||
return lhs > rhs;
|
return lhs > rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator() (value_null, value_null) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct greater_or_equal
|
struct greater_or_equal
|
||||||
: public boost::static_visitor<bool>
|
: public boost::static_visitor<bool>
|
||||||
{
|
{
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
bool operator()( const T &, const U & ) const
|
bool operator()(const T &, const U &) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -130,23 +193,28 @@ namespace mapnik {
|
||||||
return lhs >= rhs;
|
return lhs >= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator() (UnicodeString const& lhs, UnicodeString const& rhs ) const
|
bool operator() (UnicodeString const& lhs, UnicodeString const& rhs) const
|
||||||
{
|
{
|
||||||
return lhs >= rhs;
|
return lhs >= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator() (value_null, value_null) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct less_than
|
struct less_than
|
||||||
: public boost::static_visitor<bool>
|
: public boost::static_visitor<bool>
|
||||||
{
|
{
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
bool operator()( const T &, const U & ) const
|
bool operator()(const T &, const U &) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool operator()( T lhs,T rhs) const
|
bool operator()(T lhs, T rhs) const
|
||||||
{
|
{
|
||||||
return lhs < rhs;
|
return lhs < rhs;
|
||||||
}
|
}
|
||||||
|
@ -161,24 +229,29 @@ namespace mapnik {
|
||||||
return lhs < rhs;
|
return lhs < rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()( UnicodeString const& lhs,
|
bool operator()(UnicodeString const& lhs,
|
||||||
UnicodeString const& rhs ) const
|
UnicodeString const& rhs ) const
|
||||||
{
|
{
|
||||||
return lhs < rhs;
|
return lhs < rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator() (value_null, value_null) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct less_or_equal
|
struct less_or_equal
|
||||||
: public boost::static_visitor<bool>
|
: public boost::static_visitor<bool>
|
||||||
{
|
{
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
bool operator()( const T &, const U & ) const
|
bool operator()(const T &, const U &) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool operator()(T lhs, T rhs ) const
|
bool operator()(T lhs, T rhs) const
|
||||||
{
|
{
|
||||||
return lhs <= rhs;
|
return lhs <= rhs;
|
||||||
}
|
}
|
||||||
|
@ -194,11 +267,16 @@ namespace mapnik {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool operator()( UnicodeString const& lhs,
|
bool operator()(UnicodeString const& lhs,
|
||||||
UnicodeString const& rhs ) const
|
UnicodeString const& rhs ) const
|
||||||
{
|
{
|
||||||
return lhs <= rhs;
|
return lhs <= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator() (value_null, value_null) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
|
@ -386,7 +464,12 @@ namespace mapnik {
|
||||||
ss << std::setprecision(16) << val;
|
ss << std::setprecision(16) << val;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
std::string operator() (value_null const& val) const
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct to_unicode : public boost::static_visitor<UnicodeString>
|
struct to_unicode : public boost::static_visitor<UnicodeString>
|
||||||
{
|
{
|
||||||
|
@ -411,6 +494,11 @@ namespace mapnik {
|
||||||
out << std::setprecision(16) << val;
|
out << std::setprecision(16) << val;
|
||||||
return UnicodeString(out.str().c_str());
|
return UnicodeString(out.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnicodeString operator() (value_null const& val) const
|
||||||
|
{
|
||||||
|
return UnicodeString("");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct to_expression_string : public boost::static_visitor<std::string>
|
struct to_expression_string : public boost::static_visitor<std::string>
|
||||||
|
@ -455,9 +543,14 @@ namespace mapnik {
|
||||||
ss << std::setprecision(16) << val;
|
ss << std::setprecision(16) << val;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string operator() (value_null const& val) const
|
||||||
|
{
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class value
|
class value
|
||||||
{
|
{
|
||||||
value_base base_;
|
value_base base_;
|
||||||
|
@ -468,7 +561,7 @@ namespace mapnik {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
value ()
|
value ()
|
||||||
: base_(0) {}
|
: base_(value_null()) {}
|
||||||
|
|
||||||
template <typename T> value(T _val_)
|
template <typename T> value(T _val_)
|
||||||
: base_(_val_) {}
|
: base_(_val_) {}
|
||||||
|
@ -480,7 +573,7 @@ namespace mapnik {
|
||||||
|
|
||||||
bool operator!=(value const& other) const
|
bool operator!=(value const& other) const
|
||||||
{
|
{
|
||||||
return !(boost::apply_visitor(impl::equals(),base_,other.base_));
|
return boost::apply_visitor(impl::not_equals(),base_,other.base_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>(value const& other) const
|
bool operator>(value const& other) const
|
||||||
|
|
|
@ -456,52 +456,49 @@ namespace mapnik
|
||||||
proj_transform const& prj_trans)
|
proj_transform const& prj_trans)
|
||||||
{
|
{
|
||||||
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
||||||
if (feature.exists(sym.get_name()))
|
UnicodeString text = feature[sym.get_name()].to_unicode();
|
||||||
|
boost::shared_ptr<ImageData32> const& data = sym.get_image();
|
||||||
|
if (text.length() > 0 && data)
|
||||||
{
|
{
|
||||||
UnicodeString text = feature[sym.get_name()].to_unicode();
|
face_ptr face = font_manager_.get_face(sym.get_face_name());
|
||||||
boost::shared_ptr<ImageData32> const& data = sym.get_image();
|
if (face)
|
||||||
if (text.length() > 0 && data)
|
|
||||||
{
|
{
|
||||||
face_ptr face = font_manager_.get_face(sym.get_face_name());
|
text_renderer<mapnik::Image32> ren(pixmap_,face);
|
||||||
if (face)
|
ren.set_pixel_size(sym.get_text_size());
|
||||||
|
ren.set_fill(sym.get_fill());
|
||||||
|
|
||||||
|
string_info info(text);
|
||||||
|
face->get_string_info(info);
|
||||||
|
|
||||||
|
placement_finder<label_collision_detector4> finder(detector_);
|
||||||
|
|
||||||
|
unsigned num_geom = feature.num_geometries();
|
||||||
|
for (unsigned i=0;i<num_geom;++i)
|
||||||
{
|
{
|
||||||
text_renderer<mapnik::Image32> ren(pixmap_,face);
|
geometry2d const& geom = feature.get_geometry(i);
|
||||||
ren.set_pixel_size(sym.get_text_size());
|
if (geom.num_points() > 0) // don't bother with empty geometries
|
||||||
ren.set_fill(sym.get_fill());
|
{
|
||||||
|
path_type path(t_,geom,prj_trans);
|
||||||
string_info info(text);
|
placement text_placement(info, sym);
|
||||||
face->get_string_info(info);
|
text_placement.avoid_edges = sym.get_avoid_edges();
|
||||||
|
finder.find_point_placements<path_type>(text_placement,path);
|
||||||
placement_finder<label_collision_detector4> finder(detector_);
|
|
||||||
|
|
||||||
unsigned num_geom = feature.num_geometries();
|
|
||||||
for (unsigned i=0;i<num_geom;++i)
|
|
||||||
{
|
|
||||||
geometry2d const& geom = feature.get_geometry(i);
|
|
||||||
if (geom.num_points() > 0) // don't bother with empty geometries
|
|
||||||
{
|
|
||||||
path_type path(t_,geom,prj_trans);
|
|
||||||
placement text_placement(info, sym);
|
|
||||||
text_placement.avoid_edges = sym.get_avoid_edges();
|
|
||||||
finder.find_point_placements<path_type>(text_placement,path);
|
|
||||||
|
|
||||||
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
|
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
|
||||||
{
|
{
|
||||||
int w = data->width();
|
int w = data->width();
|
||||||
int h = data->height();
|
int h = data->height();
|
||||||
|
|
||||||
double x = text_placement.placements[ii].starting_x;
|
double x = text_placement.placements[ii].starting_x;
|
||||||
double y = text_placement.placements[ii].starting_y;
|
double y = text_placement.placements[ii].starting_y;
|
||||||
|
|
||||||
int px=int(x - (w/2));
|
int px=int(x - (w/2));
|
||||||
int py=int(y - (h/2));
|
int py=int(y - (h/2));
|
||||||
|
|
||||||
pixmap_.set_rectangle_alpha(px,py,*data);
|
pixmap_.set_rectangle_alpha(px,py,*data);
|
||||||
|
|
||||||
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
|
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
|
||||||
|
|
||||||
ren.render(x,y);
|
ren.render(x,y);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -668,61 +665,58 @@ namespace mapnik
|
||||||
proj_transform const& prj_trans)
|
proj_transform const& prj_trans)
|
||||||
{
|
{
|
||||||
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
||||||
|
|
||||||
if (feature.exists(sym.get_name()))
|
UnicodeString text = feature[sym.get_name()].to_unicode();
|
||||||
|
if ( text.length() > 0 )
|
||||||
{
|
{
|
||||||
UnicodeString text = feature[sym.get_name()].to_unicode();
|
Color const& fill = sym.get_fill();
|
||||||
if ( text.length() > 0 )
|
face_ptr face = font_manager_.get_face(sym.get_face_name());
|
||||||
|
if (face)
|
||||||
{
|
{
|
||||||
Color const& fill = sym.get_fill();
|
text_renderer<mapnik::Image32> ren(pixmap_,face);
|
||||||
face_ptr face = font_manager_.get_face(sym.get_face_name());
|
ren.set_pixel_size(sym.get_text_size());
|
||||||
if (face)
|
ren.set_fill(fill);
|
||||||
|
ren.set_halo_fill(sym.get_halo_fill());
|
||||||
|
ren.set_halo_radius(sym.get_halo_radius());
|
||||||
|
|
||||||
|
placement_finder<label_collision_detector4> finder(detector_);
|
||||||
|
|
||||||
|
string_info info(text);
|
||||||
|
face->get_string_info(info);
|
||||||
|
unsigned num_geom = feature.num_geometries();
|
||||||
|
for (unsigned i=0;i<num_geom;++i)
|
||||||
{
|
{
|
||||||
text_renderer<mapnik::Image32> ren(pixmap_,face);
|
geometry2d const& geom = feature.get_geometry(i);
|
||||||
ren.set_pixel_size(sym.get_text_size());
|
if (geom.num_points() > 0) // don't bother with empty geometries
|
||||||
ren.set_fill(fill);
|
|
||||||
ren.set_halo_fill(sym.get_halo_fill());
|
|
||||||
ren.set_halo_radius(sym.get_halo_radius());
|
|
||||||
|
|
||||||
placement_finder<label_collision_detector4> finder(detector_);
|
|
||||||
|
|
||||||
string_info info(text);
|
|
||||||
face->get_string_info(info);
|
|
||||||
unsigned num_geom = feature.num_geometries();
|
|
||||||
for (unsigned i=0;i<num_geom;++i)
|
|
||||||
{
|
{
|
||||||
geometry2d const& geom = feature.get_geometry(i);
|
path_type path(t_,geom,prj_trans);
|
||||||
if (geom.num_points() > 0) // don't bother with empty geometries
|
placement text_placement(info,sym);
|
||||||
|
if (sym.get_label_placement() == POINT_PLACEMENT)
|
||||||
{
|
{
|
||||||
path_type path(t_,geom,prj_trans);
|
double label_x, label_y, z=0.0;
|
||||||
placement text_placement(info,sym);
|
geom.label_position(&label_x, &label_y);
|
||||||
if (sym.get_label_placement() == POINT_PLACEMENT)
|
prj_trans.backward(label_x,label_y, z);
|
||||||
{
|
t_.forward(&label_x,&label_y);
|
||||||
double label_x, label_y, z=0.0;
|
finder.find_point_placement(text_placement,label_x,label_y);
|
||||||
geom.label_position(&label_x, &label_y);
|
}
|
||||||
prj_trans.backward(label_x,label_y, z);
|
else //LINE_PLACEMENT
|
||||||
t_.forward(&label_x,&label_y);
|
{
|
||||||
finder.find_point_placement(text_placement,label_x,label_y);
|
finder.find_line_placements<path_type>(text_placement,path);
|
||||||
}
|
}
|
||||||
else //LINE_PLACEMENT
|
|
||||||
{
|
|
||||||
finder.find_line_placements<path_type>(text_placement,path);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii)
|
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii)
|
||||||
{
|
{
|
||||||
double x = text_placement.placements[ii].starting_x;
|
double x = text_placement.placements[ii].starting_x;
|
||||||
double y = text_placement.placements[ii].starting_y;
|
double y = text_placement.placements[ii].starting_y;
|
||||||
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
|
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
|
||||||
ren.render(x,y);
|
ren.render(x,y);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
|
{
|
||||||
}
|
throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -750,47 +750,44 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
||||||
|
|
||||||
if (feature.exists(sym.get_name()))
|
UnicodeString text = feature[sym.get_name()].to_unicode();
|
||||||
|
boost::shared_ptr<ImageData32> const& data = sym.get_image();
|
||||||
|
|
||||||
|
if (text.length() > 0 && data)
|
||||||
{
|
{
|
||||||
UnicodeString text = feature[sym.get_name()].to_unicode();
|
cairo_face_ptr face = face_manager_.get_face(sym.get_face_name());
|
||||||
boost::shared_ptr<ImageData32> const& data = sym.get_image();
|
|
||||||
|
|
||||||
if (text.length() > 0 && data)
|
if (face)
|
||||||
{
|
{
|
||||||
cairo_face_ptr face = face_manager_.get_face(sym.get_face_name());
|
cairo_context context(context_);
|
||||||
|
|
||||||
if (face)
|
context.set_font_face(face);
|
||||||
|
|
||||||
|
string_info info(text);
|
||||||
|
|
||||||
|
face->get_string_info(sym.get_text_size(), info);
|
||||||
|
|
||||||
|
placement_finder<label_collision_detector4> finder(detector_);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
cairo_context context(context_);
|
geometry2d const& geom = feature.get_geometry(i);
|
||||||
|
|
||||||
context.set_font_face(face);
|
if (geom.num_points() > 0) // don't bother with empty geometries
|
||||||
|
|
||||||
string_info info(text);
|
|
||||||
|
|
||||||
face->get_string_info(sym.get_text_size(), info);
|
|
||||||
|
|
||||||
placement_finder<label_collision_detector4> finder(detector_);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < feature.num_geometries(); ++i)
|
|
||||||
{
|
{
|
||||||
geometry2d const& geom = feature.get_geometry(i);
|
path_type path(t_, geom, prj_trans);
|
||||||
|
placement text_placement(info, sym);
|
||||||
|
|
||||||
if (geom.num_points() > 0) // don't bother with empty geometries
|
text_placement.avoid_edges = sym.get_avoid_edges();
|
||||||
|
finder.find_point_placements<path_type>(text_placement, path);
|
||||||
|
|
||||||
|
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
|
||||||
{
|
{
|
||||||
path_type path(t_, geom, prj_trans);
|
double shield_x = text_placement.placements[ii].starting_x - data->width() / 2;
|
||||||
placement text_placement(info, sym);
|
double shield_y = text_placement.placements[ii].starting_y - data->height() / 2;
|
||||||
|
|
||||||
text_placement.avoid_edges = sym.get_avoid_edges();
|
context.add_image(shield_x, shield_y, *data);
|
||||||
finder.find_point_placements<path_type>(text_placement, path);
|
context.add_text(sym, text_placement.placements[ii], face);
|
||||||
|
|
||||||
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
|
|
||||||
{
|
|
||||||
double shield_x = text_placement.placements[ii].starting_x - data->width() / 2;
|
|
||||||
double shield_y = text_placement.placements[ii].starting_y - data->height() / 2;
|
|
||||||
|
|
||||||
context.add_image(shield_x, shield_y, *data);
|
|
||||||
context.add_text(sym, text_placement.placements[ii], face);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -927,60 +924,57 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
||||||
|
|
||||||
if (feature.exists(sym.get_name()))
|
UnicodeString text = feature[sym.get_name()].to_unicode();
|
||||||
|
|
||||||
|
if (text.length() > 0)
|
||||||
{
|
{
|
||||||
UnicodeString text = feature[sym.get_name()].to_unicode();
|
cairo_face_ptr face = face_manager_.get_face(sym.get_face_name());
|
||||||
|
|
||||||
if (text.length() > 0)
|
if (face)
|
||||||
{
|
{
|
||||||
cairo_face_ptr face = face_manager_.get_face(sym.get_face_name());
|
cairo_context context(context_);
|
||||||
|
|
||||||
if (face)
|
context.set_font_face(face);
|
||||||
|
|
||||||
|
string_info info(text);
|
||||||
|
|
||||||
|
face->get_string_info(sym.get_text_size(), info);
|
||||||
|
|
||||||
|
placement_finder<label_collision_detector4> finder(detector_);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
cairo_context context(context_);
|
geometry2d const& geom = feature.get_geometry(i);
|
||||||
|
|
||||||
context.set_font_face(face);
|
if (geom.num_points() > 0) // don't bother with empty geometries
|
||||||
|
|
||||||
string_info info(text);
|
|
||||||
|
|
||||||
face->get_string_info(sym.get_text_size(), info);
|
|
||||||
|
|
||||||
placement_finder<label_collision_detector4> finder(detector_);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < feature.num_geometries(); ++i)
|
|
||||||
{
|
{
|
||||||
geometry2d const& geom = feature.get_geometry(i);
|
path_type path(t_, geom, prj_trans);
|
||||||
|
placement text_placement(info, sym);
|
||||||
|
|
||||||
if (geom.num_points() > 0) // don't bother with empty geometries
|
if (sym.get_label_placement() == POINT_PLACEMENT)
|
||||||
{
|
{
|
||||||
path_type path(t_, geom, prj_trans);
|
double label_x, label_y, z = 0.0;
|
||||||
placement text_placement(info, sym);
|
|
||||||
|
|
||||||
if (sym.get_label_placement() == POINT_PLACEMENT)
|
geom.label_position(&label_x, &label_y);
|
||||||
{
|
prj_trans.backward(label_x, label_y, z);
|
||||||
double label_x, label_y, z = 0.0;
|
t_.forward(&label_x, &label_y);
|
||||||
|
finder.find_point_placement(text_placement, label_x, label_y);
|
||||||
|
}
|
||||||
|
else //LINE_PLACEMENT
|
||||||
|
{
|
||||||
|
finder.find_line_placements<path_type>(text_placement, path);
|
||||||
|
}
|
||||||
|
|
||||||
geom.label_position(&label_x, &label_y);
|
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii)
|
||||||
prj_trans.backward(label_x, label_y, z);
|
{
|
||||||
t_.forward(&label_x, &label_y);
|
context.add_text(sym, text_placement.placements[ii], face);
|
||||||
finder.find_point_placement(text_placement, label_x, label_y);
|
|
||||||
}
|
|
||||||
else //LINE_PLACEMENT
|
|
||||||
{
|
|
||||||
finder.find_line_placements<path_type>(text_placement, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii)
|
|
||||||
{
|
|
||||||
context.add_text(sym, text_placement.placements[ii], face);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
|
{
|
||||||
}
|
throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue