【问题标题】:c# find the closest two numbers in a list with two columns to two number argumentsc# 查找列表中最接近的两个数字,其中包含两个数字参数的两列
【发布时间】:2020-01-02 23:26:12
【问题描述】:

我正在使用地理纬度/经度值并给定特定的纬度/经度组合,我需要根据美国邮政编码从经度/经度位置列表中找到最近的纬度/经度。找到后,我需要返回该位置的邮政编码。

查找最近纬度/经度的示例参数

X:-76.696136 Y: 40.095702

DataTable 列包括纬度、经度、邮编

我尝试了以下方法,但返回的两个数字之间的距离大于预期,例如返回的 ZipCode 与原始 Lat/Lon 参数有相当大的距离。我不相信 OrderBy, ThenBy 实际上提供了最接近的数字组合。是否有另一种方法可以提供更紧密的匹配?

var zipMatches = zipCodeList
 .OrderBy(item => Math.Abs(Convert.ToDouble(item.Latitude) - Convert.ToDouble(searchedItem.GeoLat)))
 .ThenBy(item => Math.Abs(Convert.ToDouble(item.Longitude) - Convert.ToDouble(searchedItem.GeoLon)))
 .FirstOrDefault();

预期结果将是最接近所提供参数的纬度/经度对。

X:-76.696136 Y: 40.095702

【问题讨论】:

标签: c#


【解决方案1】:

对球体的距离计算可能会变得相当复杂。如果要比较的点彼此之间的距离不是太远,并且您不在日期从 -180 度跃升至 +180 度的日期线附近,则可以简化假设您在 Euclidean plane 上并计算 @ 987654322@ 使用Pythagorean theorem

distance = sqrt((x1 - x0)^2 + (y1 - y0)^2)

由于您对绝对幅度不感兴趣,而只对相对距离感兴趣,因此可以省略平方根计算

sqrDistance = (x1 - x0)^2 + (y1 - y0)^2

这样

double searchLat = Convert.ToDouble(searchedItem.GeoLat);
double searchLon = Convert.ToDouble(searchedItem.GeoLon);
var zipMatches = zipCodeList
     .OrderBy(item => Math.Pow(Convert.ToDouble(item.Latitude) - searchLat, 2) +
                      Math.Pow(Convert.ToDouble(item.Longitude) - searchLon, 2))
     .FirstOrDefault();

【讨论】:

  • 为了便于阅读,最好还是保留平方根。
【解决方案2】:

加强 Olivier 的回答。 首先,如果位置是基于邮政编码的,那么可能有多个相同的距离点,并且随机第一个可能不是很实用。 下面的代码将返回所有恰好离搜索点最近的点:

private double GetSqrDistanceBetweenPoints(GeoCoordinate point1, GeoCoordinate point2)
{
    return Math.Pow(Convert.ToDouble(point1.Latitude) - point2.Latitude, 2) +
           Math.Pow(Convert.ToDouble(point1.Longitude) - point2.Longitude, 2);
}
private List<GeoCoordinate> Test(List<GeoCoordinate> zipCodeList, GeoCoordinate searchedItem)
{
    var zipMatches = zipCodeList
        .ToLookup(x => GetSqrDistanceBetweenPoints(x, searchedItem))
        .OrderBy(x => x.Key)
        .FirstOrDefault()?
        .ToList();

    return zipMatches;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多