atlas
KDTree.h
1 /*
2  * (C) Copyright 2013 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation
8  * nor does it submit to any jurisdiction.
9  */
10 
11 #pragma once
12 
13 #include "atlas/util/Geometry.h"
14 #include "atlas/util/ObjectHandle.h"
15 #include "atlas/util/detail/KDTree.h"
16 
17 namespace atlas {
18 namespace util {
19 
20 //------------------------------------------------------------------------------------------------------
21 
47 
48 template <typename PayloadT, typename PointT = Point3>
49 class KDTree : public ObjectHandle<detail::KDTreeBase<PayloadT, PointT>> {
50 public:
52  using Implementation = typename Handle::Implementation;
53  using Point = typename Implementation::Point;
54  using Payload = typename Implementation::Payload;
55  using PayloadList = typename Implementation::PayloadList;
56  using Value = typename Implementation::Value;
57  using ValueList = typename Implementation::ValueList;
58 
59  using Handle::get;
60  using Handle::Handle;
61 
62 public:
63  //--------------------------------------------------------------------------------------
64  // Constructors
65 
66  KDTree( const KDTree& handle ) : Handle( handle ) {}
67 
69  KDTree() : Handle( new detail::KDTreeMemory<Payload, Point>() ) {}
70 
72  KDTree( const Geometry& geometry ) : Handle( new detail::KDTreeMemory<Payload, Point>( geometry ) ) {}
73 
75  template <typename Tree>
76  KDTree( const std::shared_ptr<Tree>& kdtree ) :
77  Handle( new detail::KDTree_eckit<Tree, Payload, Point>( kdtree ) ) {}
78 
80  template <typename Tree>
81  KDTree( const std::shared_ptr<Tree>& kdtree, const Geometry& geometry ) :
82  Handle( new detail::KDTree_eckit<Tree, Payload, Point>( kdtree, geometry ) ) {}
83 
84  //--------------------------------------------------------------------------------------
85  // Methods to build the KDTree
86 
88  void reserve( idx_t size ) { get()->reserve( size ); }
89 
92  template <typename Point>
93  void insert( const Point& p, const Payload& payload ) {
94  get()->insert( p, payload );
95  }
96 
99  void insert( const Value& value ) { get()->insert( value ); }
100 
104  void build() { get()->build(); }
105 
109  template <typename Longitudes, typename Latitudes, typename Payloads>
110  void build( const Longitudes& longitudes, const Latitudes& latitudes, const Payloads& payloads ) {
111  get()->build( longitudes, latitudes, payloads );
112  }
113 
117  template <typename LongitudesIterator, typename LatitudesIterator, typename PayloadsIterator>
118  void build( const LongitudesIterator& longitudes_begin, const LongitudesIterator& longitudes_end,
119  const LatitudesIterator& latitudes_begin, const LatitudesIterator& latitudes_end,
120  const PayloadsIterator& payloads_begin, const PayloadsIterator& payloads_end ) {
121  get()->build( longitudes_begin, longitudes_end, latitudes_begin, latitudes_end, payloads_begin, payloads_end );
122  }
123 
127  template <typename Points, typename Payloads>
128  void build( const Points& points, const Payloads& payloads ) {
129  get()->build( points, payloads );
130  }
131 
135  template <typename PointIterator, typename PayloadsIterator>
136  void build( const PointIterator& points_begin, const PointIterator& points_end,
137  const PayloadsIterator& payloads_begin, const PayloadsIterator& payloads_end ) {
138  get()->build( points_begin, points_end, payloads_begin, payloads_end );
139  }
140 
143  void build( const std::vector<Value>& values ) { get()->build( values ); }
144 
145  //--------------------------------------------------------------------------------------
146  // Methods to access the KDTree
147 
148  bool empty() const { return get()->empty(); }
149 
150  size_t size() const { return get()->size(); }
151 
152  size_t footprint() const { return get()->footprint(); }
153 
155  template <typename Point>
156  ValueList closestPoints( const Point& p, size_t k ) const {
157  return get()->closestPoints( p, k );
158  }
159 
161  template <typename Point>
162  Value closestPoint( const Point& p ) const {
163  return get()->closestPoint( p );
164  }
165 
168  template <typename Point>
169  ValueList closestPointsWithinRadius( const Point& p, double radius ) const {
170  return get()->closestPointsWithinRadius( p, radius );
171  }
172 
174  const Geometry& geometry() const { return get()->geometry(); }
175 };
176 
177 //------------------------------------------------------------------------------------------------------
178 
179 using IndexKDTree2D = KDTree<idx_t, Point2>; // 2D search: implementation is using 2D points only
180 using IndexKDTree3D = KDTree<idx_t, Point3>; // 3D search: lonlat (2D) to xyz (3D) conversion is done internally
181 using IndexKDTree = IndexKDTree3D;
182 
183 // ------------------------------------------------------------------
184 // C wrapper interfaces to C++ routines
185 
186 extern "C" {
187 IndexKDTree::Implementation* atlas__IndexKDTree__new();
188 IndexKDTree::Implementation* atlas__IndexKDTree__new_geometry( const Geometry::Implementation* geometry );
189 void atlas__IndexKDTree__delete( IndexKDTree::Implementation* This );
190 void atlas__IndexKDTree__reserve( IndexKDTree::Implementation* This, const idx_t size );
191 void atlas__IndexKDTree__insert( IndexKDTree::Implementation* This, const double lon, const double lat,
192  const idx_t index );
193 void atlas__IndexKDTree__build( IndexKDTree::Implementation* This );
194 void atlas__IndexKDTree__closestPoints( const IndexKDTree::Implementation* This, const double plon, const double plat,
195  const size_t k, double*& lon, double*& lat, idx_t*& indices,
196  double*& distances );
197 void atlas__IndexKDTree__closestPoint( const IndexKDTree::Implementation* This, const double plon, const double plat,
198  double& lon, double& lat, idx_t& index, double& distance );
199 void atlas__IndexKDTree__closestPointsWithinRadius( const IndexKDTree::Implementation* This, const double plon,
200  const double plat, const double radius, size_t& k, double*& lon,
201  double*& lat, idx_t*& indices, double*& distances );
202 const Geometry::Implementation* atlas__IndexKDTree__geometry( const IndexKDTree::Implementation* This );
203 int atlas__IndexKDTree__empty( const IndexKDTree::Implementation* This );
204 idx_t atlas__IndexKDTree__size( const IndexKDTree::Implementation* This );
205 }
206 
207 //------------------------------------------------------------------------------------------------------
208 
209 } // namespace util
210 } // namespace atlas
const Geometry & geometry() const
Return geometry used to convert (lon,lat) to (x,y,z) coordinates.
Definition: KDTree.h:174
ValueList closestPointsWithinRadius(const Point &p, double radius) const
Find all points within a distance of given radius from a given point 3D cartesian point (x...
Definition: KDTree.h:169
void build()
Build the kd-tree in one shot, if memory has been reserved.
Definition: KDTree.h:104
Definition: Geometry.h:94
void build(const Points &points, const Payloads &payloads)
Build with templated points.
Definition: KDTree.h:128
Definition: Geometry.h:30
KDTree()
Construct an empty kd-tree with default geometry (Earth)
Definition: KDTree.h:69
void build(const std::vector< Value > &values)
Build with vector of Value.
Definition: KDTree.h:143
ValueList closestPoints(const Point &p, size_t k) const
Find k closest points given a 3D cartesian point (x,y,z) or 2D lonlat point(lon,lat) ...
Definition: KDTree.h:156
Definition: KDTree.h:34
Value closestPoint(const Point &p) const
Find closest point given a 3D cartesian point (x,y,z) or 2D lonlat point(lon,lat) ...
Definition: KDTree.h:162
void insert(const Value &value)
Insert kd-tree value in tree.
Definition: KDTree.h:99
void build(const Longitudes &longitudes, const Latitudes &latitudes, const Payloads &payloads)
Build with spherical points (lon,lat) where longitudes, latitudes, and payloads are separate containe...
Definition: KDTree.h:110
k-dimensional tree constructable both with 2D (lon,lat) points as with 3D (x,y,z) points ...
Definition: KDTree.h:49
KDTree(const std::shared_ptr< Tree > &kdtree)
Construct a shared kd-tree with default geometry (Earth)
Definition: KDTree.h:76
KDTree(const Geometry &geometry)
Construct an empty kd-tree with custom geometry.
Definition: KDTree.h:72
void reserve(idx_t size)
Reserve memory for building the kd-tree in one shot (optional, at cost of extra memory) ...
Definition: KDTree.h:88
void build(const LongitudesIterator &longitudes_begin, const LongitudesIterator &longitudes_end, const LatitudesIterator &latitudes_begin, const LatitudesIterator &latitudes_end, const PayloadsIterator &payloads_begin, const PayloadsIterator &payloads_end)
Build with spherical points (lon,lat) given separate iterator ranges for longitudes, latitudes, and payloads.
Definition: KDTree.h:118
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33
void insert(const Point &p, const Payload &payload)
Insert spherical point (lon,lat) or 3D cartesian point (x,y,z)
Definition: KDTree.h:93
long idx_t
Integer type for indices in connectivity tables.
Definition: config.h:42
KDTree(const std::shared_ptr< Tree > &kdtree, const Geometry &geometry)
Construct a shared kd-tree with custom geometry.
Definition: KDTree.h:81
Definition: ObjectHandle.h:64
void build(const PointIterator &points_begin, const PointIterator &points_end, const PayloadsIterator &payloads_begin, const PayloadsIterator &payloads_end)
Build with spherical points (lon,lat) given separate iterator ranges for longitudes, latitudes, and payloads.
Definition: KDTree.h:136