remove_spikes.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
  5. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
  6. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
  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. #include <iostream>
  11. #include <iomanip>
  12. #include <string>
  13. // Instead of having a separate (and nearly similar) unit test to test multipolygons,
  14. // we now include them here and compile them by default. Only undefining the next line
  15. // will avoid testing multi-geometries
  16. #define BOOST_GEOMETRY_UNIT_TEST_MULTI
  17. #include <boost/variant/variant.hpp>
  18. #include <geometry_test_common.hpp>
  19. // The include to test
  20. #include <boost/geometry/algorithms/remove_spikes.hpp>
  21. // Helper includes
  22. #include <boost/geometry/algorithms/area.hpp>
  23. #include <boost/geometry/algorithms/correct.hpp>
  24. #include <boost/geometry/algorithms/perimeter.hpp>
  25. #include <boost/geometry/geometries/geometries.hpp>
  26. #include <boost/geometry/geometries/point_xy.hpp>
  27. #include <boost/geometry/io/wkt/wkt.hpp>
  28. #include <boost/geometry/strategies/strategies.hpp>
  29. #if defined(BOOST_GEOMETRY_UNIT_TEST_MULTI)
  30. # include <boost/geometry/geometries/multi_polygon.hpp>
  31. #endif
  32. #if defined(TEST_WITH_SVG)
  33. # include <boost/geometry/io/svg/svg_mapper.hpp>
  34. #endif
  35. template <typename Geometry>
  36. inline void test_remove_spikes(std::string const& /*id*/,
  37. Geometry& geometry,
  38. double expected_area, double expected_perimeter)
  39. {
  40. bg::remove_spikes(geometry);
  41. double detected_area = bg::area(geometry);
  42. double detected_perimeter = bg::perimeter(geometry);
  43. BOOST_CHECK_CLOSE(detected_area, expected_area, 0.01);
  44. BOOST_CHECK_CLOSE(detected_perimeter, expected_perimeter, 0.01);
  45. }
  46. template <typename Geometry>
  47. void test_geometry(std::string const& id, std::string const& wkt,
  48. double expected_area, double expected_perimeter)
  49. {
  50. Geometry geometry;
  51. bg::read_wkt(wkt, geometry);
  52. bg::correct(geometry);
  53. boost::variant<Geometry> v(geometry);
  54. #if defined(TEST_WITH_SVG)
  55. std::ostringstream filename;
  56. filename << "remove_spikes_" << id;
  57. if (! bg::closure<Geometry>::value)
  58. {
  59. filename << "_open";
  60. }
  61. filename << ".svg";
  62. std::ofstream svg(filename.str().c_str());
  63. bg::svg_mapper<typename bg::point_type<Geometry>::type> mapper(svg, 500, 500);
  64. mapper.add(geometry);
  65. mapper.map(geometry, "fill-opacity:0.3;opacity:0.6;fill:rgb(51,51,153);stroke:rgb(0,0,255);stroke-width:2");
  66. #endif
  67. test_remove_spikes(id, geometry, expected_area, expected_perimeter);
  68. test_remove_spikes(id, v, expected_area, expected_perimeter);
  69. #if defined(TEST_WITH_SVG)
  70. mapper.map(geometry, "opacity:0.6;fill:none;stroke:rgb(255,0,0);stroke-width:3");
  71. #endif
  72. }
  73. template <typename P, bool Clockwise, bool Closed>
  74. void test_polygons()
  75. {
  76. typedef bg::model::ring<P, Clockwise, Closed> ring;
  77. typedef bg::model::polygon<P, Clockwise, Closed> polygon;
  78. test_geometry<ring>("box",
  79. "POLYGON((0 0,0 4,4 4,4 0,0 0))",
  80. 16, 16);
  81. test_geometry<polygon>("box",
  82. "POLYGON((0 0,0 4,4 4,4 0,0 0))",
  83. 16, 16);
  84. test_geometry<polygon>("box2",
  85. "POLYGON((0 0,0 2,0 4,2 4,4 4,4 2,4 0,2 0,0 0))",
  86. 16, 16);
  87. test_geometry<polygon>("spike_right",
  88. "POLYGON((0 0,0 4,4 4,4 2,6 2,4 2,4 0,0 0))",
  89. 16, 16);
  90. test_geometry<polygon>("spike_at_corner",
  91. "POLYGON((0 0,0 4,6 4,4 4,4 0,0 0))",
  92. 16, 16);
  93. test_geometry<polygon>("spike_at_first",
  94. "POLYGON((0 0,-1 3,0 0,0 4,4 4,4 0,0 0))",
  95. 16, 16);
  96. test_geometry<polygon>("spike_at_last",
  97. "POLYGON((0 0,0 4,4 4,4 0,6 0,0 0))",
  98. 16, 16);
  99. test_geometry<polygon>("spike_at_closing",
  100. "POLYGON((-1 0,0 0,0 4,4 4,4 0,0 0,-1 0))",
  101. 16, 16);
  102. test_geometry<polygon>("double_spike",
  103. "POLYGON((0 0,0 4,4 4,4 2,6 2,5 2,4 2,4 0,0 0))",
  104. 16, 16);
  105. test_geometry<polygon>("three_double_spike",
  106. "POLYGON((0 0,0 4,4 4,4 2,6 2,5 2,4.5 2,4 2,4 0,0 0))",
  107. 16, 16);
  108. test_geometry<polygon>("spike_with_corner",
  109. "POLYGON((0 0,0 4,4 4,4 2,6 2,6 4,6 2,4 2,4 0,0 0))",
  110. 16, 16);
  111. test_geometry<polygon>("triangle0",
  112. "POLYGON((0 0,0 4,2 0,4 0,0 0))",
  113. 4, 6 + sqrt(20.0));
  114. test_geometry<polygon>("triangle1",
  115. "POLYGON((0 4,2 0,4 0,0 0,0 4))",
  116. 4, 6 + sqrt(20.0));
  117. test_geometry<polygon>("triangle2",
  118. "POLYGON((2 0,4 0,0 0,0 4,2 0))",
  119. 4, 6 + sqrt(20.0));
  120. test_geometry<polygon>("triangle3",
  121. "POLYGON((4 0,0 0,0 4,2 0,4 0))",
  122. 4, 6 + sqrt(20.0));
  123. test_geometry<polygon>("only_spike1",
  124. "POLYGON((0 0,2 2,0 0))",
  125. 0, 0);
  126. test_geometry<polygon>("only_spike2",
  127. "POLYGON((0 0,2 2,4 4,2 2,0 0))",
  128. 0, 0);
  129. test_geometry<polygon>("only_spike3",
  130. "POLYGON((0 0,2 2,4 4,0 0))",
  131. 0, 0);
  132. test_geometry<polygon>("only_spike4",
  133. "POLYGON((0 0,4 4,2 2,0 0))",
  134. 0, 0);
  135. }
  136. template <typename P, bool Clockwise, bool Closed>
  137. void test_multi_polygons()
  138. {
  139. typedef bg::model::polygon<P, Clockwise, Closed> polygon;
  140. typedef bg::model::multi_polygon<polygon> multi_polygon;
  141. test_geometry<multi_polygon>("multi_spike_with_corner",
  142. "MULTIPOLYGON(((0 0,0 4,4 4,4 2,6 2,6 4,6 2,4 2,4 0,0 0)))",
  143. 16, 16);
  144. }
  145. template <typename P, bool Clockwise, bool Closed>
  146. void test_all()
  147. {
  148. test_polygons<P, Clockwise, Closed>();
  149. test_multi_polygons<P, Clockwise, Closed>();
  150. }
  151. int test_main(int, char* [])
  152. {
  153. test_all<bg::model::d2::point_xy<double>, true, true>();
  154. test_all<bg::model::d2::point_xy<double>, true, false>();
  155. return 0;
  156. }