1 // Copyright 2008, Google Inc. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
5 //
6 // 1. Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright notice,
9 // this list of conditions and the following disclaimer in the documentation
10 // and/or other materials provided with the distribution.
11 // 3. Neither the name of Google Inc. nor the names of its contributors may be
12 // used to endorse or promote products derived from this software without
13 // specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 // This file contains the unit tests for the Bbox class.
27
28 #include "kml/engine/bbox.h"
29 #include "gtest/gtest.h"
30
31 namespace kmlengine {
32
33 class BboxTest : public testing::Test {
34 protected:
35 void VerifyBounds(const Bbox& bbox, double north, double south, double east,
36 double west);
37 };
38
39 // Verify the state of a default Bbox.
TEST_F(BboxTest,TestDefault)40 TEST_F(BboxTest, TestDefault) {
41 Bbox default_bbox;
42 ASSERT_EQ(kMinLat, default_bbox.get_north());
43 ASSERT_EQ(kMaxLat, default_bbox.get_south());
44 ASSERT_EQ(kMinLon, default_bbox.get_east());
45 ASSERT_EQ(kMaxLon, default_bbox.get_west());
46 ASSERT_EQ(0, default_bbox.GetCenterLat());
47 ASSERT_EQ(0, default_bbox.GetCenterLon());
48 }
49
VerifyBounds(const Bbox & bbox,double north,double south,double east,double west)50 void BboxTest::VerifyBounds(const Bbox& bbox, double north, double south,
51 double east, double west) {
52 // Verify the getters.
53 ASSERT_EQ(north, bbox.get_north());
54 ASSERT_EQ(south, bbox.get_south());
55 ASSERT_EQ(east, bbox.get_east());
56 ASSERT_EQ(west, bbox.get_west());
57
58 const double kWantLat((north + south)/2.0);
59 const double kWantLon((east + west)/2.0);
60
61 // Verify GetCenter().
62 double mid_lat, mid_lon;
63 bbox.GetCenter(&mid_lat, &mid_lon);
64 ASSERT_EQ(kWantLat, mid_lat);
65 ASSERT_EQ(kWantLon, mid_lon);
66
67 // Verify GetCenterLat,Lon().
68 ASSERT_EQ(kWantLat, bbox.GetCenterLat());
69 ASSERT_EQ(kWantLon, bbox.GetCenterLon());
70
71 // Verify Contains().
72 ASSERT_TRUE(bbox.Contains(mid_lat, mid_lon));
73 ASSERT_TRUE(bbox.Contains(north, east));
74 ASSERT_TRUE(bbox.Contains(south, east));
75 ASSERT_TRUE(bbox.Contains(south, west));
76 ASSERT_TRUE(bbox.Contains(north, west));
77 }
78
79 // Verify copy construction and assignment.
TEST_F(BboxTest,TestCopy)80 TEST_F(BboxTest, TestCopy) {
81 const double kNorth = 2;
82 const double kSouth = 1;
83 const double kEast = 4;
84 const double kWest = 3;
85 // Create a Bbox to copy.
86 Bbox a(kNorth, kSouth, kEast, kWest);
87
88 // Create a Bbox using the copy constructor.
89 Bbox b(a);
90 VerifyBounds(b, kNorth, kSouth, kEast, kWest);
91
92 // Create a Bbox and assign to it.
93 Bbox c;
94 c = a;
95 VerifyBounds(c, kNorth, kSouth, kEast, kWest);
96 }
97
98 // Verify some basic usage.
TEST_F(BboxTest,TestBasic)99 TEST_F(BboxTest, TestBasic) {
100 const double kNorth = 45.45;
101 const double kSouth = -12.12;
102 const double kEast = 123.123;
103 const double kWest = -89.89;
104
105 Bbox bbox;
106
107 // Two points is sufficient to define a box.
108 bbox.ExpandLatLon(kNorth, kEast);
109 bbox.ExpandLatLon(kSouth, kWest);
110
111 VerifyBounds(bbox, kNorth, kSouth, kEast, kWest);
112 }
113
114 // Verify the constructor.
TEST_F(BboxTest,TestConstructor)115 TEST_F(BboxTest, TestConstructor) {
116 const double kNorth = 89.123;
117 const double kSouth = -2.222;
118 const double kEast = -88.888;
119 const double kWest = -154.6789;
120 Bbox bbox(kNorth, kSouth, kEast, kWest);
121 VerifyBounds(bbox, kNorth, kSouth, kEast, kWest);
122 }
123
124 // Verify bounding box of multiple points.
TEST_F(BboxTest,TestMultiple)125 TEST_F(BboxTest, TestMultiple) {
126 const struct {
127 double lat, lon;
128 } kPoints[] = {
129 { 46.3941,10.1168 },
130 { 46.6356,8.84678 },
131 { 46.69,8.95711 },
132 { 46.158,8.97531 },
133 { 46.1719,8.79744 },
134 { 46.1217,8.35152 },
135 { 46.62,8.5706 },
136 { 46.7067,8.953 },
137 { 46.6087,8.82036 },
138 { 46.1546,8.9633 },
139 { 46.2368,10.1363 },
140 { 46.7079,9.19907 },
141 { 45.9296,8.92094 },
142 { 46.1738,8.84359 },
143 { 46.5616,8.34504 },
144 { 46.7389,8.97314 },
145 { 46.7493,8.23686 },
146 { 46.7233,8.92272 },
147 { 45.9528,8.95471 }
148 };
149 const double kNorthExpected = 46.7493;
150 const double kSouthExpected = 45.9296;
151 const double kEastExpected = 10.1363;
152 const double kWestExpected = 8.23686;
153
154 Bbox bbox;
155 for (size_t i = 0; i < sizeof(kPoints)/sizeof(kPoints[0]); ++i) {
156 bbox.ExpandLatLon(kPoints[i].lat, kPoints[i].lon);
157 }
158
159 ASSERT_EQ(kNorthExpected, bbox.get_north());
160 ASSERT_EQ(kSouthExpected, bbox.get_south());
161 ASSERT_EQ(kEastExpected, bbox.get_east());
162 ASSERT_EQ(kWestExpected, bbox.get_west());
163
164 const double kLatExpected = (kNorthExpected + kSouthExpected)/2.0;
165 const double kLonExpected = (kEastExpected + kWestExpected)/2.0;
166 double mid_lat, mid_lon;
167 bbox.GetCenter(&mid_lat, &mid_lon);
168 ASSERT_EQ(kLatExpected, mid_lat);
169 ASSERT_EQ(kLonExpected, mid_lon);
170 ASSERT_EQ(kLatExpected, bbox.GetCenterLat());
171 ASSERT_EQ(kLonExpected, bbox.GetCenterLon());
172
173 for (size_t i = 0; i < sizeof(kPoints)/sizeof(kPoints[0]); ++i) {
174 ASSERT_TRUE(bbox.Contains(kPoints[i].lat, kPoints[i].lon));
175 }
176
177 VerifyBounds(bbox, kNorthExpected, kSouthExpected, kEastExpected,
178 kWestExpected);
179 }
180
TEST_F(BboxTest,TestExpandFromBbox)181 TEST_F(BboxTest, TestExpandFromBbox) {
182 const double kNorth = 89.123;
183 const double kSouth = -2.222;
184 const double kEast = -88.888;
185 const double kWest = -154.6789;
186 Bbox bbox(kNorth, kSouth, kEast, kWest);
187 Bbox another_bbox;
188 another_bbox.ExpandFromBbox(bbox);
189 VerifyBounds(another_bbox, kNorth, kSouth, kEast, kWest);
190 }
191
TEST_F(BboxTest,TestSetNSEW)192 TEST_F(BboxTest, TestSetNSEW) {
193 Bbox b;
194 b.set_north(37.786807);
195 ASSERT_EQ(37.786807, b.get_north());
196 b.set_south(37.781563);
197 ASSERT_EQ(37.781563, b.get_south());
198 b.set_east(-122.494135);
199 ASSERT_EQ(-122.494135, b.get_east());
200 b.set_west(-122.504031);
201 ASSERT_EQ(-122.504031, b.get_west());
202 }
203
TEST_F(BboxTest,TestAlignBbox)204 TEST_F(BboxTest, TestAlignBbox) {
205 Bbox b;
206 b.set_north(37.786807); // Lincoln Park 3
207 b.set_south(37.781563); // Lincoln Park 7
208 b.set_east(-122.494135); // Lincoln Park 18
209 b.set_west(-122.504031); // Lincoln Park 5
210 Bbox qt(180, -180, 180, -180);
211 b.AlignBbox(&qt, 24);
212 ASSERT_EQ(37.79296875, qt.get_north());
213 ASSERT_EQ(37.7490234375, qt.get_south());
214 ASSERT_EQ(-122.4755859375, qt.get_east());
215 ASSERT_EQ(-122.51953125, qt.get_west());
216 }
217
TEST_F(BboxTest,TestContainedByBox)218 TEST_F(BboxTest, TestContainedByBox) {
219 Bbox r(180, -180, 180, -180);
220 Bbox a(1,-1,1,-1);
221 ASSERT_TRUE(a.ContainedByBox(180, -180, 180, -180));
222 ASSERT_TRUE(a.ContainedByBbox(r));
223 Bbox b(1000,-1,1,-1);
224 ASSERT_FALSE(b.ContainedByBox(180, -180, 180, -180));
225 ASSERT_FALSE(b.ContainedByBbox(r));
226 }
227
228 } // end namespace kmlengine
229