| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #ifndef _PY_KDTREE_H_ |
| | #define _PY_KDTREE_H_ |
| |
|
| | #include <kdtree++/kdtree.hpp> |
| |
|
| | #include <iostream> |
| | #include <vector> |
| | #include <limits> |
| |
|
| | template <size_t DIM, typename COORD_T, typename DATA_T > |
| | struct record_t { |
| | static const size_t dim = DIM; |
| | typedef COORD_T coord_t; |
| | typedef DATA_T data_t; |
| |
|
| | typedef coord_t point_t[dim]; |
| | |
| | inline coord_t operator[](size_t const N) const { return point[N]; } |
| |
|
| | point_t point; |
| | data_t data; |
| | }; |
| |
|
| | typedef double RANGE_T; |
| |
|
| | %%TMPL_HPP_DEFS%% |
| |
|
| | |
| | |
| | |
| |
|
| |
|
| | template <class RECORD_T> |
| | inline double tac(RECORD_T r, int k) { return r[k]; } |
| |
|
| | template <size_t DIM, typename COORD_T, typename DATA_T > |
| | class PyKDTree { |
| | public: |
| |
|
| | typedef record_t<DIM, COORD_T, DATA_T> RECORD_T; |
| | typedef KDTree::KDTree<DIM, RECORD_T, std::pointer_to_binary_function<RECORD_T,int,double> > TREE_T; |
| | TREE_T tree; |
| |
|
| | PyKDTree() : tree(std::ptr_fun(tac<RECORD_T>)) { }; |
| |
|
| | void add(RECORD_T T) { tree.insert(T); }; |
| |
|
| | |
| | |
| | |
| | bool remove(RECORD_T T) { |
| | bool removed = false; |
| |
|
| | typename TREE_T::const_iterator it = tree.find_exact(T); |
| | if (it!=tree.end()) { |
| | tree.erase_exact(T); |
| | removed = true; |
| | } |
| | return removed; |
| | }; |
| |
|
| | int size(void) { return tree.size(); } |
| |
|
| | void optimize(void) { tree.optimise(); } |
| | |
| | RECORD_T* find_exact(RECORD_T T) { |
| | RECORD_T* found = NULL; |
| | typename TREE_T::const_iterator it = tree.find_exact(T); |
| | if (it!=tree.end()) |
| | found = new RECORD_T(*it); |
| |
|
| | return found; |
| | } |
| |
|
| | size_t count_within_range(typename RECORD_T::point_t T, RANGE_T range) { |
| | RECORD_T query_record; |
| | memcpy(query_record.point, T, sizeof(COORD_T)*DIM); |
| |
|
| | return tree.count_within_range(query_record, range); |
| | } |
| |
|
| | std::vector<RECORD_T >* find_within_range(typename RECORD_T::point_t T, RANGE_T range) { |
| | RECORD_T query_record; |
| | memcpy(query_record.point, T, sizeof(COORD_T)*DIM); |
| |
|
| | std::vector<RECORD_T> *v = new std::vector<RECORD_T>; |
| | tree.find_within_range(query_record, range, std::back_inserter(*v)); |
| | return v; |
| | } |
| |
|
| | RECORD_T* find_nearest (typename RECORD_T::point_t T) { |
| | RECORD_T* found = NULL; |
| | RECORD_T query_record; |
| | memcpy(query_record.point, T, sizeof(COORD_T)*DIM); |
| |
|
| | std::pair<typename TREE_T::const_iterator, typename TREE_T::distance_type> best = |
| | tree.find_nearest(query_record, std::numeric_limits<typename TREE_T::distance_type>::max()); |
| |
|
| | if (best.first!=tree.end()) { |
| | found = new RECORD_T(*best.first); |
| | } |
| | return found; |
| | } |
| |
|
| | std::vector<RECORD_T >* get_all() { |
| | std::vector<RECORD_T>* v = new std::vector<RECORD_T>; |
| |
|
| | for (typename TREE_T::const_iterator iter=tree.begin(); iter!=tree.end(); ++iter) { |
| | v->push_back(*iter); |
| | } |
| |
|
| | return v; |
| | } |
| |
|
| | size_t __len__() { return tree.size(); } |
| | }; |
| | #endif |
| |
|