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 const& 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 const& geom_;
00085 proj_transform const& prj_trans_;
00086 };
00087
00088 template <typename Transform,typename Geometry>
00089 struct MAPNIK_DECL coord_transform3
00090 {
00091 coord_transform3(Transform const& t,
00092 Geometry const& geom,
00093 proj_transform const& prj_trans,
00094 int dx, int dy)
00095 : t_(t),
00096 geom_(geom),
00097 prj_trans_(prj_trans),
00098 dx_(dx), dy_(dy) {}
00099
00100 unsigned vertex(double * x , double * y) const
00101 {
00102 unsigned command = geom_.vertex(x,y);
00103 double z=0;
00104 prj_trans_.backward(*x,*y,z);
00105 t_.forward(x,y);
00106 *x+=dx_;
00107 *y+=dy_;
00108 return command;
00109 }
00110
00111 void rewind (unsigned pos)
00112 {
00113 geom_.rewind(pos);
00114 }
00115
00116 private:
00117 Transform const& t_;
00118 Geometry const& geom_;
00119 proj_transform const& prj_trans_;
00120 int dx_;
00121 int dy_;
00122 };
00123
00124 class CoordTransform
00125 {
00126 private:
00127 int width;
00128 int height;
00129 double scale_;
00130 Envelope<double> extent_;
00131 double offset_x_;
00132 double offset_y_;
00133 public:
00134 CoordTransform(int width,int height,const Envelope<double>& extent,
00135 double offset_x = 0, double offset_y = 0)
00136 :width(width),height(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y)
00137 {
00138 double sx=((double)width)/extent_.width();
00139 double sy=((double)height)/extent_.height();
00140 scale_=std::min(sx,sy);
00141 }
00142
00143 inline double scale() const
00144 {
00145 return scale_;
00146 }
00147
00148 inline void forward(double * x, double * y) const
00149 {
00150 *x = (*x - extent_.minx()) * scale_ - offset_x_;
00151 *y = (extent_.maxy() - *y) * scale_ - offset_y_;
00152 }
00153
00154 inline void backward(double * x, double * y) const
00155 {
00156 *x = extent_.minx() + (*x + offset_x_)/scale_;
00157 *y = extent_.maxy() - (*y + offset_y_)/scale_;
00158 }
00159
00160 inline coord2d& forward(coord2d& c) const
00161 {
00162 forward(&c.x,&c.y);
00163 return c;
00164 }
00165
00166 inline coord2d& backward(coord2d& c) const
00167 {
00168 backward(&c.x,&c.y);
00169 return c;
00170 }
00171
00172 inline Envelope<double> forward(const Envelope<double>& e) const
00173 {
00174 double x0 = e.minx();
00175 double y0 = e.miny();
00176 double x1 = e.maxx();
00177 double y1 = e.maxy();
00178 forward(&x0,&y0);
00179 forward(&x1,&y1);
00180 return Envelope<double>(x0,y0,x1,y1);
00181 }
00182
00183 inline Envelope<double> backward(const Envelope<double>& e) const
00184 {
00185 double x0 = e.minx();
00186 double y0 = e.miny();
00187 double x1 = e.maxx();
00188 double y1 = e.maxy();
00189 backward(&x0,&y0);
00190 backward(&x1,&y1);
00191 return Envelope<double>(x0,y0,x1,y1);
00192 }
00193
00194 inline CoordinateArray& forward(CoordinateArray& coords) const
00195 {
00196 for (unsigned i=0;i<coords.size();++i)
00197 {
00198 forward(coords[i]);
00199 }
00200 return coords;
00201 }
00202
00203 inline CoordinateArray& backward(CoordinateArray& coords) const
00204 {
00205 for (unsigned i=0;i<coords.size();++i)
00206 {
00207 backward(coords[i]);
00208 }
00209 return coords;
00210 }
00211 inline Envelope<double> const& extent() const
00212 {
00213 return extent_;
00214 }
00215 };
00216 }
00217
00218 #endif //CTRANS_HPP