将米转换为十进制度
Posted
技术标签:
【中文标题】将米转换为十进制度【英文标题】:Convert meters to decimal degrees 【发布时间】:2014-10-03 22:22:03 【问题描述】:我需要在 C# 中。我在Wikipedia 上读到 1 个十进制度等于 111.32 公里。但它在赤道上,所以如果我位于它的上方/下方,我的转换会出错吗? 我认为这是错误的:
long sRad = (long.Parse(sRadTBx.Text)) / (111.32*1000);
编辑:我需要这个搜索范围来查找附近的用户
long myLatitude = 100;
long myLongitude = 100;
long sRad = /* right formula to convert meters to decimal degrees*/
long begLat = myLatitude - searchRad;
long endLat = myLatitude + searchRad;
long begLong = myLongitude - searchRad;
long endLong = myLongitude + searchRad;
List<User> FoundUsers = new List<User>();
foreach (User user in db.Users)
// Check if the user in the database is within range
if (user.usrLat >= begLat && user.usrLat <= endLat && user.usrLong >= begLong && user.usrLong <= endLong)
// Add the user to the FoundUsers list
FoundUsers.Add(user);
【问题讨论】:
@Sayse,无法从文本框中获取浮点数 但是您使用的是双精度值,所以double.Parse
会更有意义
【参考方案1】:
同样来自同一篇***文章:
As one moves away from the equator towards a pole, however,
one degree of longitude is multiplied by
the cosine of the latitude,
decreasing the distance, approaching zero at the pole.
所以这将是纬度的函数:
double GetSRad(double latitude)
return 111.32 * Math.Cos(latitude * (Math.PI / 180));
或类似的。
编辑:所以反过来,将米转换为十进制度,你需要这样做:
double MetersToDecimalDegrees(double meters, double latitude)
return meters / (111.32 * 1000 * Math.Cos(latitude * (Math.PI / 180)));
【讨论】:
是的,这会告诉你十进制度等于多少公里,作为纬度的函数。【参考方案2】: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));
您可以使用它来确定搜索矩形的边界。
【讨论】:
我不想找到两个坐标之间的距离,我想将我的搜索半径从米转换为十进制度,只是为了在那个运行良好的函数中使用。有可能吗? 所以 φ1 - 我的搜索半径是米吗? d, φ1, φ2, brng 是什么?抱歉,我的几何学不好,这些变量对我没有任何意义。您编写的这两行代码是否替换了 begLat、endLat、endLong、begLong 值? @Leek 哎呀!对不起,我忘了包括那些的定义。我的错。我编辑了我的答案,您可以在第一个代码块的正上方找到它们。这两行不会替换任何东西,它们会进入另一个接受方位角的函数(方向,即,它是弧度,所以你可能想要修复它)。然后,您可以找到每个方向的距离以找到begLat
和其余的。例如,对于顶部,您需要从点 x
米到 0 度的纬度。西是x
米到 270 度。以上是关于将米转换为十进制度的主要内容,如果未能解决你的问题,请参考以下文章