00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef CTRANS_HPP
00026 #define CTRANS_HPP
00027
00028 #include <mapnik/envelope.hpp>
00029 #include <mapnik/coord_array.hpp>
00030 #include <mapnik/proj_transform.hpp>
00031
00032 namespace mapnik {
00033 typedef coord_array<coord2d> CoordinateArray;
00034
00035 template <typename Transform,typename Geometry>
00036 struct MAPNIK_DECL coord_transform
00037 {
00038 coord_transform(Transform const& t, Geometry& geom)
00039 : t_(t), geom_(geom) {}
00040
00041 unsigned vertex(double *x , double *y) const
00042 {
00043 unsigned command = geom_.vertex(x,y);
00044 t_.forward(x,y);
00045 return command;
00046 }
00047
00048 void rewind (unsigned pos)
00049 {
00050 geom_.rewind(pos);
00051 }
00052
00053 private:
00054 Transform const& t_;
00055 Geometry& geom_;
00056 };
00057
00058 template <typename Transform,typename Geometry>
00059 struct MAPNIK_DECL coord_transform2
00060 {
00061 coord_transform2(Transform const& t,
00062 Geometry& geom,
00063 proj_transform const& prj_trans)
00064 : t_(t),
00065 geom_(geom),
00066 prj_trans_(prj_trans) {}
00067
00068 unsigned vertex(double * x , double * y) const
00069 {
00070 unsigned command = geom_.vertex(x,y);
00071 double z=0;
00072 prj_trans_.backward(*x,*y,z);
00073 t_.forward(x,y);
00074 return command;
00075 }
00076
00077 void rewind (unsigned pos)
00078 {
00079 geom_.rewind(pos);
00080 }
00081
00082 private:
00083 Transform const& t_;
00084 Geometry& geom_;
00085 proj_transform const& prj_trans_;
00086 };
00087
00088
00089 class CoordTransform
00090 {
00091 private:
00092 int width;
00093 int height;
00094 double scale_;
00095 Envelope<double> extent_;
00096 double offset_x_,offset_y_;
00097 public:
00098 CoordTransform(int width,int height,const Envelope<double>& extent,
00099 double offset_x = 0, double offset_y = 0)
00100 :width(width),height(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y)
00101 {
00102 double sx=((double)width)/extent_.width();
00103 double sy=((double)height)/extent_.height();
00104 scale_=std::min(sx,sy);
00105 }
00106
00107 inline double scale() const
00108 {
00109 return scale_;
00110 }
00111
00112 inline void forward(double * x, double * y) const
00113 {
00114
00115 *x = (*x - extent_.minx()) * scale_ - offset_x_;
00116 *y = (extent_.maxy() - *y) * scale_ - offset_y_;
00117 }
00118
00119 inline void backward(double * x, double * y) const
00120 {
00121 *x = extent_.minx() + (*x + offset_x_)/scale_;
00122 *y = extent_.maxy() - (*y + offset_y_)/scale_;
00123 }
00124
00125 inline coord2d& forward(coord2d& c) const
00126 {
00127 forward(&c.x,&c.y);
00128 return c;
00129 }
00130
00131 inline coord2d& backward(coord2d& c) const
00132 {
00133 backward(&c.x,&c.y);
00134 return c;
00135 }
00136
00137 inline Envelope<double> forward(const Envelope<double>& e) const
00138 {
00139 double x0 = e.minx();
00140 double y0 = e.miny();
00141 double x1 = e.maxx();
00142 double y1 = e.maxy();
00143 forward(&x0,&y0);
00144 forward(&x1,&y1);
00145 return Envelope<double>(x0,y0,x1,y1);
00146 }
00147
00148 inline Envelope<double> backward(const Envelope<double>& e) const
00149 {
00150 double x0 = e.minx();
00151 double y0 = e.miny();
00152 double x1 = e.maxx();
00153 double y1 = e.maxy();
00154 backward(&x0,&y0);
00155 backward(&x1,&y1);
00156 return Envelope<double>(x0,y0,x1,y1);
00157 }
00158
00159 inline CoordinateArray& forward(CoordinateArray& coords) const
00160 {
00161 for (unsigned i=0;i<coords.size();++i)
00162 {
00163 forward(coords[i]);
00164 }
00165 return coords;
00166 }
00167
00168 inline CoordinateArray& backward(CoordinateArray& coords) const
00169 {
00170 for (unsigned i=0;i<coords.size();++i)
00171 {
00172 backward(coords[i]);
00173 }
00174 return coords;
00175 }
00176 };
00177 }
00178
00179 #endif //CTRANS_HPP