1 // $Id$ 2 // 3 // (C) Copyright Mateusz Loskot 2008, mateusz@loskot.net 4 // Distributed under the BSD License 5 // (See accompanying file LICENSE.txt or copy at 6 // http://www.opensource.org/licenses/bsd-license.php) 7 // 8 #include <liblas/liblas.hpp> 9 #include <liblas/detail/private_utility.hpp> 10 #include <tut/tut.hpp> 11 #include <algorithm> 12 #include <fstream> 13 #include <iterator> 14 #include <list> 15 #include "liblas_test.hpp" 16 #include "common.hpp" 17 using namespace liblas; 18 19 namespace tut 20 { 21 struct lasreader_iterator_data 22 { 23 std::string file10_; 24 std::ifstream ifs_; 25 Reader reader_; 26 lasreader_iterator_datatut::lasreader_iterator_data27 lasreader_iterator_data() : 28 file10_(g_test_data_path + "//TO_core_last_clip.las"), 29 ifs_(file10_.c_str(), std::ios::in | std::ios::binary), 30 reader_(ifs_) 31 {} 32 }; 33 34 typedef test_group<lasreader_iterator_data> tg; 35 typedef tg::object to; 36 37 tg test_group_lasreader_iterator("liblas::lasreader_iterator"); 38 39 // Test default constructor 40 template<> 41 template<> test()42 void to::test<1>() 43 { 44 lasreader_iterator it; 45 } 46 47 // Test user-defined constructor 48 template<> 49 template<> test()50 void to::test<2>() 51 { 52 lasreader_iterator it(reader_); 53 } 54 55 // Test copy constructor with default initialized iterator 56 template<> 57 template<> test()58 void to::test<3>() 59 { 60 lasreader_iterator it1; 61 lasreader_iterator it2(it1); 62 63 ensure(it1 == it2); 64 } 65 66 // Test copy constructor with initialized iterator 67 template<> 68 template<> test()69 void to::test<4>() 70 { 71 lasreader_iterator it1(reader_); 72 lasreader_iterator it2(it1); 73 74 ensure(it1 == it2); 75 } 76 77 // Test assignment operator with default initialized iterator 78 template<> 79 template<> test()80 void to::test<5>() 81 { 82 lasreader_iterator it1; 83 lasreader_iterator it2; 84 it1 = it2; 85 86 ensure(it1 == it2); 87 } 88 89 // Test assignment operator with initialized iterator 90 template<> 91 template<> test()92 void to::test<6>() 93 { 94 lasreader_iterator it1(reader_); 95 lasreader_iterator it2; 96 it1 = it2; 97 98 ensure(it1 == it2); 99 } 100 101 // Test dereference operator 102 template<> 103 template<> test()104 void to::test<7>() 105 { 106 lasreader_iterator it(reader_); 107 108 test_file10_point1(*it); 109 } 110 111 // Test pointer-to-member operator 112 template<> 113 template<> test()114 void to::test<8>() 115 { 116 lasreader_iterator it(reader_); 117 118 // test 1st point data record 119 ensure_distance(it->GetX(), double(630262.30), 0.0001); 120 ensure_distance(it->GetY(), double(4834500), 0.0001); 121 ensure_distance(it->GetZ(), double(51.53), 0.0001); 122 ensure_equals(it->GetIntensity(), 670); 123 ensure_equals(it->GetScanAngleRank(), 0); 124 ensure_equals(it->GetUserData(), 3); 125 ensure_equals(it->GetScanFlags(), 9); 126 ensure_distance(it->GetTime(), double(413665.23360000004), 0.0001); 127 128 liblas::Classification c(1); 129 ensure_equals(it->GetClassification(), c); 130 } 131 132 // Test pre-increment operator 133 template<> 134 template<> test()135 void to::test<9>() 136 { 137 lasreader_iterator it(reader_); // move to 1st point 138 ++it; // move to 2nd record 139 140 test_file10_point2(*it); 141 } 142 143 // Test post-increment operator 144 template<> 145 template<> test()146 void to::test<10>() 147 { 148 lasreader_iterator it(reader_); // move to 1st point 149 it++; // move to 2nd record 150 151 test_file10_point2(*it); 152 } 153 154 // Test equal-to operator 155 template<> 156 template<> test()157 void to::test<11>() 158 { 159 lasreader_iterator it(reader_); // move to 1st point 160 lasreader_iterator end; 161 162 ensure_not(end == it); 163 } 164 165 // Test not-equal-to operator 166 template<> 167 template<> test()168 void to::test<12>() 169 { 170 lasreader_iterator it(reader_); // move to 1st point 171 lasreader_iterator end; 172 173 ensure(end != it); 174 } 175 176 // Test iteration 177 template<> 178 template<> test()179 void to::test<13>() 180 { 181 boost::uint32_t const cnt = reader_.GetHeader().GetPointRecordsCount(); 182 lasreader_iterator it(reader_); // move to 1st point 183 lasreader_iterator end; 184 185 boost::uint32_t s = 0; 186 while (end != it) 187 { 188 s++; 189 ++it; 190 } 191 192 ensure_equals(cnt, s); 193 } 194 195 // Test std::distance operation 196 template<> 197 template<> test()198 void to::test<14>() 199 { 200 boost::uint32_t const cnt = reader_.GetHeader().GetPointRecordsCount(); 201 lasreader_iterator it(reader_); // move to 1st point 202 lasreader_iterator end; 203 204 typedef lasreader_iterator::difference_type difference_type; 205 difference_type const d = std::distance(it, end); 206 ensure_equals(d, static_cast<difference_type>(cnt)); 207 } 208 209 // Test std::distance operation 210 template<> 211 template<> test()212 void to::test<15>() 213 { 214 typedef lasreader_iterator::difference_type difference_type; 215 216 difference_type a = std::distance(lasreader_iterator(reader_), lasreader_iterator()); 217 218 // Reader state is set to "past-the-end-of-file" 219 // So, reset is needed 220 reader_.Reset(); 221 222 difference_type b = std::distance(lasreader_iterator(reader_), lasreader_iterator()); 223 224 ensure_equals(a, b); 225 } 226 227 // Test std::advance operation 228 template<> 229 template<> test()230 void to::test<16>() 231 { 232 lasreader_iterator it(reader_); // move to 1st point 233 234 std::advance(it, 1); // move to 2nd record 235 test_file10_point2(*it); 236 237 std::advance(it, 2); // move to 4th record 238 test_file10_point4(*it); 239 } 240 241 // Test std::copy algorithm 242 template<> 243 template<> test()244 void to::test<17>() 245 { 246 boost::uint32_t const size = reader_.GetHeader().GetPointRecordsCount(); 247 lasreader_iterator it(reader_); 248 lasreader_iterator end; 249 250 typedef std::list<Point> list_t; 251 typedef std::back_insert_iterator<list_t> inserter_t; 252 list_t cache; 253 254 // Test copying LAS records to std::list based cache 255 std::copy(it, end, inserter_t(cache)); 256 ensure_equals(cache.size(), size); 257 258 // Test copied data 259 list_t::const_iterator cit = cache.begin(); // 1st element 260 std::advance(cit, 1); // move to 2nd element in cache 261 test_file10_point2(*cit); 262 std::advance(cit, 2); // move to 4th element in cache 263 test_file10_point4(*cit); 264 } 265 266 // Test std::count algorithm 267 template<> 268 template<> test()269 void to::test<18>() 270 { 271 // Construct copy of 2nd point record from tested file 272 Header h; 273 Point pt(&h); 274 h.SetScale(0.01, 0.01, 0.01); 275 pt.SetHeader(&h); 276 pt.SetCoordinates(630282.45, 4834500, 51.63); 277 pt.SetIntensity(350); 278 pt.SetClassification(1); 279 pt.SetScanAngleRank(0); 280 pt.SetUserData(3); 281 pt.SetScanFlags(9); 282 pt.SetTime(413665.52880000003); 283 ensure(pt.IsValid()); 284 test_file10_point2(pt); 285 286 lasreader_iterator it(reader_); 287 lasreader_iterator end; 288 289 // Count records equal to given point object 290 typedef lasreader_iterator::difference_type difference_type; 291 difference_type const expected = 1; 292 difference_type n = std::count(it, end, pt); 293 ensure_equals(n, expected); 294 } 295 296 // Test std::equal algorithm 297 template<> 298 template<> test()299 void to::test<19>() 300 { 301 std::ifstream ifs(file10_.c_str(), std::ios::in | std::ios::binary); 302 Reader reader(ifs); 303 304 // Copy LAS records to std::list based cache 305 typedef std::list<Point> list_t; 306 typedef std::back_insert_iterator<list_t> inserter_t; 307 list_t cache; 308 { 309 lasreader_iterator it(reader); 310 lasreader_iterator end; 311 ensure(it != end); 312 313 std::copy(it, end, inserter_t(cache)); 314 ensure_equals(cache.size(), reader.GetHeader().GetPointRecordsCount()); 315 } 316 317 // Reset reader to the beginning of LAS file 318 reader.Reset(); 319 320 // Compare LAS file with cache 321 { 322 lasreader_iterator it(reader); 323 lasreader_iterator end; 324 ensure(it != end); 325 326 bool eq = std::equal(it, end, cache.begin()); 327 ensure(eq); 328 } 329 } 330 331 // Test std::find algorithm 332 template<> 333 template<> test()334 void to::test<20>() 335 { 336 // Construct copy of 2nd point record from tested file 337 Header h; 338 Point pt(&h); 339 h.SetScale(0.01, 0.01, 0.01); 340 pt.SetHeader(&h); 341 pt.SetCoordinates(630282.45, 4834500, 51.63); 342 pt.SetIntensity(350); 343 pt.SetClassification(1); 344 pt.SetScanAngleRank(0); 345 pt.SetUserData(3); 346 pt.SetScanFlags(9); 347 pt.SetTime(413665.52880000003); 348 ensure(pt.IsValid()); 349 test_file10_point2(pt); 350 351 lasreader_iterator it(reader_); 352 lasreader_iterator end; 353 354 // find 2nd point data record 355 lasreader_iterator fit; 356 fit = std::find(it, end, pt); 357 ensure(fit != end); 358 test_file10_point2(*fit); 359 } 360 361 // Test std::find_if algorithm 362 template<> 363 template<> test()364 void to::test<21>() 365 { 366 lasreader_iterator it(reader_); 367 lasreader_iterator end; 368 369 // find 2nd point data record comparing XY coordinates 370 lasreader_iterator fit; 371 fit = std::find_if(it, end, is_xy(630282.45, 4834500, 0.0001)); 372 ensure(fit != end); 373 test_file10_point2(*fit); 374 } 375 376 // Test std::for_each algorithm 377 template<> 378 template<> test()379 void to::test<22>() 380 { 381 lasreader_iterator it(reader_); 382 lasreader_iterator end; 383 384 typedef liblas::Bounds<double> bbox_t; 385 386 Header const& h = reader_.GetHeader(); 387 bbox_t lasbbox = h.GetExtent(); 388 389 // Accumulate points extents to common bounding box 390 bbox_t accumulated; 391 std::for_each(it, end, bbox_calculator(accumulated)); 392 393 ensure(lasbbox == accumulated); 394 } 395 } 396