1
+ #include " ../RTree.h"
2
+ #include < gmock/gmock.h>
3
+ #include < gtest/gtest-matchers.h>
4
+ #include < gtest/gtest.h>
5
+
6
+ #include < array>
7
+
8
+ using namespace ::testing;
9
+
10
+ struct Rect {
11
+ Rect (double a_minX, double a_minY, double a_maxX, double a_maxY)
12
+ : id(Rect ::max_id++) {
13
+ min[0 ] = a_minX;
14
+ min[1 ] = a_minY;
15
+
16
+ max[0 ] = a_maxX;
17
+ max[1 ] = a_maxY;
18
+ }
19
+
20
+ static size_t max_id;
21
+ size_t id;
22
+ double min[2 ];
23
+ double max[2 ];
24
+ };
25
+
26
+ size_t Rect ::max_id = 0 ;
27
+
28
+ std::array<Rect , 5 > rects{
29
+ // xmin, ymin, xmax, ymax
30
+ Rect (0.0 , 0.0 , 2.0 , 1.0 ), Rect (5.0 , 5.0 , 7.0 , 7.0 ),
31
+ Rect (8.0 , 5.0 , 9.0 , 6.0 ), Rect (7.0 , 1.0 , 9.0 , 2.0 ),
32
+ Rect (4.0 , 5.0 , 5.0 , 6.0 ),
33
+ };
34
+
35
+ // / <summary>
36
+ // / Tests that a nearest neighbor works with a flat tree
37
+ // / </summary>
38
+ // / <remarks>
39
+ // / maxNodes is larger than the number of rects. This
40
+ // / ensures that the root node can fit all the entries.
41
+ // / Therefore, the tree only has a single layer
42
+ // / </remarks>
43
+ TEST (NearestNeighbour, FlatTree) {
44
+ int constexpr maxNodes = 8 ;
45
+ RTree<Rect *, double , 2 , double , maxNodes> tree;
46
+
47
+ for (auto &r : rects) {
48
+ tree.Insert (r.min , r.max , &r);
49
+ }
50
+
51
+ std::vector<size_t > order;
52
+
53
+ double x_min[2 ] = {4.0 , 3.0 };
54
+ double x_max[2 ] = {4.0 , 3.0 };
55
+
56
+ auto count = tree.NNSearch (x_min, x_max, [&order](Rect *r, double ) {
57
+ order.push_back (r->id );
58
+ return true ;
59
+ });
60
+
61
+ EXPECT_EQ (rects.size (), count);
62
+ EXPECT_EQ (rects[4 ].id , order[0 ]);
63
+ EXPECT_EQ (rects[1 ].id , order[1 ]);
64
+ EXPECT_EQ (rects[0 ].id , order[2 ]);
65
+ EXPECT_EQ (rects[3 ].id , order[3 ]);
66
+ EXPECT_EQ (rects[2 ].id , order[4 ]);
67
+ }
68
+
69
+ // / <summary>
70
+ // / Tests that a nearest neighbor works with a deep tree
71
+ // / </summary>
72
+ // / <remarks>
73
+ // / maxNodes is smaller than the number of rects. This
74
+ // / ensures that the root node cannot fit all the entries.
75
+ // / Therefore, the tree must have multiple layers.
76
+ // / </remarks>
77
+ TEST (NearestNeighbour, DeepTree) {
78
+ int constexpr maxNodes = 2 ;
79
+ RTree<Rect *, double , 2 , double , maxNodes> tree;
80
+
81
+ for (auto &r : rects) {
82
+ tree.Insert (r.min , r.max , &r);
83
+ }
84
+
85
+ std::vector<size_t > order;
86
+
87
+ double x_min[2 ] = {4.0 , 3.0 };
88
+ double x_max[2 ] = {4.0 , 3.0 };
89
+
90
+ auto count = tree.NNSearch (x_min, x_max, [&order](Rect *r, double ) {
91
+ order.push_back (r->id );
92
+ return true ;
93
+ });
94
+
95
+ EXPECT_EQ (rects.size (), count);
96
+ EXPECT_EQ (rects[4 ].id , order[0 ]);
97
+ EXPECT_EQ (rects[1 ].id , order[1 ]);
98
+ EXPECT_EQ (rects[0 ].id , order[2 ]);
99
+ EXPECT_EQ (rects[3 ].id , order[3 ]);
100
+ EXPECT_EQ (rects[2 ].id , order[4 ]);
101
+ }
102
+
103
+ // / <summary>
104
+ // / Verifies that the search can be stopped after a
105
+ // / fixed number of results are found
106
+ // / </summary>
107
+ TEST (NearestNeighbour, MaxNumberOfHits) {
108
+ RTree<Rect *, double , 2 , double , 3 > tree;
109
+ size_t constexpr maxHits = 2 ;
110
+
111
+ for (auto &r : rects) {
112
+ tree.Insert (r.min , r.max , &r);
113
+ }
114
+
115
+ std::vector<size_t > order;
116
+
117
+ double x_min[2 ] = {4.0 , 3.0 };
118
+ double x_max[2 ] = {4.0 , 3.0 };
119
+
120
+ auto count = tree.NNSearch (x_min, x_max, [&order](Rect *r, double ) {
121
+ order.push_back (r->id );
122
+ return order.size () < maxHits;
123
+ });
124
+
125
+ EXPECT_EQ (maxHits, count);
126
+ }
0 commit comments