| 445 | } |
| 446 | |
| 447 | void BuildAddressTable(FilesContainerR & container, std::string const & addressDataFile, Writer & streetsWriter, |
| 448 | Writer & placesWriter, uint32_t threadsCount) |
| 449 | { |
| 450 | std::vector<feature::AddressData> addrs; |
| 451 | ReadAddressData(addressDataFile, addrs); |
| 452 | |
| 453 | auto const featuresCount = base::checked_cast<uint32_t>(addrs.size()); |
| 454 | |
| 455 | // Initialize temporary source for the current mwm file. |
| 456 | FrozenDataSource dataSource; |
| 457 | MwmSet::MwmId mwmId; |
| 458 | { |
| 459 | auto const regResult = dataSource.RegisterMap(platform::LocalCountryFile::MakeTemporary(container.GetFileName())); |
| 460 | ASSERT_EQUAL(regResult.second, MwmSet::RegResult::Success, ()); |
| 461 | mwmId = regResult.first; |
| 462 | } |
| 463 | |
| 464 | std::vector<std::unique_ptr<search::MwmContext>> contexts(threadsCount); |
| 465 | |
| 466 | std::atomic<uint32_t> address = 0; |
| 467 | std::atomic<uint32_t> missing = 0; |
| 468 | |
| 469 | /// @see Addr_Street_Place test for checking constants. |
| 470 | double constexpr kStreetRadiusM = 2000; |
| 471 | double constexpr kPlaceRadiusM = 4000; |
| 472 | |
| 473 | std::vector<uint32_t> streets(featuresCount, kInvalidFeatureId); |
| 474 | std::vector<uint32_t> places(featuresCount, kInvalidFeatureId); |
| 475 | |
| 476 | // Thread working function. |
| 477 | auto const fn = [&](uint32_t threadIdx) |
| 478 | { |
| 479 | auto const fc = static_cast<uint64_t>(featuresCount); |
| 480 | auto const beg = static_cast<uint32_t>(fc * threadIdx / threadsCount); |
| 481 | auto const end = static_cast<uint32_t>(fc * (threadIdx + 1) / threadsCount); |
| 482 | |
| 483 | for (uint32_t i = beg; i < end; ++i) |
| 484 | { |
| 485 | auto const street = addrs[i].Get(feature::AddressData::Type::Street); |
| 486 | auto const place = addrs[i].Get(feature::AddressData::Type::Place); |
| 487 | if (street.empty() && place.empty()) |
| 488 | continue; |
| 489 | |
| 490 | ++address; |
| 491 | |
| 492 | std::optional<uint32_t> streetId, placeId; |
| 493 | |
| 494 | auto ft = contexts[threadIdx]->GetFeature(i); |
| 495 | CHECK(ft, ()); |
| 496 | auto const center = feature::GetCenter(*ft); |
| 497 | |
| 498 | if (!street.empty()) |
| 499 | { |
| 500 | auto const streets = |
| 501 | search::ReverseGeocoder::GetNearbyStreets(*contexts[threadIdx], center, kStreetRadiusM, true); |
| 502 | streetId = MatchObjectByName(street, streets, [](std::string_view name) |
| 503 | { return search::GetStreetNameAsKey(name, false /* ignoreStreetSynonyms */); }); |
| 504 |
no test coverage detected