/// <summary> /// Snaps to an edge closest to the given coordinates. /// </summary> /// <param name="routerDb">The router db.</param> /// <param name="longitude">The longitude.</param> /// <param name="latitude">The latitude.</param> /// <param name="maxOffsetInMeter">The maximum offset in meter.</param> /// <param name="profile">The profile to snap for.</param> /// <returns>The snap point.</returns> public static Result <SnapPoint> Snap(this RouterDb routerDb, double longitude, double latitude, float maxOffsetInMeter = 1000, Profile profile = null) { ProfileHandler profileHandler = null; if (profile != null) { profileHandler = routerDb.GetProfileHandler(profile); } var offset = 100; while (offset < maxOffsetInMeter) { // calculate search box. var offsets = (new Coordinate(longitude, latitude)).OffsetWithDistances(maxOffsetInMeter); var latitudeOffset = System.Math.Abs(latitude - offsets.Latitude); var longitudeOffset = System.Math.Abs(longitude - offsets.Longitude); var box = (longitude - longitudeOffset, latitude - latitudeOffset, longitude + longitudeOffset, latitude + latitudeOffset); // make sure data is loaded. routerDb.DataProvider?.TouchBox(box); // snap to closest edge. var snapPoint = routerDb.SnapInBox(box, (eEnum) => { if (profileHandler == null) { return(true); } profileHandler.MoveTo(eEnum); var canStop = profileHandler.CanStop; return(canStop); }); if (snapPoint.EdgeId != uint.MaxValue) { return(snapPoint); } offset *= 2; } return(new Result <SnapPoint>($"Could not snap to location: {longitude},{latitude}")); }