Christopher Olsson 已经给出了很好的答案,但我想我也应该补充一些理论。
我一直发现this webpage 对这些公式很有用。
概念简介
想想实际的几何形状。
就目前而言,您目前所做的只是缩放输入。想象一下气球的经典例子。在气球上画两条线,在底部和顶部相交。这些代表经度线,因为它们“上下”。引号,当然,因为没有真的这样的概念,但我们可以想象。现在,如果您查看每条线,您会发现它们的距离会随着您上下移动它们的长度而变化。根据原始规范,它们在气球的顶部和底部相遇,但它们不会在其他任何地方相遇。经度线也是如此。非欧几何告诉我们,如果线完全相交,它们恰好相交两次,这很难概念化。但正因为如此,我们的线之间的距离有效地反映了整个赤道。
如您所见,纬度极大地影响了纵向线之间的距离。它们从北极和南极最近到赤道最远不等。
纬线更容易一些。它们不收敛。如果你拿着我们的理论气球直线上下,两极指向直线向上和直线向下,也就是说,纬线将平行于地板。在更广义的意义上,它们将垂直于由纵向线的极点构成的轴(欧几里得概念)。因此,无论您的经度如何,纬度之间的距离都是恒定的。
您的实施
现在,您的实现依赖于这些线始终保持恒定距离的想法。如果是这种情况,您将能够像您一样采用简单的缩放方法。事实上,如果它们在欧几里得意义上是平行的,那么它与从每小时英里转换为每小时公里的概念并没有太大的不同。然而,距离的变化使这变得更加复杂。
北极的经度之间的距离为零,而在赤道,正如您引用的维基百科页面所述,它是 111.32 公里。因此,要获得真正准确的结果,您必须考虑要查找的纬度。这就是为什么这会变得有点复杂。
获得现实的结果
现在,您想要的公式,鉴于您最近的编辑,您似乎希望在评估中同时纳入纬度和经度。鉴于您的代码示例,您似乎想要找到两个坐标之间的距离,并且您希望它在短距离内运行良好。因此,我会建议,正如我在本文开头指出的网站所建议的那样,使用 Haversine 公式。该网站提供了很多很好的信息,但这是公式本身。我直接从网站、符号和所有内容中复制它,以确保我不会犯任何愚蠢的错别字。因此,这当然是 JavaScript,但您基本上只需更改某些情况,它就会在 C# 中运行。
这里,φ是纬度,λ是经度,θ是方位角(弧度,从北顺时针方向),δ是角距离(弧度)d/R; d是经过的距离,R是地球的半径
var R = 6371; // km
var φ1 = lat1.toRadians();
var φ2 = lat2.toRadians();
var Δφ = (lat2-lat1).toRadians();
var Δλ = (lon2-lon1).toRadians();
var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
我认为这里唯一需要注意的是R,正如第一行所声明的,是地球的半径。正如评论所暗示的那样,我们已经在以公里为单位工作,因此您可能需要也可能不需要为您的实施进行更改。幸运的是,通过在线搜索以您最喜欢的单位找到地球的(平均)半径很容易。
当然,您还需要注意,toRadians 只是输入乘以 Math.PI,然后除以 180。很简单。
替代方案
这真的看起来与您的情况无关,但我会包括在内。上述公式将给出准确的结果,但会以速度为代价。显然,这对任何个人记录来说都是一笔不小的交易,但是随着您处理越来越多的事情,这可能会成为一个问题。如果是这样,并且如果您在一个相当集中的地区进行交易,您可以利用我们星球的巨大性质并找到适合于一个纬度和经度之间距离的数字,然后将地球视为“或多或少欧几里得”(平坦,即),并使用勾股定理来计算值。当然,随着您离原始测试站点的距离越远,这将变得越来越不准确(我个人只是通过询问 Google 地球或类似产品来找到这些数字)。但是,如果您正在处理一个密集的用户群,那将比在 Math 类中运行一系列公式来解决问题要快得多。
另一种更抽象的选择
您可能还想考虑在哪里执行此逻辑。在这里,我开始有点超出我的范围,但是如果您碰巧将数据存储在 SQL Server 中,它已经内置了一些非常酷的地理功能,可以为您处理距离计算。只需查看 GEOGRAPHY 类型即可。
编辑
这是对评论的回应,表明期望的结果实际上是一个表示边界的矩形。现在,我建议不要这样做,因为它并不是您的代码所建议的真正的搜索“半径”。
但是,如果您确实想坚持这种方法,您将查看两种不同的距离:一种用于纬度,另一种用于经度。这也来自该网页。 φ1 是 myLatitude,λ1 是 myLongitude。此公式接受方位角和起始坐标,然后给出结果位置。
var φ2 = Math.asin( Math.sin(φ1)*Math.cos(d/R) + Math.cos(φ1)*Math.sin(d/R)*Math.cos(brng) );
var λ2 = λ1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(φ1), Math.cos(d/R)-Math.sin(φ1)*Math.sin(φ2));
您可以使用它来确定搜索矩形的边界。