point_in_box_by_side.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. // This file was modified by Oracle on 2018.
  6. // Modifications copyright (c) 2018 Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  9. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  10. // Use, modification and distribution is subject to the Boost Software License,
  11. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. #ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
  14. #define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
  15. #include <boost/array.hpp>
  16. #include <boost/core/ignore_unused.hpp>
  17. #include <boost/geometry/core/access.hpp>
  18. #include <boost/geometry/core/coordinate_dimension.hpp>
  19. #include <boost/geometry/algorithms/assign.hpp>
  20. #include <boost/geometry/strategies/covered_by.hpp>
  21. #include <boost/geometry/strategies/side.hpp>
  22. #include <boost/geometry/strategies/within.hpp>
  23. namespace boost { namespace geometry { namespace strategy
  24. {
  25. namespace within
  26. {
  27. struct decide_within
  28. {
  29. static inline bool apply(int side, bool& result)
  30. {
  31. if (side != 1)
  32. {
  33. result = false;
  34. return false;
  35. }
  36. return true; // continue
  37. }
  38. };
  39. struct decide_covered_by
  40. {
  41. static inline bool apply(int side, bool& result)
  42. {
  43. if (side != 1)
  44. {
  45. result = side >= 0;
  46. return false;
  47. }
  48. return true; // continue
  49. }
  50. };
  51. // WARNING
  52. // This strategy is not suitable for boxes in non-cartesian CSes having edges
  53. // longer than 180deg because e.g. the SSF formula picks the side of the closer
  54. // longitude, so for long edges the side is the opposite.
  55. template <typename Decide = decide_within>
  56. struct point_in_box_by_side
  57. {
  58. template <typename Point, typename Box>
  59. static inline bool apply(Point const& point, Box const& box)
  60. {
  61. typedef typename strategy::side::services::default_strategy
  62. <
  63. typename cs_tag<Box>::type
  64. >::type side_strategy_type;
  65. // Create (counterclockwise) array of points, the fifth one closes it
  66. // Every point should be on the LEFT side (=1), or ON the border (=0),
  67. // So >= 1 or >= 0
  68. boost::array<typename point_type<Box>::type, 5> bp;
  69. geometry::detail::assign_box_corners_oriented<true>(box, bp);
  70. bp[4] = bp[0];
  71. bool result = true;
  72. side_strategy_type strategy;
  73. boost::ignore_unused(strategy);
  74. for (int i = 1; i < 5; i++)
  75. {
  76. int const side = strategy.apply(point, bp[i - 1], bp[i]);
  77. if (! Decide::apply(side, result))
  78. {
  79. return result;
  80. }
  81. }
  82. return result;
  83. }
  84. };
  85. } // namespace within
  86. }}} // namespace boost::geometry::strategy
  87. #endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP