Autoware.Auto
spatial_hash.hpp
Go to the documentation of this file.
1 // Copyright 2019 the Autoware Foundation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Co-developed by Tier IV, Inc. and Apex.AI, Inc.
19 
20 #ifndef GEOMETRY__SPATIAL_HASH_HPP_
21 #define GEOMETRY__SPATIAL_HASH_HPP_
22 
23 #include <common/types.hpp>
26 #include <vector>
27 #include <unordered_map>
28 #include <utility>
29 
32 
33 namespace autoware
34 {
35 namespace common
36 {
37 namespace geometry
38 {
40 namespace spatial_hash
41 {
42 
50 template<typename PointT, typename ConfigT>
51 class GEOMETRY_PUBLIC SpatialHashBase
52 {
53  using Index3 = details::Index3;
54  //lint -e{9131} NOLINT There's no other way to make this work in a static assert
55  static_assert(
56  std::is_same<ConfigT, Config2d>::value || std::is_same<ConfigT, Config3d>::value,
57  "SpatialHash only works with Config2d or Config3d");
58 
59 public:
60  using Hash = std::unordered_multimap<Index, PointT>;
61  using IT = typename Hash::const_iterator;
63  class Output
64  {
65 public:
69  Output(const IT iterator, const float32_t distance)
70  : m_iterator(iterator),
71  m_distance(distance)
72  {
73  }
76  const PointT & get_point() const
77  {
78  return m_iterator->second;
79  }
82  IT get_iterator() const
83  {
84  return m_iterator;
85  }
88  operator const PointT &() const
89  {
90  return get_point();
91  }
94  operator IT() const
95  {
96  return get_iterator();
97  }
101  {
102  return m_distance;
103  }
104 
105 private:
106  IT m_iterator;
107  float32_t m_distance;
108  }; // class Output
109  using OutputVector = typename std::vector<Output>;
110 
113  explicit SpatialHashBase(const ConfigT & cfg)
114  : m_config{cfg},
115  m_hash(),
116  m_neighbors{}, // TODO(c.ho) reserve, but there's no default constructor for output
117  m_bins_hit{}, // zero initialization (and below)
118  m_neighbors_found{}
119  {
120  }
121 
126  IT insert(const PointT & pt)
127  {
128  if (size() >= capacity()) {
129  throw std::length_error{"SpatialHash: Cannot insert past capacity"};
130  }
131  return insert_impl(pt);
132  }
133 
140  template<typename IteratorT>
141  void insert(IteratorT begin, IteratorT end)
142  {
143  // This check is here for strong exception safety
144  if ((size() + std::distance(begin, end)) > capacity()) {
145  throw std::length_error{"SpatialHash: Cannot multi-insert past capacity"};
146  }
147  for (IteratorT it = begin; it != end; ++it) {
148  (void)insert_impl(*it);
149  }
150  }
151 
153  void clear()
154  {
155  m_hash.clear();
156  }
159  Index size() const
160  {
161  return m_hash.size();
162  }
165  Index capacity() const
166  {
167  return m_config.get_capacity();
168  }
171  bool8_t empty() const
172  {
173  return m_hash.empty();
174  }
177  IT begin() const
178  {
179  return m_hash.begin();
180  }
183  IT end() const
184  {
185  return m_hash.end();
186  }
189  IT cbegin() const
190  {
191  return begin();
192  }
195  IT cend() const
196  {
197  return end();
198  }
199 
203  Index bins_hit() const
204  {
205  return m_bins_hit;
206  }
207 
212  {
213  return m_neighbors_found;
214  }
215 
216 protected:
225  const float32_t x,
226  const float32_t y,
227  const float32_t z)
228  {
229  // reset output
230  m_neighbors.clear();
231  // Compute bin, bin range
232  const Index3 ref_idx = m_config.index3(x, y, z);
233  const details::BinRange idx_range = m_config.bin_range(ref_idx);
234  Index3 idx = idx_range.first;
235  // For bins in radius
236  do { // guaranteed to have at least the bin ref_idx is in
237  // update book-keeping
238  ++m_bins_hit;
239  // Iterating in a square/cube pattern is easier than constructing sphere pattern
240  if (m_config.is_candidate_bin(ref_idx, idx)) {
241  // For point in bin
242  const Index jdx = m_config.index(idx);
243  const auto range = m_hash.equal_range(jdx);
244  for (auto it = range.first; it != range.second; ++it) {
245  const auto & pt = it->second;
246  const float32_t dist2 = m_config.distance_squared(x, y, z, pt);
247  if (dist2 <= m_config.radius2()) {
248  // Only compute true distance if necessary
249  m_neighbors.emplace_back(it, sqrtf(dist2));
250  }
251  }
252  }
253  } while (m_config.next_bin(idx_range, idx));
254  // update book-keeping
255  m_neighbors_found += m_neighbors.size();
256  return m_neighbors;
257  }
258 
259 private:
262  GEOMETRY_LOCAL IT insert_impl(const PointT & pt)
263  {
264  // Compute bin
265  const Index idx =
266  m_config.bin(point_adapter::x_(pt), point_adapter::y_(pt), point_adapter::z_(pt));
267  // Insert into bin
268  return m_hash.insert(std::make_pair(idx, pt));
269  }
270 
271  const ConfigT m_config;
272  Hash m_hash;
273  OutputVector m_neighbors;
274  Index m_bins_hit;
275  Index m_neighbors_found;
276 }; // class SpatialHashBase
277 
282 template<typename PointT, typename ConfigT>
283 class GEOMETRY_PUBLIC SpatialHash;
284 
287 template<typename PointT>
288 class GEOMETRY_PUBLIC SpatialHash<PointT, Config2d>: public SpatialHashBase<PointT, Config2d>
289 {
290 public:
292 
293  explicit SpatialHash(const Config2d & cfg)
294  : SpatialHashBase<PointT, Config2d>(cfg) {}
295 
302  const OutputVector & near(const float32_t x, const float32_t y)
303  {
304  return this->near_impl(x, y, 0.0F);
305  }
306 
312  const OutputVector & near(const PointT & pt)
313  {
314  return near(point_adapter::x_(pt), point_adapter::y_(pt));
315  }
316 };
317 
320 template<typename PointT>
321 class GEOMETRY_PUBLIC SpatialHash<PointT, Config3d>: public SpatialHashBase<PointT, Config3d>
322 {
323 public:
325 
326  explicit SpatialHash(const Config3d & cfg)
327  : SpatialHashBase<PointT, Config3d>(cfg) {}
328 
337  const OutputVector & near(const float32_t x, const float32_t y, const float32_t z)
338  {
339  return this->near_impl(x, y, z);
340  }
341 
347  const OutputVector & near(const PointT & pt)
348  {
349  return near(point_adapter::x_(pt), point_adapter::y_(pt), point_adapter::z_(pt));
350  }
351 };
352 
353 template<typename T>
354 using SpatialHash2d = SpatialHash<T, Config2d>;
355 template<typename T>
356 using SpatialHash3d = SpatialHash<T, Config3d>;
357 } // namespace spatial_hash
358 } // namespace geometry
359 } // namespace common
360 } // namespace autoware
361 
362 #endif // GEOMETRY__SPATIAL_HASH_HPP_
Output(const IT iterator, const float32_t distance)
Constructor.
Definition: spatial_hash.hpp:69
Internal struct for packing three indices together.
Definition: spatial_hash_config.hpp:59
SpatialHash< T, Config3d > SpatialHash3d
Definition: spatial_hash.hpp:356
const OutputVector & near(const float32_t x, const float32_t y)
Finds all points within a fixed radius of a reference point.
Definition: spatial_hash.hpp:302
IT get_iterator() const
Get underlying iterator.
Definition: spatial_hash.hpp:82
typename SpatialHashBase< PointT, Config2d >::OutputVector OutputVector
Definition: spatial_hash.hpp:291
float float32_t
Definition: types.hpp:36
SpatialHash< T, Config2d > SpatialHash2d
Definition: spatial_hash.hpp:354
const OutputVector & near(const PointT &pt)
Finds all points within a fixed radius of a reference point.
Definition: spatial_hash.hpp:312
void insert(IteratorT begin, IteratorT end)
Inserts a range of points.
Definition: spatial_hash.hpp:141
Index bins_hit() const
Get the number of bins touched during the lifetime of this object, for debugging and size tuning...
Definition: spatial_hash.hpp:203
const PointT & get_point() const
Get stored point.
Definition: spatial_hash.hpp:76
bool bool8_t
Definition: types.hpp:33
This file includes common type definition.
Configuration class for a 2d spatial hash.
Definition: spatial_hash_config.hpp:342
IT cbegin() const
Get iterator to beginning of data structure.
Definition: spatial_hash.hpp:189
const OutputVector & near(const float32_t x, const float32_t y, const float32_t z)
Finds all points within a fixed radius of a reference point.
Definition: spatial_hash.hpp:337
auto z_(const PointT &pt)
Gets the z value for a point.
Definition: common_2d.hpp:65
SpatialHash(const Config3d &cfg)
Definition: spatial_hash.hpp:326
const OutputVector & near(const PointT &pt)
Finds all points within a fixed radius of a reference point.
Definition: spatial_hash.hpp:347
float32_t get_distance() const
Get distance to reference point.
Definition: spatial_hash.hpp:100
DifferentialState x
Definition: kinematic_bicycle.snippet.hpp:28
Index neighbors_found() const
Get number of near neighbors found during the lifetime of this object, for debugging and size tuning...
Definition: spatial_hash.hpp:211
const OutputVector & near_impl(const float32_t x, const float32_t y, const float32_t z)
Finds all points within a fixed radius of a reference point.
Definition: spatial_hash.hpp:224
typename std::vector< Output > OutputVector
Definition: spatial_hash.hpp:109
IT insert(const PointT &pt)
Inserts point.
Definition: spatial_hash.hpp:126
bool8_t empty() const
Whether the hash is empty.
Definition: spatial_hash.hpp:171
std::size_t Index
Index type for identifying bins of the hash/lattice.
Definition: spatial_hash_config.hpp:49
std::pair< Index3, Index3 > BinRange
Definition: spatial_hash_config.hpp:66
void clear()
Reset the state of the data structure.
Definition: spatial_hash.hpp:153
DifferentialState y
Definition: kinematic_bicycle.snippet.hpp:28
std::unordered_multimap< Index, PointT > Hash
Definition: spatial_hash.hpp:60
This file implements a spatial hash for efficient fixed-radius near neighbor queries in 2D...
auto x_(const PointT &pt)
Gets the x value for a point.
Definition: common_2d.hpp:47
Index capacity() const
Get the maximum capacity of the data structure.
Definition: spatial_hash.hpp:165
auto y_(const PointT &pt)
Gets the y value for a point.
Definition: common_2d.hpp:56
Configuration class for a 3d spatial hash.
Definition: spatial_hash_config.hpp:404
class GEOMETRY_PUBLIC SpatialHash
The class to be used for specializing on apex_app::common::geometry::spatial_hash::SpatialHashBase to...
Definition: spatial_hash.hpp:283
end
Definition: scripts/get_open_port.py:23
typename Hash::const_iterator IT
Definition: spatial_hash.hpp:61
SpatialHash(const Config2d &cfg)
Definition: spatial_hash.hpp:293
An implementation of the spatial hash or integer lattice data structure for efficient (O(1)) near nei...
Definition: spatial_hash.hpp:51
Index size() const
Get current number of element stored in this data structure.
Definition: spatial_hash.hpp:159
IT cend() const
Get iterator to end of data structure.
Definition: spatial_hash.hpp:195
SpatialHashBase(const ConfigT &cfg)
Constructor.
Definition: spatial_hash.hpp:113
typename SpatialHashBase< PointT, Config3d >::OutputVector OutputVector
Definition: spatial_hash.hpp:324
IT end() const
Get iterator to end of data structure.
Definition: spatial_hash.hpp:183
Wrapper around an iterator and a distance (from some query point)
Definition: spatial_hash.hpp:63
IT begin() const
Get iterator to beginning of data structure.
Definition: spatial_hash.hpp:177
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24