]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Boost.Geometry |
2 | ||
3 | // Copyright (c) 2018-2019 Barend Gehrels, Amsterdam, the Netherlands. | |
4 | ||
20effc67 TL |
5 | // This file was modified by Oracle on 2020. |
6 | // Modifications copyright (c) 2020 Oracle and/or its affiliates. | |
7 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle | |
8 | ||
92f5a8d4 TL |
9 | // Use, modification and distribution is subject to the Boost Software License, |
10 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
11 | // http://www.boost.org/LICENSE_1_0.txt) | |
12 | ||
13 | #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_POINT_CIRCLE_HPP | |
14 | #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_POINT_CIRCLE_HPP | |
15 | ||
16 | #include <cstddef> | |
17 | ||
20effc67 | 18 | #include <boost/range/value_type.hpp> |
92f5a8d4 TL |
19 | |
20 | #include <boost/geometry/util/math.hpp> | |
20effc67 | 21 | #include <boost/geometry/util/select_calculation_type.hpp> |
92f5a8d4 TL |
22 | |
23 | #include <boost/geometry/strategies/buffer.hpp> | |
24 | ||
25 | ||
26 | namespace boost { namespace geometry | |
27 | { | |
28 | ||
29 | namespace strategy { namespace buffer | |
30 | { | |
31 | ||
32 | /*! | |
33 | \brief Create a circular buffer around a point, on the Earth | |
34 | \ingroup strategies | |
35 | \details This strategy can be used as PointStrategy for the buffer algorithm. | |
36 | It creates a circular buffer around a point, on the Earth. It can be applied | |
37 | for points and multi_points. | |
38 | ||
39 | \qbk{ | |
40 | [heading Example] | |
41 | [buffer_geographic_point_circle] | |
42 | [buffer_geographic_point_circle_output] | |
43 | [heading See also] | |
44 | \* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)] | |
45 | \* [link geometry.reference.strategies.strategy_buffer_point_circle point_circle] | |
46 | \* [link geometry.reference.strategies.strategy_buffer_point_square point_square] | |
47 | } | |
48 | */ | |
49 | template | |
50 | < | |
51 | typename FormulaPolicy = strategy::andoyer, | |
52 | typename Spheroid = srs::spheroid<double>, | |
53 | typename CalculationType = void | |
54 | > | |
55 | class geographic_point_circle | |
56 | { | |
57 | public : | |
58 | //! \brief Constructs the strategy | |
59 | //! \param count number of points for the created circle (if count | |
60 | //! is smaller than 3, count is internally set to 3) | |
61 | explicit geographic_point_circle(std::size_t count = 90) | |
62 | : m_count((count < 3u) ? 3u : count) | |
63 | {} | |
64 | ||
65 | #ifndef DOXYGEN_SHOULD_SKIP_THIS | |
66 | //! Fills output_range with a circle around point using distance_strategy | |
67 | template | |
68 | < | |
69 | typename Point, | |
70 | typename OutputRange, | |
71 | typename DistanceStrategy | |
72 | > | |
73 | inline void apply(Point const& point, | |
74 | DistanceStrategy const& distance_strategy, | |
75 | OutputRange& output_range) const | |
76 | { | |
77 | typedef typename boost::range_value<OutputRange>::type output_point_type; | |
78 | ||
20effc67 | 79 | typedef typename select_calculation_type |
92f5a8d4 | 80 | < |
20effc67 | 81 | Point, output_point_type, |
92f5a8d4 TL |
82 | CalculationType |
83 | //double | |
84 | >::type calculation_type; | |
85 | ||
86 | calculation_type const buffer_distance = distance_strategy.apply(point, point, | |
87 | strategy::buffer::buffer_side_left); | |
88 | ||
89 | typedef typename FormulaPolicy::template direct | |
90 | < | |
91 | calculation_type, true, false, false, false | |
92 | > direct_t; | |
93 | ||
94 | calculation_type const two_pi = geometry::math::two_pi<calculation_type>(); | |
95 | calculation_type const pi = geometry::math::pi<calculation_type>(); | |
96 | ||
97 | calculation_type const diff = two_pi / calculation_type(m_count); | |
98 | // TODO: after calculation of some angles is corrected, | |
99 | // we can start at 0.0 | |
100 | calculation_type angle = 0.001; | |
101 | ||
102 | for (std::size_t i = 0; i < m_count; i++, angle += diff) | |
103 | { | |
104 | if (angle > pi) | |
105 | { | |
106 | angle -= two_pi; | |
107 | } | |
108 | ||
109 | typename direct_t::result_type | |
110 | dir_r = direct_t::apply(get_as_radian<0>(point), get_as_radian<1>(point), | |
111 | buffer_distance, angle, | |
112 | m_spheroid); | |
113 | output_point_type p; | |
114 | set_from_radian<0>(p, dir_r.lon2); | |
115 | set_from_radian<1>(p, dir_r.lat2); | |
116 | output_range.push_back(p); | |
117 | } | |
118 | ||
119 | { | |
120 | // Close the range | |
121 | const output_point_type p = output_range.front(); | |
122 | output_range.push_back(p); | |
123 | } | |
124 | } | |
125 | #endif // DOXYGEN_SHOULD_SKIP_THIS | |
126 | ||
127 | private : | |
128 | std::size_t m_count; | |
129 | Spheroid m_spheroid; | |
130 | }; | |
131 | ||
132 | ||
133 | }} // namespace strategy::buffer | |
134 | ||
135 | }} // namespace boost::geometry | |
136 | ||
137 | #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_POINT_CIRCLE_HPP |