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); }
// 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); }