diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index d4089e38c..c12decd39 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -251,6 +251,58 @@ public: *y=y0; } + void middle_point(double *x, double *y) const + { + // calculate mid point on path + double x0=0; + double y0=0; + double x1=0; + double y1=0; + + unsigned size = cont_.size(); + if (size == 1) + { + cont_.get_vertex(0,x,y); + } + else if (size == 2) + { + cont_.get_vertex(0,&x0,&y0); + cont_.get_vertex(1,&x1,&y1); + *x = 0.5 * (x1 + x0); + *y = 0.5 * (y1 + y0); + } + else + { + double len=0.0; + for (unsigned pos = 1; pos < size; ++pos) + { + cont_.get_vertex(pos-1,&x0,&y0); + cont_.get_vertex(pos,&x1,&y1); + double dx = x1 - x0; + double dy = y1 - y0; + len += std::sqrt(dx * dx + dy * dy); + } + double midlen = 0.5 * len; + double dist = 0.0; + for (unsigned pos = 1; pos < size;++pos) + { + cont_.get_vertex(pos-1,&x0,&y0); + cont_.get_vertex(pos,&x1,&y1); + double dx = x1 - x0; + double dy = y1 - y0; + double seg_len = std::sqrt(dx * dx + dy * dy); + if (( dist + seg_len) >= midlen) + { + double r = (midlen - dist)/seg_len; + *x = x0 + (x1 - x0) * r; + *y = y0 + (y1 - y0) * r; + break; + } + dist += seg_len; + } + } + } + void line_to(value_type x,value_type y) { cont_.push_back(x,y,SEG_LINETO); diff --git a/src/agg/process_shield_symbolizer.cpp b/src/agg/process_shield_symbolizer.cpp index b95793c99..58f34688e 100644 --- a/src/agg/process_shield_symbolizer.cpp +++ b/src/agg/process_shield_symbolizer.cpp @@ -154,7 +154,8 @@ void agg_renderer::process(shield_symbolizer const& sym, if( how_placed == VERTEX_PLACEMENT ) geom.vertex(&label_x,&label_y); // by vertex else - geom.label_position(&label_x, &label_y); // by middle of line or by point + geom.middle_point(&label_x, &label_y); // by middle of line + prj_trans.backward(label_x,label_y, z); t_.forward(&label_x,&label_y);