| 234 | } |
| 235 | |
| 236 | void GuidesConnections::ConnectToGuidesGraph(std::vector<m2::PointD> const & checkpoints) |
| 237 | { |
| 238 | PullCheckpointsToTracks(checkpoints); |
| 239 | |
| 240 | PullAdditionalCheckpointsToTracks(checkpoints); |
| 241 | |
| 242 | std::map<std::pair<kml::MarkGroupId, size_t>, Segment> addedTracks; |
| 243 | |
| 244 | for (auto const & [checkpointIdx, proj] : m_checkpointsOnTracks) |
| 245 | { |
| 246 | auto const & checkpoint = checkpoints[checkpointIdx]; |
| 247 | auto const & checkpointProj = proj.m_projectedPoint; |
| 248 | |
| 249 | Segment segmentOnTrack; |
| 250 | auto const [it, insertedSegment] = |
| 251 | addedTracks.emplace(std::make_pair(proj.m_guideId, proj.m_trackIdx), segmentOnTrack); |
| 252 | if (insertedSegment) |
| 253 | { |
| 254 | CHECK(!m_allTracks[proj.m_guideId][proj.m_trackIdx].empty(), |
| 255 | ("checkpointIdx:", checkpointIdx, "guideId:", proj.m_guideId, "trackIdx:", proj.m_trackIdx)); |
| 256 | |
| 257 | segmentOnTrack = m_graph.AddTrack(m_allTracks[proj.m_guideId][proj.m_trackIdx], proj.m_trackPointIdx); |
| 258 | it->second = segmentOnTrack; |
| 259 | } |
| 260 | else |
| 261 | { |
| 262 | segmentOnTrack = m_graph.FindSegment(it->second, proj.m_trackPointIdx); |
| 263 | } |
| 264 | FakeEnding const newEnding = m_graph.MakeFakeEnding(segmentOnTrack, checkpoint, checkpointProj); |
| 265 | auto const [itEnding, inserted] = m_checkpointsFakeEndings.emplace(checkpointIdx, newEnding); |
| 266 | |
| 267 | CHECK(inserted, (checkpointIdx)); |
| 268 | bool const fitsForOsmLink = !FitsForDirectLinkToGuide(checkpointIdx, checkpoints.size()); |
| 269 | |
| 270 | if (fitsForOsmLink) |
| 271 | AddConnectionToOsm(checkpointIdx, segmentOnTrack, checkpointProj, true /* fromCheckpoint */); |
| 272 | |
| 273 | // Connect to OSM start and finish points of the track. |
| 274 | auto const & firstPointOnTrack = m_allTracks[proj.m_guideId][proj.m_trackIdx][0]; |
| 275 | if (!(fitsForOsmLink && firstPointOnTrack == checkpointProj)) |
| 276 | { |
| 277 | auto const & firstSegmentOnTrack = m_graph.FindSegment(segmentOnTrack, 0); |
| 278 | AddConnectionToOsm(checkpointIdx, firstSegmentOnTrack, firstPointOnTrack, false /* fromCheckpoint */); |
| 279 | } |
| 280 | |
| 281 | auto const & lastPointIdx = m_allTracks[proj.m_guideId][proj.m_trackIdx].size() - 1; |
| 282 | auto const & lastPointOnTrack = m_allTracks[proj.m_guideId][proj.m_trackIdx][lastPointIdx]; |
| 283 | if (!(fitsForOsmLink && lastPointOnTrack == checkpointProj)) |
| 284 | { |
| 285 | auto const & lastSegmentOnTrack = m_graph.FindSegment(segmentOnTrack, lastPointIdx - 1); |
| 286 | AddConnectionToOsm(checkpointIdx, lastSegmentOnTrack, lastPointOnTrack, false /* fromCheckpoint */); |
| 287 | } |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | void GuidesConnections::AddConnectionToOsm(size_t checkpointIdx, Segment const & real, |
| 292 | geometry::PointWithAltitude const & loop, bool fromCheckpoint) |