public double?ProjectedDistance(ProjVector2 point, double distanceLimit) { point = point.ToProjection(Points.First().Projection); int bestIndex = -1; double bestProj = 0; double bestDist = 0; for (int i = 1; i < Points.Count; i++) { ProjVector2 a = Points[i] - Points[i - 1]; ProjVector2 b = point - Points[i - 1]; double proj = a.Dot(b) / a.LengthSquared; if (proj < 0) { proj = 0; } else if (proj > 1) { proj = 1; } double dist = (point - (Points[i] + a * proj)).MeterLength / 1000; if ((bestIndex == -1 || dist < bestDist) && dist < distanceLimit) { bestIndex = i; bestProj = proj; bestDist = dist; } } // The point could not be projected if (bestIndex == -1) { return(null); } double km = 0; for (int i = 1; i <= bestIndex; i++) { km += (Points[i] - Points[i - 1]).MeterLength / 1000; } km += bestProj * (Points[bestIndex + 1] - Points[bestIndex]).MeterLength / 1000; return(km); }
public static ProjVector2?Search(Station station, ProjVector2 position, double radius, int maxLevenshtein) { int minDist = 0; PlacesAPIData?minRes = null; var results = Scan(position.ToProjection(Projection.LatitudeLongitude), radius); foreach (var result in results) { int dist = LevenshteinDistance(station.NormalizedName, Station.NormalizeName(result.StationName)); if (dist == 0) { return(result.Position); } if (dist <= maxLevenshtein && (minRes == null || dist < minDist)) { minRes = result; minDist = dist; } } return(minRes?.Position); }