private string SelectLink(double latitude, double longitude, double heading, DataRow[] selectedRows) { string matchedLink = ""; double minDistance = double.PositiveInfinity; //車のHEADINGを計算 double carHeading; if (heading > 180) { carHeading = heading - 180; } else { carHeading = heading; } //自動車の向きとリンクの向きのなす角 double minAngle = double.PositiveInfinity; foreach (DataRow row in selectedRows) { double pointY; //リンク上のGPSの点との最近点の緯度 double pointX; //リンク上のGPSの点との最近点の経度 //リンクとGPS上の点との距離とリンク上の最近点を計算 CalculateMinimumDistancePointOfLink(latitude, longitude, row, out pointY, out pointX); //リンクとの最短距離 double distance = DistanceCalculator.CalcDistance(latitude, longitude, pointY, pointX); if (row.Field <double?>("heading") != null) { double linkHeading = row.Field <double>("heading"); //リンクとHEADINGの角度を算出 double angle = Math.Abs(carHeading - linkHeading); if (angle > 90) { angle = 180 - angle; } //リンクとの距離が10m以内でかつなす角が小さいものをマッチング if (distance < 10 && angle < minAngle) { minDistance = distance; minAngle = angle; matchedLink = row.Field <string>("link_id").Trim(); } else { //10m以内のリンクがないときは距離が短いものをマッチング if (minDistance >= distance) { minDistance = distance; matchedLink = row.Field <string>("link_id").Trim(); } } } else { //Headingが計算できないときは距離が短いものをマッチング if (minDistance >= distance) { minDistance = distance; matchedLink = row.Field <string>("link_id").Trim(); } } } return(matchedLink); }