Merge branch 'master' of github.com:mapnik/mapnik
This commit is contained in:
commit
39accb234f
1 changed files with 228 additions and 2 deletions
|
@ -24,13 +24,21 @@
|
|||
#ifndef CTRANS_HPP
|
||||
#define CTRANS_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/coord_array.hpp>
|
||||
#include <mapnik/proj_transform.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
|
||||
// stl
|
||||
#include <algorithm>
|
||||
|
||||
const double pi = boost::math::constants::pi<double>();
|
||||
const double pi_by_2 = pi/2.0;
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
|
@ -150,6 +158,224 @@ private:
|
|||
};
|
||||
|
||||
|
||||
// TODO - expose this and make chainable
|
||||
template <typename Transform,typename Geometry>
|
||||
struct MAPNIK_DECL coord_transform_parallel
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
typedef typename Geometry::value_type value_type;
|
||||
|
||||
coord_transform_parallel(Transform const& t,
|
||||
Geometry const& geom,
|
||||
proj_transform const& prj_trans )
|
||||
: t_(t),
|
||||
geom_(geom),
|
||||
prj_trans_(prj_trans),
|
||||
offset_(0.0),
|
||||
threshold_(10),
|
||||
m_status(initial) {}
|
||||
|
||||
enum status
|
||||
{
|
||||
initial,
|
||||
start,
|
||||
first,
|
||||
process,
|
||||
last_vertex,
|
||||
angle_joint,
|
||||
end
|
||||
};
|
||||
|
||||
double get_offset() const
|
||||
{
|
||||
return offset_;
|
||||
}
|
||||
|
||||
void set_offset(double offset)
|
||||
{
|
||||
offset_ = offset;
|
||||
}
|
||||
|
||||
unsigned int get_threshold() const
|
||||
{
|
||||
return threshold_;
|
||||
}
|
||||
|
||||
void set_threshold(unsigned int t)
|
||||
{
|
||||
threshold_ = t;
|
||||
}
|
||||
|
||||
unsigned vertex(double * x , double * y)
|
||||
{
|
||||
double z=0;
|
||||
|
||||
if (offset_==0.0)
|
||||
{
|
||||
unsigned command = geom_.vertex(x,y);
|
||||
prj_trans_.backward(*x,*y,z);
|
||||
t_.forward(x,y);
|
||||
return command;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(true){
|
||||
switch(m_status)
|
||||
{
|
||||
case end:
|
||||
return SEG_END;
|
||||
break;
|
||||
case initial:
|
||||
m_pre_cmd = geom_.vertex(x,y);
|
||||
prj_trans_.backward(*x,*y,z);
|
||||
t_.forward(x,y);
|
||||
m_pre_x = *x;
|
||||
m_pre_y = *y;
|
||||
//m_status = (m_pre_cmd!=SEG_END)?start:end; //
|
||||
case start:
|
||||
m_cur_cmd = geom_.vertex(&m_cur_x, &m_cur_y);
|
||||
prj_trans_.backward(m_cur_x,m_cur_y,z);
|
||||
t_.forward(&m_cur_x,&m_cur_y);
|
||||
case first:
|
||||
angle_a = atan2((m_pre_y-m_cur_y),(m_pre_x-m_cur_x));
|
||||
dx_pre = cos(angle_a + pi_by_2);
|
||||
dy_pre = sin(angle_a + pi_by_2);
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "offsetting line by: " << offset_ << "\n";
|
||||
std::clog << "initial dx=" << (dx_pre * offset_) << " dy=" << (dy_pre * offset_) << "\n";
|
||||
#endif
|
||||
*x = m_pre_x + (dx_pre * offset_);
|
||||
*y = m_pre_y + (dy_pre * offset_);
|
||||
m_status = process;
|
||||
return SEG_MOVETO;
|
||||
case process:
|
||||
switch(m_cur_cmd)
|
||||
{
|
||||
case SEG_LINETO:
|
||||
m_next_cmd = geom_.vertex(&m_next_x, &m_next_y);
|
||||
prj_trans_.backward(m_next_x,m_next_y,z);
|
||||
t_.forward(&m_next_x,&m_next_y);
|
||||
switch(m_next_cmd)
|
||||
{
|
||||
case SEG_LINETO:
|
||||
m_status = angle_joint;
|
||||
break;
|
||||
default:
|
||||
m_status = last_vertex;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SEG_END:
|
||||
m_status = end;
|
||||
return SEG_END;
|
||||
}
|
||||
break;
|
||||
case last_vertex:
|
||||
dx_curr = cos(angle_a + pi_by_2);
|
||||
dy_curr = sin(angle_a + pi_by_2);
|
||||
*x = m_cur_x + (dx_curr * offset_);
|
||||
*y = m_cur_y + (dy_curr * offset_);
|
||||
m_status = end;
|
||||
return m_cur_cmd;
|
||||
case angle_joint:
|
||||
angle_b = atan2((m_cur_y-m_next_y),(m_cur_x-m_next_x));
|
||||
h = tan((angle_b - angle_a)/2.0);
|
||||
|
||||
if (fabs(h) < threshold_)
|
||||
{
|
||||
dx_curr = cos(angle_a + pi_by_2);
|
||||
dy_curr = sin(angle_a + pi_by_2);
|
||||
*x = m_cur_x + (dx_curr * offset_) - h * (dy_curr * offset_);
|
||||
*y = m_cur_y + (dy_curr * offset_) + h * (dx_curr * offset_);
|
||||
}
|
||||
else // skip sharp spikes
|
||||
{
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
dx_curr = cos(angle_a + pi_by_2);
|
||||
dy_curr = sin(angle_a + pi_by_2);
|
||||
sin_curve = dx_curr*dy_pre-dy_curr*dx_pre;
|
||||
std::clog << "angle a: " << angle_a << "\n";
|
||||
std::clog << "angle b: " << angle_b << "\n";
|
||||
std::clog << "h: " << h << "\n";
|
||||
std::clog << "sin_curve: " << sin_curve << "\n";
|
||||
#endif
|
||||
m_status = process;
|
||||
break;
|
||||
}
|
||||
|
||||
// alternate sharp spike fix, but suboptimal...
|
||||
|
||||
/*
|
||||
sin_curve = dx_curr*dy_pre-dy_curr*dx_pre;
|
||||
cos_curve = -dx_pre*dx_curr-dy_pre*dy_curr;
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "sin_curve value: " << sin_curve << "\n";
|
||||
#endif
|
||||
if(sin_curve > -0.3 && sin_curve < 0.3) {
|
||||
angle_b = atan2((m_cur_y-m_next_y),(m_cur_x-m_next_x));
|
||||
h = tan((angle_b - angle_a)/2.0);
|
||||
*x = m_cur_x + (dx_curr * offset_) - h * (dy_curr * offset_);
|
||||
*y = m_cur_y + (dy_curr * offset_) + h * (dx_curr * offset_);
|
||||
} else {
|
||||
if (angle_b - angle_a > 0)
|
||||
h = -1.0*(1.0+cos_curve)/sin_curve;
|
||||
else
|
||||
h = (1.0+cos_curve)/sin_curve;
|
||||
*x = m_cur_x + (dx_curr + base_shift*dy_curr)*offset_;
|
||||
*y = m_cur_y + (dy_curr - base_shift*dx_curr)*offset_;
|
||||
}
|
||||
*/
|
||||
|
||||
m_pre_x = *x;
|
||||
m_pre_x = *y;
|
||||
m_cur_x = m_next_x;
|
||||
m_cur_y = m_next_y;
|
||||
angle_a = angle_b;
|
||||
m_pre_cmd = m_cur_cmd;
|
||||
m_cur_cmd = m_next_cmd;
|
||||
m_status = process;
|
||||
return m_pre_cmd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rewind (unsigned pos)
|
||||
{
|
||||
geom_.rewind(pos);
|
||||
m_status = initial;
|
||||
}
|
||||
|
||||
private:
|
||||
Transform const& t_;
|
||||
Geometry const& geom_;
|
||||
proj_transform const& prj_trans_;
|
||||
int offset_;
|
||||
unsigned int threshold_;
|
||||
status m_status;
|
||||
double dx_pre;
|
||||
double dy_pre;
|
||||
double dx_curr;
|
||||
double dy_curr;
|
||||
double sin_curve;
|
||||
double cos_curve;
|
||||
double angle_a;
|
||||
double angle_b;
|
||||
double h;
|
||||
unsigned m_pre_cmd;
|
||||
double m_pre_x;
|
||||
double m_pre_y;
|
||||
unsigned m_cur_cmd;
|
||||
double m_cur_x;
|
||||
double m_cur_y;
|
||||
unsigned m_next_cmd;
|
||||
double m_next_x;
|
||||
double m_next_y;
|
||||
};
|
||||
|
||||
|
||||
class CoordTransform
|
||||
{
|
||||
private:
|
||||
|
|
Loading…
Reference in a new issue