| 26 | } |
| 27 | |
| 28 | void Processor::Run(std::istream & is) |
| 29 | { |
| 30 | std::atomic<size_t> incomplete = 0; |
| 31 | size_t total = 0; |
| 32 | |
| 33 | std::string line; |
| 34 | while (std::getline(is, line)) |
| 35 | { |
| 36 | ++total; |
| 37 | |
| 38 | m_workers.SubmitWork([this, &incomplete, copy = std::move(line)]() mutable |
| 39 | { |
| 40 | std::string_view line = copy; |
| 41 | |
| 42 | // Remove possible trailing "\t\n" (pipe reading from tar). |
| 43 | size_t const i = line.rfind(')'); |
| 44 | if (i == std::string::npos) |
| 45 | { |
| 46 | LOG(LWARNING, ("Invalid string:", line)); |
| 47 | return; |
| 48 | } |
| 49 | line = line.substr(0, i + 1); |
| 50 | |
| 51 | tiger::AddressEntry e; |
| 52 | if (!tiger::ParseLine(line, e)) |
| 53 | { |
| 54 | LOG(LWARNING, ("Bad entry:", line)); |
| 55 | return; |
| 56 | } |
| 57 | |
| 58 | if (e.m_from.empty() || e.m_to.empty() || e.m_street.empty()) |
| 59 | { |
| 60 | ++incomplete; |
| 61 | return; |
| 62 | } |
| 63 | |
| 64 | std::vector<m2::PointD> points; |
| 65 | points.reserve(e.m_geom.size()); |
| 66 | for (auto const & ll : e.m_geom) |
| 67 | points.push_back(mercator::FromLatLon(ll)); |
| 68 | |
| 69 | auto const countries = m_affiliation.GetAffiliations(points); |
| 70 | |
| 71 | std::vector<int64_t> iPoints; |
| 72 | iPoints.reserve(points.size()); |
| 73 | for (auto const & p : points) |
| 74 | iPoints.push_back(PointToInt64Obsolete(p, kPointCoordBits)); |
| 75 | |
| 76 | std::lock_guard guard(m_mtx); |
| 77 | for (auto const & country : countries) |
| 78 | { |
| 79 | auto & writer = GetWriter(country); |
| 80 | e.Save(writer); |
| 81 | rw::Write(writer, iPoints); |
| 82 | } |
| 83 | }); |
| 84 | } |
| 85 | |