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