03_polygon_example.cpp 4.8 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. // Polygon Example
  10. #include <algorithm> // for reverse, unique
  11. #include <iostream>
  12. #include <string>
  13. #include <boost/geometry/geometry.hpp>
  14. #include <boost/geometry/geometries/point_xy.hpp>
  15. #include <boost/geometry/geometries/polygon.hpp>
  16. #include <boost/geometry/geometries/adapted/c_array.hpp>
  17. #include <boost/geometry/geometries/multi_polygon.hpp>
  18. BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
  19. std::string boolstr(bool v)
  20. {
  21. return v ? "true" : "false";
  22. }
  23. int main(void)
  24. {
  25. using namespace boost::geometry;
  26. typedef model::d2::point_xy<double> point_2d;
  27. typedef model::polygon<point_2d> polygon_2d;
  28. typedef model::box<point_2d> box_2d;
  29. // Define a polygon and fill the outer ring.
  30. // In most cases you will read it from a file or database
  31. polygon_2d poly;
  32. {
  33. const double coor[][2] = {
  34. {2.0, 1.3}, {2.4, 1.7}, {2.8, 1.8}, {3.4, 1.2}, {3.7, 1.6},
  35. {3.4, 2.0}, {4.1, 3.0}, {5.3, 2.6}, {5.4, 1.2}, {4.9, 0.8}, {2.9, 0.7},
  36. {2.0, 1.3} // closing point is opening point
  37. };
  38. assign_points(poly, coor);
  39. }
  40. // Polygons should be closed, and directed clockwise. If you're not sure if that is the case,
  41. // call the correct algorithm
  42. correct(poly);
  43. // Polygons can be streamed as text
  44. // (or more precisely: as DSV (delimiter separated values))
  45. std::cout << dsv(poly) << std::endl;
  46. // As with lines, bounding box of polygons can be calculated
  47. box_2d b;
  48. envelope(poly, b);
  49. std::cout << dsv(b) << std::endl;
  50. // The area of the polygon can be calulated
  51. std::cout << "area: " << area(poly) << std::endl;
  52. // And the centroid, which is the center of gravity
  53. point_2d cent;
  54. centroid(poly, cent);
  55. std::cout << "centroid: " << dsv(cent) << std::endl;
  56. // The number of points can be requested per ring (using .size())
  57. // or per polygon (using num_points)
  58. std::cout << "number of points in outer ring: " << poly.outer().size() << std::endl;
  59. // Polygons can have one or more inner rings, also called holes, islands, interior rings.
  60. // Let's add one
  61. {
  62. poly.inners().resize(1);
  63. model::ring<point_2d>& inner = poly.inners().back();
  64. const double coor[][2] = { {4.0, 2.0}, {4.2, 1.4}, {4.8, 1.9}, {4.4, 2.2}, {4.0, 2.0} };
  65. assign_points(inner, coor);
  66. }
  67. correct(poly);
  68. std::cout << "with inner ring:" << dsv(poly) << std::endl;
  69. // The area of the polygon is changed of course
  70. std::cout << "new area of polygon: " << area(poly) << std::endl;
  71. centroid(poly, cent);
  72. std::cout << "new centroid: " << dsv(cent) << std::endl;
  73. // You can test whether points are within a polygon
  74. std::cout << "point in polygon:"
  75. << " p1: " << boolstr(within(make<point_2d>(3.0, 2.0), poly))
  76. << " p2: " << boolstr(within(make<point_2d>(3.7, 2.0), poly))
  77. << " p3: " << boolstr(within(make<point_2d>(4.4, 2.0), poly))
  78. << std::endl;
  79. // As with linestrings and points, you can derive from polygon to add, for example,
  80. // fill color and stroke color. Or SRID (spatial reference ID). Or Z-value. Or a property map.
  81. // We don't show this here.
  82. // Clip the polygon using a box
  83. box_2d cb(make<point_2d>(1.5, 1.5), make<point_2d>(4.5, 2.5));
  84. typedef std::vector<polygon_2d> polygon_list;
  85. polygon_list v;
  86. intersection(cb, poly, v);
  87. std::cout << "Clipped output polygons" << std::endl;
  88. for (polygon_list::const_iterator it = v.begin(); it != v.end(); ++it)
  89. {
  90. std::cout << dsv(*it) << std::endl;
  91. }
  92. typedef model::multi_polygon<polygon_2d> polygon_set;
  93. polygon_set ps;
  94. union_(cb, poly, ps);
  95. polygon_2d hull;
  96. convex_hull(poly, hull);
  97. std::cout << "Convex hull:" << dsv(hull) << std::endl;
  98. // If you really want:
  99. // You don't have to use a vector, you can define a polygon with a deque
  100. // You can specify the container for the points and for the inner rings independantly
  101. typedef model::polygon<point_2d, true, true, std::deque, std::deque> deque_polygon;
  102. deque_polygon poly2;
  103. ring_type<deque_polygon>::type& ring = exterior_ring(poly2);
  104. append(ring, make<point_2d>(2.8, 1.9));
  105. append(ring, make<point_2d>(2.9, 2.4));
  106. append(ring, make<point_2d>(3.3, 2.2));
  107. append(ring, make<point_2d>(3.2, 1.8));
  108. append(ring, make<point_2d>(2.8, 1.9));
  109. std::cout << dsv(poly2) << std::endl;
  110. return 0;
  111. }