]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry Index |
2 | // | |
3 | // R-tree spatial query visitor implementation | |
4 | // | |
5 | // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. | |
6 | // | |
1e59de90 TL |
7 | // This file was modified by Oracle on 2019-2021. |
8 | // Modifications copyright (c) 2019-2021 Oracle and/or its affiliates. | |
92f5a8d4 TL |
9 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle |
10 | // | |
7c673cae FG |
11 | // Use, modification and distribution is subject to the Boost Software License, |
12 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
13 | // http://www.boost.org/LICENSE_1_0.txt) | |
14 | ||
15 | #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP | |
16 | #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP | |
17 | ||
1e59de90 TL |
18 | #include <boost/geometry/index/detail/rtree/node/node_elements.hpp> |
19 | #include <boost/geometry/index/detail/predicates.hpp> | |
20 | #include <boost/geometry/index/parameters.hpp> | |
21 | ||
7c673cae FG |
22 | namespace boost { namespace geometry { namespace index { |
23 | ||
24 | namespace detail { namespace rtree { namespace visitors { | |
25 | ||
f67539c2 | 26 | template <typename MembersHolder, typename Predicates, typename OutIter> |
7c673cae | 27 | struct spatial_query |
7c673cae | 28 | { |
f67539c2 TL |
29 | typedef typename MembersHolder::parameters_type parameters_type; |
30 | typedef typename MembersHolder::translator_type translator_type; | |
31 | typedef typename MembersHolder::allocators_type allocators_type; | |
32 | ||
92f5a8d4 TL |
33 | typedef typename index::detail::strategy_type<parameters_type>::type strategy_type; |
34 | ||
f67539c2 TL |
35 | typedef typename MembersHolder::node node; |
36 | typedef typename MembersHolder::internal_node internal_node; | |
37 | typedef typename MembersHolder::leaf leaf; | |
7c673cae | 38 | |
1e59de90 | 39 | typedef typename allocators_type::node_pointer node_pointer; |
f67539c2 | 40 | typedef typename allocators_type::size_type size_type; |
7c673cae | 41 | |
1e59de90 TL |
42 | spatial_query(MembersHolder const& members, Predicates const& p, OutIter out_it) |
43 | : m_tr(members.translator()) | |
44 | , m_strategy(index::detail::get_strategy(members.parameters())) | |
45 | , m_pred(p) | |
46 | , m_out_iter(out_it) | |
47 | , m_found_count(0) | |
7c673cae FG |
48 | {} |
49 | ||
1e59de90 | 50 | size_type apply(node_pointer ptr, size_type reverse_level) |
7c673cae | 51 | { |
1e59de90 TL |
52 | namespace id = index::detail; |
53 | if (reverse_level > 0) | |
7c673cae | 54 | { |
1e59de90 TL |
55 | internal_node& n = rtree::get<internal_node>(*ptr); |
56 | // traverse nodes meeting predicates | |
57 | for (auto const& p : rtree::elements(n)) | |
92f5a8d4 | 58 | { |
1e59de90 TL |
59 | // if node meets predicates (0 is dummy value) |
60 | if (id::predicates_check<id::bounds_tag>(m_pred, 0, p.first, m_strategy)) | |
61 | { | |
62 | apply(p.second, reverse_level - 1); | |
63 | } | |
92f5a8d4 | 64 | } |
7c673cae | 65 | } |
1e59de90 | 66 | else |
7c673cae | 67 | { |
1e59de90 TL |
68 | leaf& n = rtree::get<leaf>(*ptr); |
69 | // get all values meeting predicates | |
70 | for (auto const& v : rtree::elements(n)) | |
7c673cae | 71 | { |
1e59de90 TL |
72 | // if value meets predicates |
73 | if (id::predicates_check<id::value_tag>(m_pred, v, m_tr(v), m_strategy)) | |
74 | { | |
75 | *m_out_iter = v; | |
76 | ++m_out_iter; | |
77 | ++m_found_count; | |
78 | } | |
7c673cae FG |
79 | } |
80 | } | |
1e59de90 TL |
81 | |
82 | return m_found_count; | |
7c673cae FG |
83 | } |
84 | ||
1e59de90 TL |
85 | size_type apply(MembersHolder const& members) |
86 | { | |
87 | return apply(members.root, members.leafs_level); | |
88 | } | |
7c673cae | 89 | |
1e59de90 TL |
90 | private: |
91 | translator_type const& m_tr; | |
92 | strategy_type m_strategy; | |
7c673cae | 93 | |
1e59de90 TL |
94 | Predicates const& m_pred; |
95 | OutIter m_out_iter; | |
92f5a8d4 | 96 | |
1e59de90 | 97 | size_type m_found_count; |
7c673cae FG |
98 | }; |
99 | ||
f67539c2 | 100 | template <typename MembersHolder, typename Predicates> |
7c673cae | 101 | class spatial_query_incremental |
7c673cae | 102 | { |
f67539c2 TL |
103 | typedef typename MembersHolder::value_type value_type; |
104 | typedef typename MembersHolder::parameters_type parameters_type; | |
105 | typedef typename MembersHolder::translator_type translator_type; | |
106 | typedef typename MembersHolder::allocators_type allocators_type; | |
107 | ||
92f5a8d4 TL |
108 | typedef typename index::detail::strategy_type<parameters_type>::type strategy_type; |
109 | ||
f67539c2 TL |
110 | typedef typename MembersHolder::node node; |
111 | typedef typename MembersHolder::internal_node internal_node; | |
112 | typedef typename MembersHolder::leaf leaf; | |
7c673cae | 113 | |
f67539c2 TL |
114 | typedef typename allocators_type::size_type size_type; |
115 | typedef typename allocators_type::const_reference const_reference; | |
116 | typedef typename allocators_type::node_pointer node_pointer; | |
7c673cae FG |
117 | |
118 | typedef typename rtree::elements_type<internal_node>::type::const_iterator internal_iterator; | |
119 | typedef typename rtree::elements_type<leaf>::type leaf_elements; | |
120 | typedef typename rtree::elements_type<leaf>::type::const_iterator leaf_iterator; | |
121 | ||
1e59de90 TL |
122 | struct internal_data |
123 | { | |
124 | internal_data(internal_iterator f, internal_iterator l, size_type rl) | |
125 | : first(f), last(l), reverse_level(rl) | |
126 | {} | |
127 | internal_iterator first; | |
128 | internal_iterator last; | |
129 | size_type reverse_level; | |
130 | }; | |
7c673cae | 131 | |
1e59de90 TL |
132 | public: |
133 | spatial_query_incremental() | |
134 | : m_translator(nullptr) | |
135 | // , m_strategy() | |
7c673cae | 136 | // , m_pred() |
1e59de90 | 137 | , m_values(nullptr) |
7c673cae FG |
138 | , m_current() |
139 | {} | |
140 | ||
1e59de90 TL |
141 | spatial_query_incremental(Predicates const& p) |
142 | : m_translator(nullptr) | |
143 | // , m_strategy() | |
7c673cae | 144 | , m_pred(p) |
1e59de90 | 145 | , m_values(nullptr) |
7c673cae FG |
146 | , m_current() |
147 | {} | |
148 | ||
1e59de90 TL |
149 | spatial_query_incremental(MembersHolder const& members, Predicates const& p) |
150 | : m_translator(::boost::addressof(members.translator())) | |
151 | , m_strategy(index::detail::get_strategy(members.parameters())) | |
152 | , m_pred(p) | |
153 | , m_values(nullptr) | |
154 | , m_current() | |
155 | {} | |
7c673cae FG |
156 | |
157 | const_reference dereference() const | |
158 | { | |
159 | BOOST_GEOMETRY_INDEX_ASSERT(m_values, "not dereferencable"); | |
160 | return *m_current; | |
161 | } | |
162 | ||
1e59de90 | 163 | void initialize(MembersHolder const& members) |
7c673cae | 164 | { |
1e59de90 | 165 | apply(members.root, members.leafs_level); |
7c673cae FG |
166 | search_value(); |
167 | } | |
168 | ||
169 | void increment() | |
170 | { | |
171 | ++m_current; | |
172 | search_value(); | |
173 | } | |
174 | ||
1e59de90 TL |
175 | bool is_end() const |
176 | { | |
177 | return 0 == m_values; | |
178 | } | |
179 | ||
180 | friend bool operator==(spatial_query_incremental const& l, spatial_query_incremental const& r) | |
181 | { | |
182 | return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current); | |
183 | } | |
184 | ||
185 | private: | |
186 | void apply(node_pointer ptr, size_type reverse_level) | |
187 | { | |
188 | namespace id = index::detail; | |
189 | ||
190 | if (reverse_level > 0) | |
191 | { | |
192 | internal_node& n = rtree::get<internal_node>(*ptr); | |
193 | auto const& elements = rtree::elements(n); | |
194 | m_internal_stack.push_back(internal_data(elements.begin(), elements.end(), reverse_level - 1)); | |
195 | } | |
196 | else | |
197 | { | |
198 | leaf& n = rtree::get<leaf>(*ptr); | |
199 | m_values = ::boost::addressof(rtree::elements(n)); | |
200 | m_current = rtree::elements(n).begin(); | |
201 | } | |
202 | } | |
203 | ||
7c673cae FG |
204 | void search_value() |
205 | { | |
1e59de90 | 206 | namespace id = index::detail; |
7c673cae FG |
207 | for (;;) |
208 | { | |
209 | // if leaf is choosen, move to the next value in leaf | |
210 | if ( m_values ) | |
211 | { | |
212 | if ( m_current != m_values->end() ) | |
213 | { | |
214 | // return if next value is found | |
f67539c2 | 215 | value_type const& v = *m_current; |
1e59de90 | 216 | if (id::predicates_check<id::value_tag>(m_pred, v, (*m_translator)(v), m_strategy)) |
92f5a8d4 | 217 | { |
7c673cae | 218 | return; |
92f5a8d4 | 219 | } |
7c673cae FG |
220 | |
221 | ++m_current; | |
222 | } | |
223 | // no more values, clear current leaf | |
224 | else | |
225 | { | |
226 | m_values = 0; | |
227 | } | |
228 | } | |
229 | // if leaf isn't choosen, move to the next leaf | |
230 | else | |
231 | { | |
232 | // return if there is no more nodes to traverse | |
1e59de90 TL |
233 | if (m_internal_stack.empty()) |
234 | { | |
7c673cae | 235 | return; |
1e59de90 TL |
236 | } |
237 | ||
238 | internal_data& current_data = m_internal_stack.back(); | |
7c673cae | 239 | |
1e59de90 TL |
240 | // no more children in current node, remove it from stack |
241 | if (current_data.first == current_data.last) | |
7c673cae FG |
242 | { |
243 | m_internal_stack.pop_back(); | |
244 | continue; | |
245 | } | |
246 | ||
1e59de90 TL |
247 | internal_iterator it = current_data.first; |
248 | ++current_data.first; | |
7c673cae FG |
249 | |
250 | // next node is found, push it to the stack | |
1e59de90 | 251 | if (id::predicates_check<id::bounds_tag>(m_pred, 0, it->first, m_strategy)) |
92f5a8d4 | 252 | { |
1e59de90 | 253 | apply(it->second, current_data.reverse_level); |
92f5a8d4 | 254 | } |
7c673cae FG |
255 | } |
256 | } | |
257 | } | |
1e59de90 | 258 | |
f67539c2 | 259 | const translator_type * m_translator; |
1e59de90 | 260 | strategy_type m_strategy; |
7c673cae FG |
261 | |
262 | Predicates m_pred; | |
263 | ||
1e59de90 | 264 | std::vector<internal_data> m_internal_stack; |
7c673cae FG |
265 | const leaf_elements * m_values; |
266 | leaf_iterator m_current; | |
267 | }; | |
268 | ||
269 | }}} // namespace detail::rtree::visitors | |
270 | ||
271 | }}} // namespace boost::geometry::index | |
272 | ||
273 | #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP |