public static void SetAsTriangleEdge(double d2, Edge currentEdge, Edge nextEdge) { Vertice start = currentEdge.Start; Vertice middle = currentEdge.End; Vertice end = nextEdge.End; (double, double)nextLine = Line.GetStraightLine(end, middle); (double, double)straightLine = Line.GetStraightLine(end, start); double cos = Angle.GetCosinusFromBetween(nextLine, straightLine); double d = DistanceHelpers.DistanceBetween(start, end); double sqrtDelta = Math.Sqrt(Math.Pow(2 * d * cos, 2) - 4 * (d * d * d2 * d2)); double x1 = (-2 * d * cos - sqrtDelta) / 2; double x2 = (-2 * d * cos + sqrtDelta) / 2; double x = Math.Min(x1, x2); if (x < 0) { x = Math.Max(x1, x2); } (Vertice, Vertice)vertices = PointHelpers.GetPointFromLineDistanceAndPoint(nextLine, x, end); Vertice resultVertice = DistanceHelpers.GetCloserVerticeFromVertice(vertices, start); if (resultVertice.x < int.MinValue + 100 || resultVertice.y > int.MaxValue - 100 || resultVertice.y < int.MinValue + 100 || resultVertice.y > int.MaxValue - 100) { int xdddd = 2; } PointHelpers.SetPointXY(middle, resultVertice.x, resultVertice.y); }
public static void SetPerpednicular(Edge siblingEdge, Edge currentEdge, Edge nextEdge) { Vertice start = currentEdge.Start; Vertice middle = currentEdge.End; Vertice end = nextEdge.End; double d = DistanceHelpers.GetEdgeLength(siblingEdge); (double, double)line = Line.GetStraightLine(siblingEdge.Start, siblingEdge.End); (Vertice, Vertice)vertices; if (line.Item1 == 0) { vertices = (new Vertice(start.x, start.y - (int)d), new Vertice(start.x, start.y + (int)d)); } else if (line.Item1 > int.MaxValue - 100 || line.Item1 < int.MinValue + 100) { vertices = (new Vertice(start.x - (int)d, start.y), new Vertice(start.x + (int)d, start.y)); } else { (double, double)perpendicularLine = Line.GetPerpendicularThroughPoint(line, start); vertices = PointHelpers.GetPointFromLineDistanceAndPoint(perpendicularLine, d, start); } Vertice resultVertice = DistanceHelpers.GetCloserVerticeFromVertice(vertices, middle); PointHelpers.SetPointXY(middle, resultVertice.x, resultVertice.y); }
private static void UpdateNeighbours(RouteFeature[] features) { Console.WriteLine("Updating feature neigbours"); double amount = 0, temp = 0, all = features.Length; for (var i = 0; i < features.Length - 1; i++) { amount++; temp++; if (temp > all / 100) { Console.WriteLine(Math.Round(amount / all * 100, 2)); temp = 0; } for (var j = i + 1; j < features.Length; j++) { if (DistanceHelpers.AreNeighbours(features[i].Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), features[j].Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray())) { features[i].Neighbours.Add(features[j]); features[j].Neighbours.Add(features[i]); } } } }
private static RouteFeature[] GetBorderFeatures(RouteFeature[] features, PointPosition[] border) { return(features.Where(f => DistanceHelpers.SplitFeatureIntoLineSegments(border.Select(x => x.ToDoubleArray()).ToArray()).Any(x => DistanceHelpers.IsCloseToLine(x, f.Data.Coordinates.First().ToDoubleArray()) || DistanceHelpers.IsCloseToLine(x, f.Data.Coordinates.Last().ToDoubleArray()))).ToArray()); }
private void RecalculateLength(RouteDTO route) { var length = 0d; foreach (var s in DistanceHelpers.SplitFeatureIntoLineSegments(route.Data.Coordinates)) { length += DistanceHelpers.DistanceBetweenCoordinates(s.Item1, s.Item2); } route.Info.Length = Math.Round(length, 2); }
public void LocationDisplayModelComparerClassCompareMethodReturnsOneIfConstructedForDownFirstParameterIsNotNullAndSecondParameterIsNull() { LocationDisplayModelComparer comparer = new LocationDisplayModelComparer(Direction.Down); LocationDisplayModel location = new LocationDisplayModel { Mileage = DistanceHelpers.GetDistance() }; int result = comparer.Compare(location, null); Assert.AreEqual(1, result); }
private GridCell FindGridCell(double[] requestStart) { foreach (var g in _grid) { if (DistanceHelpers.IsInside(requestStart, g.Border.Select(x => x.ToDoubleArray()).ToArray())) { return(g); } } throw new Exception(); }
public void LocationDisplayModelComparerClassCompareMethodReturnsOneIfConstructedForUpAndFirstParameterHasLowerMileageThanSecondParameter() { LocationDisplayModelComparer comparer = new LocationDisplayModelComparer(Direction.Up); LocationDisplayModel x = new LocationDisplayModel { Mileage = DistanceHelpers.GetDistance() }; LocationDisplayModel y = new LocationDisplayModel { Mileage = DistanceHelpers.GetDistanceGreaterThan(x.Mileage) }; int result = comparer.Compare(x, y); Assert.AreEqual(1, result); }
private int SaveRide(int userId, CreateRideDto model) { var routeSvgPath = new SvgBuilder(model.Locations.Cast <ILatLng>()).Build(); Ride ride = new Ride(); ride.StartUtc = model.StartUtc; ride.EndUtc = model.EndUtc; ride.UserId = userId; ride.AverageSpeedMph = model.Locations.Average(i => i.Mph); ride.MaxSpeedMph = model.Locations.Max(i => i.Mph); ride.DistanceMiles = DistanceHelpers.GetDistanceMile(model.Locations.Cast <ILatLng>().ToList()); ride.RouteSvgPath = routeSvgPath; ride.RideLocations = model.Locations .Select(i => new RideLocation { AccuracyInMetres = i.AccuracyInMetres, Altitude = i.Altitude, Latitude = i.Latitude, Longitude = i.Longitude, Mph = i.Mph, Timestamp = i.Timestamp, }) .ToList(); ride.Jumps = model.Jumps .Select(i => new Jump { Airtime = i.Airtime, Number = i.Number, Timestamp = i.Timestamp, Latitude = i.Latitude, Longitude = i.Longitude, }) .ToList(); ride.AccelerometerReadings = model.AccelerometerReadings .Select(i => new AccelerometerReading { Time = i.Timestamp, X = i.X, Y = i.Y, Z = i.Z, }) .ToList(); context.Rides.Add(ride); context.SaveChanges(); return(ride.RideId); }
public static void SetOnLineBetween(double d, Edge currentEdge, Edge nextEdge) { Vertice start = currentEdge.Start; Vertice middle = currentEdge.End; Vertice end = nextEdge.End; double distance = DistanceHelpers.DistanceBetween(start, end); double proportion = d / distance; Vertice resultVertice = PointHelpers.GetPointInProportion(proportion, start, end); if (resultVertice.x < int.MinValue + 100 || resultVertice.y > int.MaxValue - 100 || resultVertice.y < int.MinValue + 100 || resultVertice.y > int.MaxValue - 100) { int xdddd = 2; } PointHelpers.SetPointXY(middle, resultVertice.x, resultVertice.y); }
public static void ShortenLineForEdge(double d, Edge currentEdge, Edge nextEdge) { Vertice start = currentEdge.Start; Vertice middle = currentEdge.End; Vertice end = nextEdge.End; Vertice helper = new Vertice(end.x - CONST.ShortenLineForEdgeDistance, end.y - CONST.ShortenLineForEdgeDistance); (double, double)lineHelp = Line.GetStraightLine(helper, end); Vertice resultVertice = PointHelpers.GetPointInProportion(1 / 2, helper, end); (double, double)line = Line.GetStraightLine(start, resultVertice); (Vertice, Vertice)midVertices = PointHelpers.GetPointFromLineDistanceAndPoint(line, d, currentEdge.Start); Vertice midVertice = DistanceHelpers.GetCloserVerticeFromLine(lineHelp, midVertices); PointHelpers.SetPointXY(middle, midVertice.x, midVertice.y); }
public static void SetAsTriangleLength(double d, Edge currentEdge, Edge nextEdge) { Vertice start = currentEdge.Start; Vertice middle = currentEdge.End; Vertice end = nextEdge.End; double d2 = DistanceHelpers.GetEdgeLength(nextEdge); double distance = DistanceHelpers.DistanceBetween(start, end); double triangleArea = Triangle.TriangleArea(d, d2, distance); Vertice missingPoint = Triangle.GetPointFromTriangleArea(triangleArea, start, end, d, d2); if (missingPoint.x < int.MinValue + 100 || missingPoint.y > int.MaxValue - 100 || missingPoint.y < int.MinValue + 100 || missingPoint.y > int.MaxValue - 100) { int xdddd = 2; } PointHelpers.SetPointXY(middle, missingPoint.x, missingPoint.y); }
public void LocationDisplayModelComparerClassCompareMethodReturnsMinusOneIfConstructedForDownAndParametersHaveSameMileageAndFirstParameterIsArrivalRowAndSecondParameterIsDepartureRow() { LocationDisplayModelComparer comparer = new LocationDisplayModelComparer(Direction.Down); LocationDisplayModel x = new LocationDisplayModel { Mileage = DistanceHelpers.GetDistance(), LocationKey = _rnd.NextHexString(8) + "-a" }; LocationDisplayModel y = new LocationDisplayModel { Mileage = new Distance { Mileage = x.Mileage.Mileage, Chainage = x.Mileage.Chainage }, LocationKey = _rnd.NextHexString(8) + "-d" }; int result = comparer.Compare(x, y); Assert.AreEqual(-1, result); }
public bool IsEqualRelation(Edge e1, Edge e2) { //Because of unencountered exceptions sometimes xD if ((int)DistanceHelpers.GetEdgeLength(e1) - (int)DistanceHelpers.GetEdgeLength(e2) == int.MinValue) { return(false); } int dist = Math.Abs((int)DistanceHelpers.GetEdgeLength(e1) - (int)DistanceHelpers.GetEdgeLength(e2)); if (dist < CONST.differenceToMakeEdgesEqual) { return(true); } else { return(false); } }
private static void Main() { // create a test list of tunnel locations var tunnelList = new List <Tunnel> { new Tunnel { Location = new Location { Latitude = 1, Longitude = 6, }, Length = 2, }, new Tunnel { Location = new Location { Latitude = 7, Longitude = 3, }, Length = 8, }, new Tunnel { Location = new Location { Latitude = 4, Longitude = 1, }, Length = 3, }, }; var startLocation = new Location { Latitude = 7, Longitude = 2 }; var endLocation = new Location { Latitude = 1, Longitude = 8 }; var minimumDistance = DistanceHelpers.CalculateShortestPathTotal(startLocation, endLocation, tunnelList); }
private RouteFeature FindClosetFeature(double[] p, RouteFeature[] features) { var closet = features.First(); var dist = DistanceHelpers.CalcualteDistanceToFeatureInMeters( closet.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), p); foreach (var f in features.Skip(1)) { var newDistance = DistanceHelpers.CalcualteDistanceToFeatureInMeters( f.Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), p); if (newDistance < dist) { dist = newDistance; closet = f; } } return(closet); }
private void CheckIfAllPoinsInsidePolygon(RouteSearchRequestDTO request) { var polygon = request.PolygonPoints.Select(x => x.ToDoubleArray()).ToArray(); foreach (var p in request.Points) { if (!DistanceHelpers.IsInside(p.ToDoubleArray(), polygon)) { throw new Exception("Ne visi tarpiniai taškai patenka į apibrėžtą poligoną"); } } if (!DistanceHelpers.IsInside(request.Start.ToDoubleArray(), polygon)) { throw new Exception("Pradžia nepatenka į apibrėžtą poligoną"); } if (!DistanceHelpers.IsInside(request.End.ToDoubleArray(), polygon)) { throw new Exception("Pabaiga nepatenka į apibrėžtą poligoną"); } }
//TODO optimize for neigboring cells private void UpdateNeighbours(Dictionary <string, CellData> cellToFeatures, GridCell cell) { //Console.WriteLine("Updating feature neigbhours"); var neighbourinCells = GetTempGridCells(new[] { cell }); double amount = 0, temp = 0, all = cellToFeatures[cell.Index].BorderFeatures.Length; var newFeatures = cellToFeatures[cell.Index].BorderFeatures; var borderFeatures = cellToFeatures.Where(x => x.Key != cell.Index && neighbourinCells.Any(y => y.Index == x.Key)).SelectMany(x => x.Value.BorderFeatures) .ToArray(); for (var i = 0; i < all; i++) { amount++; temp++; if (temp > all / 100) { //Console.WriteLine(Math.Round(amount / all * 100, 2)); temp = 0; } for (var j = 0; j < borderFeatures.Length; j++) { if (DistanceHelpers.AreNeighbours( newFeatures[i].Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray(), borderFeatures[j].Data.Coordinates.Select(x => x.ToDoubleArray()).ToArray())) { newFeatures[i].Neighbours.Add(borderFeatures[j]); borderFeatures[j].Neighbours.Add(newFeatures[i]); } } } }
public static void SetPerpednicularNextEqual(Edge siblingEdge, Edge currentEdge, Edge nextEdge) { Vertice start = currentEdge.Start; Vertice middle = currentEdge.End; Vertice end = nextEdge.End; double d = DistanceHelpers.GetEdgeLength(siblingEdge); double d2 = DistanceHelpers.GetEdgeLength(nextEdge); (double, double)line = Line.GetStraightLine(siblingEdge.Start, siblingEdge.End); (double, double)distanceLine = Line.GetStraightLine(start, end); (Vertice, Vertice)vertices = (null, null); if (line.Item1 != 0 && line.Item1 < int.MaxValue - 100 && line.Item1 > int.MinValue + 100) { (double, double)perpendicularLine = Line.GetPerpendicularThroughPoint(line, start); if (d2 < Line.DistanceVerticeFromLine(perpendicularLine, end)) { d2 = Line.DistanceVerticeFromLine(perpendicularLine, end) + 1; } double cos = Angle.GetCosinusFromBetween(perpendicularLine, distanceLine); double sqrtDelta = Math.Sqrt(Math.Pow(2 * d * cos, 2) - 4 * (d * d - d2 * d2)); double x1 = (2 * d * cos - sqrtDelta) / 2; double x2 = (2 * d * cos + sqrtDelta) / 2; double x = Math.Min(x1, x2); if (x < 0) { x = Math.Max(x1, x2); } vertices = PointHelpers.GetPointFromLineDistanceAndPoint(perpendicularLine, x, start); Vertice resultVertice = DistanceHelpers.GetCloserVerticeFromVertice(vertices, end); PointHelpers.SetPointXY(middle, resultVertice.x, resultVertice.y); } else { SetPerpednicularNextPerpendicular(siblingEdge, currentEdge, nextEdge); } }
//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 void CanGetShortestPath(Location startLocation, Location endLocation, List <Tunnel> tunnelList, int expected) { var result = DistanceHelpers.CalculateShortestPathTotal(startLocation, endLocation, tunnelList); Assert.Equal(expected, result); }
public void CanCalculateManhattanDistance(int value1, int value2, int value3, int value4, int expected) { var result = DistanceHelpers.CalculateManhattanDistance(value1, value2, value3, value4); Assert.Equal(expected, result); }
public RouteSearchResponseDTO FindRoute2(RouteSearchRequestDTO request) { if (request.Start == null) { throw new Exception("Maršruto pradžios taškas turi būti nurodytas"); } if (request.End == null) { throw new Exception("Maršruto pabaigos taškas turi būti nurodytas"); } if (request.PolygonPoints.Length < 4) { throw new Exception("Turėtų būti bent 3 duomenų ribokliai"); } CheckIfAllPoinsInsidePolygon(request); var line = new[] { request.Start.ToDoubleArray() }.Concat(request.Points.Select(x => x.ToDoubleArray())) .Concat(new[] { request.End.ToDoubleArray() }).ToArray(); var segments = DistanceHelpers.SplitFeatureIntoLineSegments(line); var usedFeatures = new List <RouteFeature>(); RouteDTO route = null; foreach (var s in segments) { var loadedData = Loader.LoadDataBetweenTwoPoints(s.Item1, s.Item2, request.PolygonPoints.Select(x => x.ToDoubleArray()).ToArray()); var graph = new Graph(loadedData.AllFeatures, request.SearchOptions); var path = graph.FindShortestPath(loadedData.StartFeature, loadedData.EndFeature, usedFeatures); if (path == null) { throw new Exception("Kelias nerastas"); } usedFeatures.AddRange(path); var tempRoute = PathToRoute(path, new PointPosition { Latitude = s.Item1[1], Longitude = s.Item1[0] }, new PointPosition { Latitude = s.Item2[1], Longitude = s.Item2[0] }); route = MergeTwoRoutes(route, tempRoute); } RecalculateLength(route); return(new RouteSearchResponseDTO(new[] { route })); }
public LoadedData2 LoadDataBetweenTwoPoints(double[] start, double[] end, double[][] polygonPoints) { var cellSequence = new List <GridCell>(); var startGridCell = FindGridCell(start); var endGridCell = FindGridCell(end); cellSequence.Add(startGridCell); if (startGridCell.Index != endGridCell.Index) { cellSequence.Add(endGridCell); } if (!cellToFeatures.ContainsKey(startGridCell.Index)) { cellToFeatures[startGridCell.Index] = ReadCellData(startGridCell.Index); UpdateNeighbours(cellToFeatures, startGridCell); } if (!cellToFeatures.ContainsKey(endGridCell.Index)) { cellToFeatures[endGridCell.Index] = ReadCellData(endGridCell.Index); UpdateNeighbours(cellToFeatures, endGridCell); } var tempGridCells = GetTempGridCells(cellSequence.ToArray()); foreach (var c in tempGridCells) { if (!cellToFeatures.ContainsKey(c.Index)) { cellToFeatures[c.Index] = ReadCellData(c.Index); UpdateNeighbours(cellToFeatures, c); } cellSequence.Add(c); } var result = new List <RouteFeature>(); //double diff = 6000; //var count = 0; //DistanceHelpers.DistanceBetweenCoordinates(); foreach (var c in cellSequence) { //count += cellToFeatures[c.Index].Features.Length; //how much we will save result.AddRange(cellToFeatures[c.Index].Features); //foreach (var f in cellToFeatures[c.Index].Features) //{ // var cord = f.Data.Coordinates.Skip(f.Data.Coordinates.Length / 2).FirstOrDefault().ToDoubleArray(); // var projection = DistanceHelpers.GetProjectionOnLine(new Tuple<double[], double[]>(start, end), cord); // if (DistanceHelpers.DistanceBetweenCoordinates(projection, cord) < diff) // { // result.Add(f); // } //} } return(new LoadedData2() { StartFeature = FindClosetFeature(start, cellToFeatures[startGridCell.Index].Features), EndFeature = FindClosetFeature(end, cellToFeatures[endGridCell.Index].Features), AllFeatures = polygonPoints.Length == 0 ? result.ToArray() : result.Where(x => DistanceHelpers.IsInside(x.Data.Coordinates.First().ToDoubleArray(), polygonPoints) || DistanceHelpers.IsInside(x.Data.Coordinates.Last().ToDoubleArray(), polygonPoints)).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); }