一千萬個為什麽

搜索

找到最接近的雙打數組

鑒於下面的代碼,如何將對象列表的值與測試值進行比較?

我正在構建一個地理定位應用程序。我將在經度和緯度上傳遞,並希望服務回答最接近這些值的位置。

我開始轉換為字符串的路徑,並將值格式化為兩個小數位,但這似乎有點太多了,我正在尋找一個更優雅的解決方案。

public class Location : IEnumerable
{
    public string label { get; set; }
    public double lat { get; set; }
    public double lon { get; set; }

    //Implement IEnumerable
    public IEnumerator GetEnumerator()
    {
        return (IEnumerator)this;
    }

}
[HandleError]
public class HomeController : Controller
{
    private List myList = new List
 {             
    new Location {
        label="Atlanta Midtown", 
        lon=33.657674, 
        lat=-84.423130},
    new Location {
        label="Atlanta Airport", 
        lon=33.794151, 
        lat=-84.387228},
    new Location {
        label="Stamford, CT", 
        lon=41.053758, 
        lat=-73.530979}, ...
}

 public static int Main(String[] args)
 {
     string inLat = "-80.987654";
     double dblInLat = double.Parse(inLat);

    //here's where I would like to find the closest location to the inLat
    //once I figure out this, I'll implement the Longitude, and I'll be set
 }

最佳答案

如果你不想得到奇怪的結果,你會想要使用正確的距離公式:

double CalculateDistance(double lat1, double lon1, double lat2, double lon2)
{
    const double R = 6371;
    return Math.Acos(
        Math.Sin(lat1) * Math.Sin(lat2) +
        Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(lon2 - lon1)) * R;
}

我希望這是正確的公式,我的數學可能會有點生疏。所有參數都需要以rad為單位,因此如果您以度為單位輸入輸入,請編寫實用程序方法:

double DegToRad(double deg)
{
    return deg * Math.PI/180.0;
}

無論如何,在那之後,你可以找出最短的距離:

Location GetClosestLocation(Location origin)
{
    double olatr = DegToRad(origin.Lat);
    double olonr = DegToRad(origin.Lon);
    return
        (from l in locations
         let latr = DegToRad(l.Lat)
         let lonr = DegToRad(l.Lon)
         orderby CalculateDistance(latr, lonr, olatr, olonr))
        .FirstOrDefault();
}

這在技術上並不是最高性能的解決方案,因為它必須進行排序,但是沒有漂亮的Linq擴展方法來使用投影進行min。如果你想要,你必須編寫自己的 foreach 循環:

Location GetClosestLocation(Location origin)
{
    double olatr = DegToRad(origin.Lat);
    double olonr = DegToRad(origin.Lon);
    Location closest = null;
    double minDistance = double.MaxValue;
    foreach (Location l in locations)
    {
        double latr = DegToRad(l.Lat);
        double lonr = DegToRad(l.Lon);
        double dist = CalculateDistance(latr, lonr, olatr, olonr));
        if (dist < minDistance)
        {
            minDistance = dist;
            closest = l;
        }
    }
    return closest;
}

轉載註明原文: 找到最接近的雙打數組