1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
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)
11 // Example: Custom coordinate system example, using transform
15 #include <boost/geometry/geometry.hpp>
17 // See also c10_custom_cs_example
19 // 1: declare, for example two cartesian coordinate systems
21 struct cart_shifted5
{};
23 // 2: register to which coordinate system family they belong
24 namespace boost
{ namespace geometry
{ namespace traits
27 template<> struct cs_tag
<cart
> { typedef cartesian_tag type
; };
28 template<> struct cs_tag
<cart_shifted5
> { typedef cartesian_tag type
; };
33 // 3: sample implementation of a shift
34 // to convert coordinate system "cart" to "cart_shirted5"
37 template <typename P1
, typename P2
>
38 inline bool apply(P1
const& p1
, P2
& p2
) const
40 namespace bg
= boost::geometry
;
41 bg::set
<0>(p2
, bg::get
<0>(p1
) + 5);
42 bg::set
<1>(p2
, bg::get
<1>(p1
));
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
52 template <typename P1
, typename P2
>
53 struct default_strategy
<cartesian_tag
, cartesian_tag
, cart
, cart_shifted5
, 2, 2, P1
, P2
>
61 // 5: implement a distance strategy between the two different ones
62 struct shift_and_calc_distance
64 template <typename P1
, typename P2
>
65 inline double apply(P1
const& p1
, P2
const& p2
) const
68 boost::geometry::transform(p1
, p1_shifted
);
69 return boost::geometry::distance(p1_shifted
, p2
);
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
;
77 // 7: register the distance strategy
78 namespace boost
{ namespace geometry
{ namespace strategy
{ namespace distance
{ namespace services
81 struct tag
<shift_and_calc_distance
>
83 typedef strategy_tag_distance_point_point type
;
86 template <typename P1
, typename P2
>
87 struct return_type
<shift_and_calc_distance
, P1
, P2
>
93 struct default_strategy
<point_tag
, point_tag
, point1
, point2
, cartesian_tag
, cartesian_tag
>
95 typedef shift_and_calc_distance type
;
105 point1
p1_a(0, 0), p1_b(5, 5);
106 point2
p2_a(2, 2), p2_b(6, 6);
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
);
113 std::cout
<< d1
<< " " << d2
<< std::endl
;
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
);
120 // Of course this can be calculated now, same CS
121 double d3
= boost::geometry::distance(p1_shifted
, p2_a
);
124 // Calculate distance between them. Note that inside distance the
125 // transformation is called.
126 double d4
= boost::geometry::distance(p1_a
, p2_a
);
128 // The result should be the same.
129 std::cout
<< d3
<< " " << d4
<< std::endl
;