]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/strategies/transform/map_transformer.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / strategies / transform / map_transformer.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
7// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
9
10// Use, modification and distribution is subject to the Boost Software License,
11// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12// http://www.boost.org/LICENSE_1_0.txt)
13
14#ifndef BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
15#define BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
16
17
18#include <cstddef>
19
20#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
21
22namespace boost { namespace geometry
23{
24
25// Silence warning C4127: conditional expression is constant
26#if defined(_MSC_VER)
27#pragma warning(push)
28#pragma warning(disable : 4127)
29#endif
30
31namespace strategy { namespace transform
32{
33
34/*!
35\brief Transformation strategy to map from one to another Cartesian coordinate system
36\ingroup strategies
37\tparam Mirror if true map is mirrored upside-down (in most cases pixels
38 are from top to bottom, while map is from bottom to top)
39 */
40template
41<
42 typename CalculationType,
43 std::size_t Dimension1,
44 std::size_t Dimension2,
45 bool Mirror = false,
46 bool SameScale = true
47>
48class map_transformer
49 : public ublas_transformer<CalculationType, Dimension1, Dimension2>
50{
51 typedef boost::numeric::ublas::matrix<CalculationType> M;
52
53public :
54 template <typename B, typename D>
55 explicit inline map_transformer(B const& box, D const& width, D const& height)
56 {
57 set_transformation(
58 get<min_corner, 0>(box), get<min_corner, 1>(box),
59 get<max_corner, 0>(box), get<max_corner, 1>(box),
60 width, height);
61 }
62
63 template <typename W, typename D>
64 explicit inline map_transformer(W const& wx1, W const& wy1, W const& wx2, W const& wy2,
65 D const& width, D const& height)
66 {
67 set_transformation(wx1, wy1, wx2, wy2, width, height);
68 }
69
70
71private :
72 template <typename W, typename P, typename S>
73 inline void set_transformation_point(W const& wx, W const& wy,
74 P const& px, P const& py,
75 S const& scalex, S const& scaley)
76 {
77
78 // Translate to a coordinate system centered on world coordinates (-wx, -wy)
79 M t1(3,3);
80 t1(0,0) = 1; t1(0,1) = 0; t1(0,2) = -wx;
81 t1(1,0) = 0; t1(1,1) = 1; t1(1,2) = -wy;
82 t1(2,0) = 0; t1(2,1) = 0; t1(2,2) = 1;
83
84 // Scale the map
85 M s(3,3);
86 s(0,0) = scalex; s(0,1) = 0; s(0,2) = 0;
87 s(1,0) = 0; s(1,1) = scaley; s(1,2) = 0;
88 s(2,0) = 0; s(2,1) = 0; s(2,2) = 1;
89
90 // Translate to a coordinate system centered on the specified pixels (+px, +py)
91 M t2(3, 3);
92 t2(0,0) = 1; t2(0,1) = 0; t2(0,2) = px;
93 t2(1,0) = 0; t2(1,1) = 1; t2(1,2) = py;
94 t2(2,0) = 0; t2(2,1) = 0; t2(2,2) = 1;
95
96 // Calculate combination matrix in two steps
97 this->m_matrix = boost::numeric::ublas::prod(s, t1);
98 this->m_matrix = boost::numeric::ublas::prod(t2, this->m_matrix);
99 }
100
101
102 template <typename W, typename D>
103 void set_transformation(W const& wx1, W const& wy1, W const& wx2, W const& wy2,
104 D const& width, D const& height)
105 {
106 D px1 = 0;
107 D py1 = 0;
108 D px2 = width;
109 D py2 = height;
110
111 // Get the same type, but at least a double
112 typedef typename select_most_precise<D, double>::type type;
113
114
115 // Calculate appropriate scale, take min because whole box must fit
116 // Scale is in PIXELS/MAPUNITS (meters)
117 W wdx = wx2 - wx1;
118 W wdy = wy2 - wy1;
119 type sx = (px2 - px1) / boost::numeric_cast<type>(wdx);
120 type sy = (py2 - py1) / boost::numeric_cast<type>(wdy);
121
122 if (SameScale)
123 {
124 type scale = (std::min)(sx, sy);
125 sx = scale;
126 sy = scale;
127 }
128
129 // Calculate centerpoints
130 W wtx = wx1 + wx2;
131 W wty = wy1 + wy2;
132 W two = 2;
133 W wmx = wtx / two;
134 W wmy = wty / two;
135 type pmx = (px1 + px2) / 2.0;
136 type pmy = (py1 + py2) / 2.0;
137
138 set_transformation_point(wmx, wmy, pmx, pmy, sx, sy);
139
140 if (Mirror)
141 {
142 // Mirror in y-direction
143 M m(3,3);
144 m(0,0) = 1; m(0,1) = 0; m(0,2) = 0;
145 m(1,0) = 0; m(1,1) = -1; m(1,2) = 0;
146 m(2,0) = 0; m(2,1) = 0; m(2,2) = 1;
147
148 // Translate in y-direction such that it fits again
149 M y(3, 3);
150 y(0,0) = 1; y(0,1) = 0; y(0,2) = 0;
151 y(1,0) = 0; y(1,1) = 1; y(1,2) = height;
152 y(2,0) = 0; y(2,1) = 0; y(2,2) = 1;
153
154 // Calculate combination matrix in two steps
155 this->m_matrix = boost::numeric::ublas::prod(m, this->m_matrix);
156 this->m_matrix = boost::numeric::ublas::prod(y, this->m_matrix);
157 }
158 }
159};
160
161
162}} // namespace strategy::transform
163
164#if defined(_MSC_VER)
165#pragma warning(pop)
166#endif
167
168}} // namespace boost::geometry
169
170
171#endif // BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP