c# - 找到与 double 数组最接近的匹配项

标签 c# asp.net

给出下面的代码,我如何将对象值列表与测试值进行比较?

我正在构建一个地理定位应用程序。我将传递经度和纬度,并希望服务返回最接近这些值的位置。

我开始尝试转换为字符串,并将值格式化为小数点后两位,但这似乎有点太贫民窟了,我正在寻找更优雅的解决方案。

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<Location> myList = new List<Location>
 {             
    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;
}

我希望这是正确的公式,我的数学在这里可能有点生疏。所有参数都需要以弧度为单位,因此如果您以度数为单位输入,还要编写一个实用方法:

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 扩展方法来对投影进行最小化处理。如果需要,您必须编写自己的 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;
}

关于c# - 找到与 double 数组最接近的匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2648501/

相关文章:

asp.net - Web 开发设置

asp.net - 覆盖应用程序根 URL 会创建一个不可用的页面

c# - 具有决策 "Contact Us"的类 eBay "workflow"系统的架构指南

c# - RestSharp 反序列化为 List<MyClass>

c# - 返回按钮代码不起作用

c# - 在 appSettings 中为一个键使用多个值

c# - 如何使用 RsaProtectedConfigurationProvider 加密/解密配置文件部分

c# - 角色管理器功能尚未启用

c# - DataGrid 更新添加的行但不更新添加的列

c# - 如何在 ASP.NET 网站中调用非托管代码并将其托管在 IIS 中?