/// <summary> /// Snaps track to OSM roads. Returns a list of snapped geometries - if it fails to find one continuous OSM geometry corresponding to the track, the list contain more than one geometry. /// </summary> /// <param name="track"></param> /// <param name="timeStamps"></param> /// <param name="highwayTags"></param> /// <param name="railTags"></param> /// <returns> List of snapped geometries. If it fails to find one continuous OSM geometry corresponding to the track, the list contains more than one geometry. Otherwise count = 1</returns> public List <List <Coord> > SnapDat(IEnumerable <Coord> track, IEnumerable <DateTime> timeStamps = null, bool highwayTags = true, bool railTags = true, bool ignoreOneWays = false) { if (track.Count() < 2) { return(new List <List <Coord> >() { track.ToList() }); } var result = new List <List <Coord> >(); // Initialize total snap time stopwatch var totalTimeStopwatch = new System.Diagnostics.Stopwatch(); totalTimeStopwatch.Start(); OsmMapMatcher mapMatcher;//= new MapMatcher(osmGraph); if (MapMatcher == null) { // Build graph in region and initialize map matcher var boundingBoxes = track.GetSmartBoundingBoxes(); var osmGraph = OsmGraphBuilder.BuildInRegion(_overpassApi, boundingBoxes, highwayTags, railTags, ignoreOneWays); mapMatcher = new OsmMapMatcher(osmGraph, Parameters, _useSearchGrid); } else { mapMatcher = MapMatcher.Clone(); } // Initialize snap time stopwatch var performSnapStopwatch = new System.Diagnostics.Stopwatch(); performSnapStopwatch.Start(); // Clean input co-ordinates var cleanedCoords = track.GetCleanedCoordinates(timeStamps); // Initialize snap summary & list for update times SnapSummary = new SnapSummary(); SnapSummary.UpdateCount = cleanedCoords.Count; var updateTimesInMilliseconds = new List <double>(); int startIndex = 0; int breakIndex = 0; for (int i = 0; i < cleanedCoords.Count; i++) { Coord coord = cleanedCoords[i]; if (mapMatcher.TryUpdateState(coord, printUpdateAnalyticsToConsole: _printConsoleUpdates)) { updateTimesInMilliseconds.Add(mapMatcher.UpdateInfo.UpdateTimeInMilliseconds); } else { SnapSummary.BreakCount += 1; breakIndex = i; if (startIndex < breakIndex) { var shape = GetSnappedSection(mapMatcher, cleanedCoords, startIndex, breakIndex); result.Add(shape); } startIndex = i + 1; mapMatcher.Reset(); } } if (startIndex < cleanedCoords.Count - 1) { var lastShape = GetSnappedSection(mapMatcher, cleanedCoords, startIndex, cleanedCoords.Count - 1); result.Add(lastShape); } // Snap summary values performSnapStopwatch.Stop(); SnapSummary.PerformSnapTimeInSeconds = performSnapStopwatch.Elapsed.TotalSeconds; totalTimeStopwatch.Stop(); SnapSummary.TotalSnapTimeInSeconds = totalTimeStopwatch.Elapsed.TotalSeconds; SnapSummary.MeanUpdateTimeInMilliseconds = updateTimesInMilliseconds.Average(); // Print summary info to the console SnapSummary.PrintSummaryToConsole(); return(result); }