]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/example/c11_custom_cs_transform_example.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / geometry / example / c11_custom_cs_transform_example.cpp
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 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Example: Custom coordinate system example, using transform
12
13 #include <iostream>
14
15 #include <boost/geometry/geometry.hpp>
16
17 // See also c10_custom_cs_example
18
19 // 1: declare, for example two cartesian coordinate systems
20 struct cart {};
21 struct cart_shifted5 {};
22
23 // 2: register to which coordinate system family they belong
24 namespace boost { namespace geometry { namespace traits
25 {
26
27 template<> struct cs_tag<cart> { typedef cartesian_tag type; };
28 template<> struct cs_tag<cart_shifted5> { typedef cartesian_tag type; };
29
30 }}} // namespaces
31
32
33 // 3: sample implementation of a shift
34 // to convert coordinate system "cart" to "cart_shirted5"
35 struct shift
36 {
37 template <typename P1, typename P2>
38 inline bool apply(P1 const& p1, P2& p2) const
39 {
40 namespace bg = boost::geometry;
41 bg::set<0>(p2, bg::get<0>(p1) + 5);
42 bg::set<1>(p2, bg::get<1>(p1));
43 return true;
44 }
45 };
46
47
48 // 4: register the default strategy to transform any cart point to any cart_shifted5 point
49 namespace boost { namespace geometry { namespace strategy { namespace transform { namespace services
50 {
51
52 template <typename P1, typename P2>
53 struct default_strategy<cartesian_tag, cartesian_tag, cart, cart_shifted5, 2, 2, P1, P2>
54 {
55 typedef shift type;
56 };
57
58 }}}}} // namespaces
59
60
61 // 5: implement a distance strategy between the two different ones
62 struct shift_and_calc_distance
63 {
64 template <typename P1, typename P2>
65 inline double apply(P1 const& p1, P2 const& p2) const
66 {
67 P2 p1_shifted;
68 boost::geometry::transform(p1, p1_shifted);
69 return boost::geometry::distance(p1_shifted, p2);
70 }
71 };
72
73 // 6: Define point types using this explicitly
74 typedef boost::geometry::model::point<double, 2, cart> point1;
75 typedef boost::geometry::model::point<double, 2, cart_shifted5> point2;
76
77 // 7: register the distance strategy
78 namespace boost { namespace geometry { namespace strategy { namespace distance { namespace services
79 {
80 template <>
81 struct tag<shift_and_calc_distance>
82 {
83 typedef strategy_tag_distance_point_point type;
84 };
85
86 template <typename P1, typename P2>
87 struct return_type<shift_and_calc_distance, P1, P2>
88 {
89 typedef double type;
90 };
91
92 template <>
93 struct default_strategy<point_tag, point_tag, point1, point2, cartesian_tag, cartesian_tag>
94 {
95 typedef shift_and_calc_distance type;
96 };
97
98
99 }}}}}
100
101
102
103 int main()
104 {
105 point1 p1_a(0, 0), p1_b(5, 5);
106 point2 p2_a(2, 2), p2_b(6, 6);
107
108 // Distances run for points on the same coordinate system.
109 // This is possible by default because they are cartesian coordinate systems.
110 double d1 = boost::geometry::distance(p1_a, p1_b);
111 double d2 = boost::geometry::distance(p2_a, p2_b);
112
113 std::cout << d1 << " " << d2 << std::endl;
114
115 // Transform from a to b:
116 boost::geometry::model::point<double, 2, cart_shifted5> p1_shifted;
117 boost::geometry::transform(p1_a, p1_shifted);
118
119
120 // Of course this can be calculated now, same CS
121 double d3 = boost::geometry::distance(p1_shifted, p2_a);
122
123
124 // Calculate distance between them. Note that inside distance the
125 // transformation is called.
126 double d4 = boost::geometry::distance(p1_a, p2_a);
127
128 // The result should be the same.
129 std::cout << d3 << " " << d4 << std::endl;
130
131 return 0;
132 }