summaryrefslogtreecommitdiff
path: root/boost/geometry/strategies/transform/map_transformer.hpp
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
commit1a78a62555be32868418fe52f8e330c9d0f95d5a (patch)
treed3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/geometry/strategies/transform/map_transformer.hpp
downloadboost-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.hpp165
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