static linelatlng findClosestLine(utmpos start, List<linelatlng> list, double minDistance, double angle)
{
// By now, just add 5.000 km to our lines so they are long enough to allow intersection
double METERS_TO_EXTEND = 5000000;
double perperndicularOrientation = AddAngle(angle, 90);
// Calculation of a perpendicular line to the grid lines containing the "start" point
/*
* --------------------------------------|------------------------------------------
* --------------------------------------|------------------------------------------
* -------------------------------------start---------------------------------------
* --------------------------------------|------------------------------------------
* --------------------------------------|------------------------------------------
* --------------------------------------|------------------------------------------
* --------------------------------------|------------------------------------------
* --------------------------------------|------------------------------------------
*/
utmpos start_perpendicular_line = newpos(start, perperndicularOrientation, -METERS_TO_EXTEND);
utmpos stop_perpendicular_line = newpos(start, perperndicularOrientation, METERS_TO_EXTEND);
// Store one intersection point per grid line
Dictionary<utmpos, linelatlng> intersectedPoints = new Dictionary<utmpos, linelatlng>();
// lets order distances from every intersected point per line with the "start" point
Dictionary<double, utmpos> ordered_min_to_max = new Dictionary<double, utmpos>();
foreach (linelatlng line in list)
{
// Extend line at both ends so it intersecs for sure with our perpendicular line
utmpos extended_line_start = newpos(line.p1, angle, -METERS_TO_EXTEND);
utmpos extended_line_stop = newpos(line.p2, angle, METERS_TO_EXTEND);
// Calculate intersection point
utmpos p = FindLineIntersection(extended_line_start, extended_line_stop, start_perpendicular_line, stop_perpendicular_line);
// Store it
intersectedPoints[p] = line;
// Calculate distances between interesected point and "start" (i.e. line and start)
double distance_p = start.GetDistance(p);
if (!ordered_min_to_max.ContainsKey(distance_p))
ordered_min_to_max.Add(distance_p, p);
}
// Acquire keys and sort them.
List<double> ordered_keys = ordered_min_to_max.Keys.ToList();
ordered_keys.Sort();
// Lets select a line that is the closest to "start" point but "mindistance" away at least.
// If we have only one line, return that line whatever the minDistance says
double key = double.MaxValue;
int i = 0;
while (key == double.MaxValue && i < ordered_keys.Count)
{
if (ordered_keys[i] >= minDistance)
key = ordered_keys[i];
i++;
}
// If no line is selected (because all of them are closer than minDistance, then get the farest one
if (key == double.MaxValue)
key = ordered_keys[ordered_keys.Count-1];
// return line
return intersectedPoints[ordered_min_to_max[key]];
}