//private double[][] SorthPath(IList<double[][]> path) //{ // var tempPat = new List<double[][]>(path); // var lastSubPath = tempPat.First(); // tempPat.Remove(lastSubPath); // IEnumerable<double[]> coordinates = lastSubPath; // while (tempPat.Any()) // { // var newLastSubPath = // tempPat.FirstOrDefault(x => DistanceHelpers.AreClose(x.First(), coordinates.First())); // if (newLastSubPath != null) // { // tempPat.Remove(newLastSubPath); // coordinates = newLastSubPath.Reverse().Concat(coordinates); // continue; // } // newLastSubPath = tempPat.FirstOrDefault(x => DistanceHelpers.AreClose(x.First(), coordinates.Last())); // if (newLastSubPath != null) // { // tempPat.Remove(newLastSubPath); // coordinates = coordinates.Concat(newLastSubPath); // continue; // } // newLastSubPath = tempPat.FirstOrDefault(x => DistanceHelpers.AreClose(x.Last(), coordinates.First())); // if (newLastSubPath != null) // { // tempPat.Remove(newLastSubPath); // coordinates = newLastSubPath.Concat(coordinates); // continue; // } // newLastSubPath = tempPat.FirstOrDefault(x => DistanceHelpers.AreClose(x.Last(), coordinates.Last())); // if (newLastSubPath != null) // { // tempPat.Remove(newLastSubPath); // coordinates = coordinates.Concat(newLastSubPath.Reverse()); // continue; // } // throw new Exception("Something went wrong at path sorting"); // } // if (!coordinates.First().SequenceEqual(path.First().First())) coordinates = coordinates.Reverse(); // return coordinates.ToArray(); //} public static IList <RouteFeature> SortFeatures(List <RouteFeature> path, PointPosition startPosition, PointPosition endPosition) { var tempPat = new List <RouteFeature>(path); var lastSubPath = tempPat.First(); tempPat.Remove(lastSubPath); IEnumerable <RouteFeature> routeFeatures = new List <RouteFeature> { lastSubPath }; while (tempPat.Any()) { var newLastSubPath = tempPat.FirstOrDefault(x => DistanceHelpers.AreClose(x.Data.Coordinates.First().ToDoubleArray(), routeFeatures.First().Data.Coordinates.First().ToDoubleArray())); if (newLastSubPath != null) { tempPat.Remove(newLastSubPath); var result = new List <RouteFeature> { newLastSubPath }; result.AddRange(routeFeatures); newLastSubPath.Data.Coordinates = newLastSubPath.Data.Coordinates.Reverse().ToArray(); routeFeatures = result; continue; } newLastSubPath = tempPat.FirstOrDefault(x => DistanceHelpers.AreClose(x.Data.Coordinates.First().ToDoubleArray(), routeFeatures.Last().Data.Coordinates.Last().ToDoubleArray())); if (newLastSubPath != null) { tempPat.Remove(newLastSubPath); var result = new List <RouteFeature>(); result.AddRange(routeFeatures); result.Add(newLastSubPath); routeFeatures = result; continue; } newLastSubPath = tempPat.FirstOrDefault(x => DistanceHelpers.AreClose(x.Data.Coordinates.Last().ToDoubleArray(), routeFeatures.First().Data.Coordinates.First().ToDoubleArray())); if (newLastSubPath != null) { tempPat.Remove(newLastSubPath); var result = new List <RouteFeature> { newLastSubPath }; result.AddRange(routeFeatures); routeFeatures = result; continue; } newLastSubPath = tempPat.FirstOrDefault(x => DistanceHelpers.AreClose(x.Data.Coordinates.Last().ToDoubleArray(), routeFeatures.Last().Data.Coordinates.Last().ToDoubleArray())); if (newLastSubPath != null) { tempPat.Remove(newLastSubPath); var result = new List <RouteFeature>(); result.AddRange(routeFeatures); result.Add(newLastSubPath); newLastSubPath.Data.Coordinates = newLastSubPath.Data.Coordinates.Reverse().ToArray(); routeFeatures = result; continue; } throw new Exception("Something went wrong at feature sorting"); } if (!routeFeatures.First().Data.Coordinates.First().ToDoubleArray() .SequenceEqual(path.First().Data.Coordinates.First().ToDoubleArray())) { routeFeatures = routeFeatures.Reverse(); foreach (var f in routeFeatures) { f.Data.Coordinates = f.Data.Coordinates.Reverse().ToArray(); } } else if (routeFeatures.Count() == 1) { var projectionStart = DistanceHelpers.GetProjectionOnFeature( routeFeatures.First().Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), startPosition.ToDoubleArray()); var projectionEnd = DistanceHelpers.GetProjectionOnFeature( routeFeatures.First().Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), endPosition.ToDoubleArray()); var featureSegments = DistanceHelpers.SplitFeatureIntoLineSegments(routeFeatures.First().Data .Coordinates.Select(x => x.ToDoubleArray()).ToArray()); var indexStart = FindIndex(projectionStart.Item1, featureSegments); var indexEnd = FindIndex(projectionEnd.Item1, featureSegments); if (indexEnd < indexStart) { routeFeatures.First().Data.Coordinates = routeFeatures.First().Data.Coordinates.Reverse().ToArray(); } } return(routeFeatures.ToArray()); }
public static RouteDTO PathToRoute(List <RouteFeature> path, PointPosition startPosition, PointPosition endPosition) { var sortedFeatures = SortFeatures(path, startPosition, endPosition); var routeDto = new RouteDTO { Data = new RouteDataDTO { Type = "LineString", Coordinates = sortedFeatures.SelectMany(x => x.Data.Coordinates.Select(y => new[] { y.Longitude, y.Latitude }) .ToArray()).ToArray() }, Info = new RouteInfoDTO { Length = 0 //Length = Math.Round(path.Sum(x => (double) x.Data.Properties["lenght"]), 2) //TODO fix } }; var routeJson = routeDto.ToGeoJson(); var firstFeature = sortedFeatures.First(); var lastFeature = sortedFeatures.Last(); var firstFeatureJson = FeaturesToGeojsonHelper.ToGeojson(new [] { firstFeature.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray() }); var lastFeatureJson = FeaturesToGeojsonHelper.ToGeojson(new [] { lastFeature.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray() }); //var distanceToStartFeature = DistanceHelpers.CalcualteDistanceToFeature( // firstFeature.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), startPosition.ToDoubleArray()); var projectionOnStartFeature = DistanceHelpers.GetProjectionOnFeature( firstFeature.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), startPosition.ToDoubleArray()); var distanceToStartProjection = DistanceHelpers.DistanceBetweenCoordinates(projectionOnStartFeature.Item2, startPosition.ToDoubleArray()); if (( distanceToStartProjection != DistanceHelpers.DistanceBetweenCoordinates(startPosition.ToDoubleArray(), firstFeature.Data.Coordinates.First().ToDoubleArray()) && distanceToStartProjection != DistanceHelpers.DistanceBetweenCoordinates(startPosition.ToDoubleArray(), firstFeature.Data.Coordinates.Last().ToDoubleArray()) ) || (distanceToStartProjection == DistanceHelpers.DistanceBetweenCoordinates( startPosition.ToDoubleArray(), firstFeature.Data.Coordinates.Last().ToDoubleArray())) ) { //var projectionResult = DistanceHelpers.GetProjectionOnFeature( // firstFeature.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), // startPosition.ToDoubleArray()); var result = new List <double[]> { projectionOnStartFeature.Item2 }; var index = Array.FindIndex(routeDto.Data.Coordinates, x => x.SequenceEqual(projectionOnStartFeature.Item1.Item1)); result.AddRange(routeDto.Data.Coordinates.Skip(index + 1)); routeDto.Data.Coordinates = result.ToArray(); } var projectionOnEndFeature = DistanceHelpers.GetProjectionOnFeature( lastFeature.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), endPosition.ToDoubleArray()); var distanceToEndProjection = DistanceHelpers.DistanceBetweenCoordinates(projectionOnEndFeature.Item2, endPosition.ToDoubleArray()); if ((distanceToEndProjection != DistanceHelpers.DistanceBetweenCoordinates(endPosition.ToDoubleArray(), lastFeature.Data.Coordinates.First().ToDoubleArray()) && distanceToEndProjection != DistanceHelpers.DistanceBetweenCoordinates(endPosition.ToDoubleArray(), lastFeature.Data.Coordinates.Last().ToDoubleArray())) || (distanceToEndProjection == DistanceHelpers.DistanceBetweenCoordinates( endPosition.ToDoubleArray(), lastFeature.Data.Coordinates.First().ToDoubleArray())) ) { //var projectionResult = DistanceHelpers.GetProjectionOnFeature( // lastFeature.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), endPosition.ToDoubleArray()); var index = Array.FindIndex(routeDto.Data.Coordinates, x => x.SequenceEqual(projectionOnEndFeature.Item1.Item2)); var result = routeDto.Data.Coordinates.Take(index).ToList(); result.Add(projectionOnEndFeature.Item2); routeDto.Data.Coordinates = result.ToArray(); } return(routeDto); }