| 135 | {} |
| 136 | |
| 137 | bool ScorePathsConnector::FindBestPath(vector<LocationReferencePoint> const & points, |
| 138 | vector<vector<ScorePath>> const & lineCandidates, LinearSegmentSource source, |
| 139 | vector<Graph::EdgeVector> & resultPath) |
| 140 | { |
| 141 | CHECK_NOT_EQUAL(source, LinearSegmentSource::NotValid, ()); |
| 142 | CHECK_GREATER_OR_EQUAL(points.size(), 2, ()); |
| 143 | |
| 144 | resultPath.resize(points.size() - 1); |
| 145 | |
| 146 | for (size_t i = 1; i < points.size(); ++i) |
| 147 | { |
| 148 | // @TODO It's possible that size of |points| is more then two. In that case two or more edges |
| 149 | // should be approximated with routes. If so only |toCandidates| which may be reached from |
| 150 | // |fromCandidates| should be used for the next edge. |
| 151 | |
| 152 | auto const & point = points[i - 1]; |
| 153 | auto const distanceToNextPoint = static_cast<double>(point.m_distanceToNextPoint); |
| 154 | auto const & fromCandidates = lineCandidates[i - 1]; |
| 155 | auto const & toCandidates = lineCandidates[i]; |
| 156 | auto & resultPathPart = resultPath[i - 1]; |
| 157 | |
| 158 | vector<ScorePath> result; |
| 159 | for (size_t fromInd = 0; fromInd < fromCandidates.size(); ++fromInd) |
| 160 | { |
| 161 | for (size_t toInd = 0; toInd < toCandidates.size(); ++toInd) |
| 162 | { |
| 163 | Graph::EdgeVector path; |
| 164 | if (!ConnectAdjacentCandidateLines(fromCandidates[fromInd].m_path, toCandidates[toInd].m_path, source, |
| 165 | point.m_lfrcnp, distanceToNextPoint, path)) |
| 166 | { |
| 167 | continue; |
| 168 | } |
| 169 | |
| 170 | Score pathLenScore = 0; |
| 171 | if (!ValidatePathByLength(path, distanceToNextPoint, source, pathLenScore)) |
| 172 | continue; |
| 173 | |
| 174 | auto const score = |
| 175 | pathLenScore + GetScoreForUniformity(path) + fromCandidates[fromInd].m_score + toCandidates[toInd].m_score; |
| 176 | result.emplace_back(score, std::move(path)); |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | for (auto const & p : result) |
| 181 | CHECK(!p.m_path.empty(), ()); |
| 182 | |
| 183 | if (result.empty()) |
| 184 | { |
| 185 | LOG(LINFO, ("No shortest path found")); |
| 186 | ++m_stat.m_noShortestPathFound; |
| 187 | resultPathPart.clear(); |
| 188 | return false; |
| 189 | } |
| 190 | |
| 191 | auto const it = max_element(result.cbegin(), result.cend(), |
| 192 | [](ScorePath const & o1, ScorePath const & o2) { return o1.m_score < o2.m_score; }); |
| 193 | |
| 194 | // Note. In case of source == LinearSegmentSource::FromCoordinatesTag there is less |
no test coverage detected