/***************************************************************************** * * This file is part of Mapnik (c++ mapping toolkit) * * Copyright (C) 2006 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ //$Id: ctrans.hpp 39 2005-04-10 20:39:53Z pavlenko $ #ifndef CTRANS_HPP #define CTRANS_HPP #include #include namespace mapnik { typedef coord_array CoordinateArray; template struct MAPNIK_DECL coord_transform { coord_transform(Transform const& t, Geometry& geom) : t_(t), geom_(geom) {} unsigned vertex(double *x , double *y) const { unsigned command = geom_.vertex(x,y); t_.forward(x,y); return command; } void rewind (unsigned pos) { geom_.rewind(pos); } private: Transform const& t_; Geometry& geom_; }; class CoordTransform { private: int width; int height; double scale_; Envelope extent_; public: CoordTransform(int width,int height,const Envelope& extent) :width(width),height(height),extent_(extent) { double sx=((double)width)/extent_.width(); double sy=((double)height)/extent_.height(); scale_=std::min(sx,sy); } inline double scale() const { return scale_; } inline void forward(double * x, double * y) const { *x = (*x - extent_.minx()) * scale_; *y = (extent_.maxy() - *y) * scale_; } inline void backward(double * x, double * y) const { *x = extent_.minx() + *x/scale_; *y = extent_.maxy() - *y/scale_; } inline coord2d& forward(coord2d& c) const { forward(&c.x,&c.y); return c; } inline coord2d& backward(coord2d& c) const { backward(&c.x,&c.y); return c; } inline Envelope forward(const Envelope& e) const { double x0 = e.minx(); double y0 = e.miny(); double x1 = e.maxx(); double y1 = e.maxy(); forward(&x0,&y0); forward(&x1,&y1); return Envelope(x0,y0,x1,y1); } inline Envelope backward(const Envelope& e) const { double x0 = e.minx(); double y0 = e.miny(); double x1 = e.maxx(); double y1 = e.maxy(); backward(&x0,&y0); backward(&x1,&y1); return Envelope(x0,y0,x1,y1); } inline CoordinateArray& forward(CoordinateArray& coords) const { for (unsigned i=0;i