AddCoordinatesInBetween(List <SegmentCoordinate> coordinates, double minDistance = _defaultMinDistance) { var result = new List <SegmentCoordinate>(); for (int i = 0; i < coordinates.Count; i++) { var currentSegment = coordinates[i]; // Always add the current segment // This will also include the last one result.Add(currentSegment); // Check if we have a following segment if (i + 1 < coordinates.Count) { var nextSegment = coordinates[i + 1]; double distance = SegmentCoordinate.DistanceBetweenInKilometers(currentSegment, nextSegment); if (distance > minDistance) { int numCoordinatesToAdd = (int)(distance / minDistance); result.AddRange(CreateCoordinatesBetween(currentSegment, nextSegment, distance, numCoordinatesToAdd)); } } } return(result); }
public double Length() { if (Coordinates.Count < 2) { return(0.0); } double totalDistance = 0.0; for (int i = 0; i < Coordinates.Count - 1; i++) { totalDistance += SegmentCoordinate.DistanceBetweenInKilometers(Coordinates[i], Coordinates[i + 1]); } return(totalDistance); }
public static List <SegmentCoordinate> CreateCoordinatesBetween(SegmentCoordinate s1, SegmentCoordinate s2, double distance, int numCoordinatesToAdd) { double forwardLat = (s2.Lat - s1.Lat) / (numCoordinatesToAdd + 1); double forwardLon = (s2.Lng - s1.Lng) / (numCoordinatesToAdd + 1); double startLat = s1.Lat; double startLon = s1.Lng; var newCoordinates = new List <SegmentCoordinate>(); // i = 0 would be our starting point for (int i = 1; i <= numCoordinatesToAdd; i++) { newCoordinates.Add(new SegmentCoordinate { Lat = startLat + forwardLat * i, Lng = startLon + forwardLon * i }); } return(newCoordinates); }
public bool AddToLists(Segment segment) { SegmentCoordinate firstCoordinateSelf = Coordinates[0]; SegmentCoordinate lastCoordinateSelf = Coordinates[Coordinates.Count - 1]; SegmentCoordinate firstCoordinateOther = segment.Coordinates[0]; SegmentCoordinate lastCoordinateOther = segment.Coordinates[segment.Coordinates.Count - 1]; if (firstCoordinateSelf.Equals(firstCoordinateOther)) { BeginChildren.Add(segment); return(true); } if (firstCoordinateSelf.Equals(lastCoordinateOther)) { segment.Coordinates.Reverse(); BeginChildren.Add(segment); return(true); } if (lastCoordinateSelf.Equals(firstCoordinateOther)) { EndChildren.Add(segment); return(true); } if (lastCoordinateSelf.Equals(lastCoordinateOther)) { segment.Coordinates.Reverse(); EndChildren.Add(segment); return(true); } return(false); }
// Shrink the graph to the range between // (1) the point that is nearest to the minimal matched house number // (2) the point that is nearest to the maximal matched house number // If on of them is not matched, return a one-side-open range // If both of them are not matched, return the full street private static List <SegmentCoordinate> ShrinkToHouseNumberRange(List <SegmentCoordinate> coordinates, CoordinatesItem segmentItem) { var minHnoCoordinate = segmentItem.HouseNumberStart == null ? null : GetCoordinateForHouseNumber(segmentItem.StreetZipId, segmentItem.HouseNumberStart.Value); var maxHnoCoordinate = segmentItem.HouseNumberEnd == null ? null : GetCoordinateForHouseNumber(segmentItem.StreetZipId, segmentItem.HouseNumberEnd.Value); var result = new List <SegmentCoordinate>(); long minIndex = 0; double minDistanceMin = double.MaxValue; long maxIndex = coordinates.Count; double minDistanceMax = double.MaxValue; for (int i = 0; i < coordinates.Count; i++) { var currentCoordinate = coordinates[i]; if (minHnoCoordinate != null) { var currentDistanceMin = SegmentCoordinate.DistanceBetweenInKilometers(minHnoCoordinate, currentCoordinate); if (currentDistanceMin < minDistanceMin) { minDistanceMin = currentDistanceMin; minIndex = i; } } if (maxHnoCoordinate != null) { var currentDistanceMax = SegmentCoordinate.DistanceBetweenInKilometers(maxHnoCoordinate, currentCoordinate); if (currentDistanceMax < minDistanceMax) { minDistanceMax = currentDistanceMax; maxIndex = i; } } } // If the minIndex is bigger than the maxIndex // something has gone wrong in the graph building // See if we can get a nice graph by reversing the whole thing if (minIndex > maxIndex) { Utils.Swap(ref minIndex, ref maxIndex); coordinates = new List <SegmentCoordinate>(coordinates); coordinates.Reverse(); } // Add some segments at the beginning and the end, // This is for some countries, where house numbers in streets seem to be pretty random (NOR)... const int addRange = 3; minIndex = Math.Max(0, minIndex - addRange); maxIndex = Math.Min(coordinates.Count, maxIndex + addRange); var startIndex = (int)minIndex; var length = (int)(maxIndex - minIndex); var newCoordinates = coordinates.GetRange(startIndex, length); return(newCoordinates); }