c06_custom_polygon_example.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. // Custom Polygon Example
  10. #include <iostream>
  11. #include <boost/geometry/geometry.hpp>
  12. #include <boost/geometry/geometries/register/point.hpp>
  13. #include <boost/geometry/geometries/register/ring.hpp>
  14. struct my_point
  15. {
  16. my_point(double an_x = 0, double an_y = 0)
  17. : x(an_x)
  18. , y(an_y)
  19. {}
  20. double x, y;
  21. };
  22. struct my_ring : std::deque<my_point>
  23. {};
  24. // Define a struct of a polygon, having always two holes
  25. // (of course this can be implemented differently, usually
  26. // with a vector or deque, but it is just an exampe)
  27. struct my_polygon
  28. {
  29. // required for a polygon: an outer ring...
  30. my_ring boundary;
  31. // ... and a Boost.Range compatible inner ring collection
  32. boost::array<my_ring, 2> holes;
  33. // just for the sample
  34. std::string name;
  35. my_polygon(std::string const& n = "") : name(n) {}
  36. };
  37. // We can conveniently use macro's to register point and ring
  38. BOOST_GEOMETRY_REGISTER_POINT_2D(my_point, double, cs::cartesian, x, y)
  39. BOOST_GEOMETRY_REGISTER_RING(my_ring)
  40. // There is currently no registration macro for polygons
  41. // and besides that a boost::array<T,N> in a macro would
  42. // be very specific, so we show it "by hand":
  43. namespace boost { namespace geometry { namespace traits
  44. {
  45. template<> struct tag<my_polygon> { typedef polygon_tag type; };
  46. template<> struct ring_const_type<my_polygon> { typedef my_ring const& type; };
  47. template<> struct ring_mutable_type<my_polygon> { typedef my_ring& type; };
  48. template<> struct interior_const_type<my_polygon>
  49. {
  50. typedef boost::array<my_ring, 2> const& type;
  51. };
  52. template<> struct interior_mutable_type<my_polygon>
  53. {
  54. typedef boost::array<my_ring, 2>& type;
  55. };
  56. template<> struct exterior_ring<my_polygon>
  57. {
  58. static my_ring& get(my_polygon& p)
  59. {
  60. return p.boundary;
  61. }
  62. static my_ring const& get(my_polygon const& p)
  63. {
  64. return p.boundary;
  65. }
  66. };
  67. template<> struct interior_rings<my_polygon>
  68. {
  69. typedef boost::array<my_ring, 2> holes_type;
  70. static holes_type& get(my_polygon& p)
  71. {
  72. return p.holes;
  73. }
  74. static holes_type const& get(my_polygon const& p)
  75. {
  76. return p.holes;
  77. }
  78. };
  79. }}} // namespace boost::geometry::traits
  80. int main()
  81. {
  82. my_polygon p1("my polygon");
  83. // Fill it the my-way, triangle
  84. p1.boundary.push_back(my_point(2, 0));
  85. p1.boundary.push_back(my_point(1, 5));
  86. p1.boundary.push_back(my_point(7, 6));
  87. p1.boundary.push_back(my_point(2, 0));
  88. // Triangle
  89. p1.holes[0].push_back(my_point(2, 1));
  90. p1.holes[0].push_back(my_point(2.4, 2));
  91. p1.holes[0].push_back(my_point(1.9, 2));
  92. p1.holes[0].push_back(my_point(2, 1));
  93. // Box
  94. p1.holes[1].push_back(my_point(3, 3));
  95. p1.holes[1].push_back(my_point(4, 3));
  96. p1.holes[1].push_back(my_point(4, 4));
  97. p1.holes[1].push_back(my_point(3, 4));
  98. p1.holes[1].push_back(my_point(3, 3));
  99. std::cout << "Representation of " << p1.name << ": "
  100. << boost::geometry::dsv(p1) << std::endl;
  101. std::cout << "Area of " << p1.name << ": "
  102. << boost::geometry::area(p1) << std::endl;
  103. std::cout << "Perimeter of " << p1.name << ": "
  104. << boost::geometry::perimeter(p1) << std::endl;
  105. std::cout << "Centroid of " << p1.name << ": "
  106. << boost::geometry::dsv(boost::geometry::return_centroid<my_point>(p1)) << std::endl;
  107. return 0;
  108. }