diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/geometry/strategies/transform/map_transformer.hpp | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'boost/geometry/strategies/transform/map_transformer.hpp')
-rw-r--r-- | boost/geometry/strategies/transform/map_transformer.hpp | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/boost/geometry/strategies/transform/map_transformer.hpp b/boost/geometry/strategies/transform/map_transformer.hpp new file mode 100644 index 0000000000..150ff1de9b --- /dev/null +++ b/boost/geometry/strategies/transform/map_transformer.hpp @@ -0,0 +1,165 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP +#define BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP + + +#include <cstddef> + +#include <boost/geometry/strategies/transform/matrix_transformers.hpp> + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace transform +{ + +/*! +\brief Transformation strategy to do map from one to another Cartesian system +\ingroup strategies +\tparam P1 first point type +\tparam P2 second point type +\tparam Mirror if true map is mirrored upside-down (in most cases pixels + are from top to bottom, while map is from bottom to top) + */ +template +< + typename P1, typename P2, + bool Mirror = false, bool SameScale = true, + std::size_t Dimension1 = dimension<P1>::type::value, + std::size_t Dimension2 = dimension<P2>::type::value +> +class map_transformer + : public ublas_transformer<P1, P2, Dimension1, Dimension2> +{ + typedef typename select_coordinate_type<P1, P2>::type T; + typedef boost::numeric::ublas::matrix<T> M; + +public : + template <typename B, typename D> + explicit inline map_transformer(B const& box, D const& width, D const& height) + { + set_transformation( + get<min_corner, 0>(box), get<min_corner, 1>(box), + get<max_corner, 0>(box), get<max_corner, 1>(box), + width, height); + } + + template <typename W, typename D> + explicit inline map_transformer(W const& wx1, W const& wy1, W const& wx2, W const& wy2, + D const& width, D const& height) + { + set_transformation(wx1, wy1, wx2, wy2, width, height); + } + + +private : + template <typename W, typename P, typename S> + inline void set_transformation_point(W const& wx, W const& wy, + P const& px, P const& py, + S const& scalex, S const& scaley) + { + + // Translate to a coordinate system centered on world coordinates (-wx, -wy) + M t1(3,3); + t1(0,0) = 1; t1(0,1) = 0; t1(0,2) = -wx; + t1(1,0) = 0; t1(1,1) = 1; t1(1,2) = -wy; + t1(2,0) = 0; t1(2,1) = 0; t1(2,2) = 1; + + // Scale the map + M s(3,3); + s(0,0) = scalex; s(0,1) = 0; s(0,2) = 0; + s(1,0) = 0; s(1,1) = scaley; s(1,2) = 0; + s(2,0) = 0; s(2,1) = 0; s(2,2) = 1; + + // Translate to a coordinate system centered on the specified pixels (+px, +py) + M t2(3, 3); + t2(0,0) = 1; t2(0,1) = 0; t2(0,2) = px; + t2(1,0) = 0; t2(1,1) = 1; t2(1,2) = py; + t2(2,0) = 0; t2(2,1) = 0; t2(2,2) = 1; + + // Calculate combination matrix in two steps + this->m_matrix = boost::numeric::ublas::prod(s, t1); + this->m_matrix = boost::numeric::ublas::prod(t2, this->m_matrix); + } + + + template <typename W, typename D> + void set_transformation(W const& wx1, W const& wy1, W const& wx2, W const& wy2, + D const& width, D const& height) + { + D px1 = 0; + D py1 = 0; + D px2 = width; + D py2 = height; + + // Get the same type, but at least a double + typedef typename select_most_precise<D, double>::type type; + + + // Calculate appropriate scale, take min because whole box must fit + // Scale is in PIXELS/MAPUNITS (meters) + W wdx = wx2 - wx1; + W wdy = wy2 - wy1; + type sx = (px2 - px1) / boost::numeric_cast<type>(wdx); + type sy = (py2 - py1) / boost::numeric_cast<type>(wdy); + + if (SameScale) + { + type scale = (std::min)(sx, sy); + sx = scale; + sy = scale; + } + + // Calculate centerpoints + W wtx = wx1 + wx2; + W wty = wy1 + wy2; + W two = 2; + W wmx = wtx / two; + W wmy = wty / two; + type pmx = (px1 + px2) / 2.0; + type pmy = (py1 + py2) / 2.0; + + set_transformation_point(wmx, wmy, pmx, pmy, sx, sy); + + if (Mirror) + { + // Mirror in y-direction + M m(3,3); + m(0,0) = 1; m(0,1) = 0; m(0,2) = 0; + m(1,0) = 0; m(1,1) = -1; m(1,2) = 0; + m(2,0) = 0; m(2,1) = 0; m(2,2) = 1; + + // Translate in y-direction such that it fits again + M y(3, 3); + y(0,0) = 1; y(0,1) = 0; y(0,2) = 0; + y(1,0) = 0; y(1,1) = 1; y(1,2) = height; + y(2,0) = 0; y(2,1) = 0; y(2,2) = 1; + + // Calculate combination matrix in two steps + this->m_matrix = boost::numeric::ublas::prod(m, this->m_matrix); + this->m_matrix = boost::numeric::ublas::prod(y, this->m_matrix); + } + } +}; + + +}} // namespace strategy::transform + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP |