c11_custom_cs_transform_example.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Use, modification and distribution is subject to the Boost Software License,
  6. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // Example: Custom coordinate system example, using transform
  10. #include <iostream>
  11. #include <boost/geometry/geometry.hpp>
  12. // See also c10_custom_cs_example
  13. // 1: declare, for example two cartesian coordinate systems
  14. struct cart {};
  15. struct cart_shifted5 {};
  16. // 2: register to which coordinate system family they belong
  17. namespace boost { namespace geometry { namespace traits
  18. {
  19. template<> struct cs_tag<cart> { typedef cartesian_tag type; };
  20. template<> struct cs_tag<cart_shifted5> { typedef cartesian_tag type; };
  21. }}} // namespaces
  22. // 3: sample implementation of a shift
  23. // to convert coordinate system "cart" to "cart_shirted5"
  24. struct shift
  25. {
  26. template <typename P1, typename P2>
  27. inline bool apply(P1 const& p1, P2& p2) const
  28. {
  29. namespace bg = boost::geometry;
  30. bg::set<0>(p2, bg::get<0>(p1) + 5);
  31. bg::set<1>(p2, bg::get<1>(p1));
  32. return true;
  33. }
  34. };
  35. // 4: register the default strategy to transform any cart point to any cart_shifted5 point
  36. namespace boost { namespace geometry { namespace strategy { namespace transform { namespace services
  37. {
  38. template <typename P1, typename P2>
  39. struct default_strategy<cartesian_tag, cartesian_tag, cart, cart_shifted5, 2, 2, P1, P2>
  40. {
  41. typedef shift type;
  42. };
  43. }}}}} // namespaces
  44. // 5: implement a distance strategy between the two different ones
  45. struct shift_and_calc_distance
  46. {
  47. template <typename P1, typename P2>
  48. inline double apply(P1 const& p1, P2 const& p2) const
  49. {
  50. P2 p1_shifted;
  51. boost::geometry::transform(p1, p1_shifted);
  52. return boost::geometry::distance(p1_shifted, p2);
  53. }
  54. };
  55. // 6: Define point types using this explicitly
  56. typedef boost::geometry::model::point<double, 2, cart> point1;
  57. typedef boost::geometry::model::point<double, 2, cart_shifted5> point2;
  58. // 7: register the distance strategy
  59. namespace boost { namespace geometry { namespace strategy { namespace distance { namespace services
  60. {
  61. template <>
  62. struct tag<shift_and_calc_distance>
  63. {
  64. typedef strategy_tag_distance_point_point type;
  65. };
  66. template <typename P1, typename P2>
  67. struct return_type<shift_and_calc_distance, P1, P2>
  68. {
  69. typedef double type;
  70. };
  71. template <>
  72. struct default_strategy<point_tag, point_tag, point1, point2, cartesian_tag, cartesian_tag>
  73. {
  74. typedef shift_and_calc_distance type;
  75. };
  76. }}}}}
  77. int main()
  78. {
  79. point1 p1_a(0, 0), p1_b(5, 5);
  80. point2 p2_a(2, 2), p2_b(6, 6);
  81. // Distances run for points on the same coordinate system.
  82. // This is possible by default because they are cartesian coordinate systems.
  83. double d1 = boost::geometry::distance(p1_a, p1_b);
  84. double d2 = boost::geometry::distance(p2_a, p2_b);
  85. std::cout << d1 << " " << d2 << std::endl;
  86. // Transform from a to b:
  87. boost::geometry::model::point<double, 2, cart_shifted5> p1_shifted;
  88. boost::geometry::transform(p1_a, p1_shifted);
  89. // Of course this can be calculated now, same CS
  90. double d3 = boost::geometry::distance(p1_shifted, p2_a);
  91. // Calculate distance between them. Note that inside distance the
  92. // transformation is called.
  93. double d4 = boost::geometry::distance(p1_a, p2_a);
  94. // The result should be the same.
  95. std::cout << d3 << " " << d4 << std::endl;
  96. return 0;
  97. }