将米转换为十进制度数 [英] Convert meters to decimal degrees

查看:363
本文介绍了将米转换为十进制度数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在C#中将米转换为十进制度.我在 Wikipedia 上看到,小数点后1位等于111.32公里.但这是在赤道上,所以如果我位于赤道上方/之下,那么转换会出错吗? 我认为这是错误的:

I need to convert meters to decimal degrees in C#. I read on Wikipedia that 1 decimal degree equals 111.32 km. But it is on equator, so if I'm located above/below it my the conversion will be wrong? I assume this is wrong:

long sRad = (long.Parse(sRadTBx.Text)) / (111.32*1000); 

编辑:我需要此搜索半径才能找到附近的用户

I need this search radius to find nearby users

    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);
    }
}

推荐答案

克里斯托弗·奥尔森(Christopher Olsson)已经有了一个很好的答案,但我认为我也会填写一些理论.

Christopher Olsson already has a good answer, but I thought I'd fill in some of the theory too.

我一直发现此网页对于这些公式很有用.

I've always found this webpage useful for these formulas.

有关概念的快速注释

考虑实际的几何形状.

就目前而言,您仅需缩放输入即可.想象一下气球的经典例子.在气球上画两条在底部和顶部相交的线.这些代表经度线,因为它们向上"和向下".引号,当然,因为没有真正这样的概念,但是我们可以想象得到.现在,如果您查看每条线,您会发现它们在上下移动时的距离会有所不同.根据原始规范,它们在气球的顶部和底部相遇,但在其他任何地方都没有相遇.经度线也是如此.非欧几里得几何告诉我们,如果线完全相交,则它们恰好相交两次,这很难概念化.但是正因为如此,我们的线之间的距离才能有效地反映在整个赤道上.

As it stands, you are currently doing nothing more than scaling the input. Imagine the classic example of a balloon. Draw two lines on the balloon that meet at the bottom and the top. These represent lines of longitude, since they go "up and down." Quotes, of course, since there aren't really such concepts, but we can imagine. Now, if you look at each line, you'll see that they vary in distance as you go up and down their lengths. Per the original specification, they meet at the top of the balloon and the bottom, but they don't meet anywhere else. The same is true of lines of longitude. Non-Euclidean geometry tells us that lines intersect exactly twice if they intersect at all, which can be hard to conceptualize. But because of that, the distance between our lines is effectively reflected across the equator.

如您所见,纬度极大地影响了纵向线之间的距离.它们的变化范围从最南北的北极到最远的赤道.

As you can see, the latitude greatly affects the distance between your longitudinal lines. They vary from the closest at the north and south poles, to the farthest away at the equator.

纬度线稍微容易一些.他们不收敛.如果您将理论气球向上或向下保持竖直,则两极指向垂直向上或向下,也就是说,纬度线将与地面平行.从更广义的意义上讲,它们将垂直于纵向线的极点所构成的轴(欧几里得概念).因此,无论您的经度如何,纬度之间的距离都是恒定的.

Latitudinal lines are a bit easier. They do not converge. If you're holding our theoretical balloon straight up and down, with the poles pointed straight up and straight down that is, lines of latitude will be parallel to the floor. In a more generalized sense, they will be perpendicular to the axis (a Euclidean concept) made by the poles of the longitudinal lines. Thus, the distance is constant between latitudes, regardless of your longitude.

您的实施

现在,您的实现依赖于这样的想法,即这些线始终保持恒定的距离.如果是这样的话,您将能够像使用平常一样采用简单的缩放方法.实际上,如果它们在欧几里得意义上是平行的,则与从每小时英里数转换为每小时公里数的概念并不太相似.但是,距离的变化使情况变得更加复杂.

Now, your implementation relies on the idea that these lines are always at a constant distance. If that was the case, you'd be able to do take a simple scaling approach, as you have. If they were, in fact, parallel in the Euclidean sense, it would be not too dissimilar to the concept of converting from miles per hour to kilometers per hour. However, the variance in distance makes this much more complicated.

北极的经度之间的距离为零,而在赤道上,正如您引用的Wikipedia页面所指出的,该距离为111.32公里.因此,要获得真正准确的结果,您必须考虑要寻找的纬度.这就是为什么它变得更加复杂的原因.

The distance between longitudes at the north pole is zero, and at the equator, as your cited Wikipedia page states, it's 111.32 kilometers. Consequently, to get a truly accurate result, you must account for the latitude you're looking for. That's why this gets a little more complicated.

获得逼真的结果

现在,根据最近的修改,您想要的公式似乎是您希望将纬度经度都纳入评估中.给定您的代码示例,似乎您想找到两个坐标之间的距离,并且希望它在短距离下能很好地工作.因此,正如我在这篇文章开头所指的网站所建议的那样,我将建议使用Haversine公式.该网站提供了很多很好的信息,但这只是公式本身.我直接从网站,符号和所有内容中复制它,以确保我不会犯任何愚蠢的错字.因此,这当然是JavaScript,但是您基本上可以更改某些情况,它将在C#中运行.

Now, the formula you want, given your recent edit, it seems that you're looking to incorporate both latitude and longitude in your assessment. Given your code example, it seems that you want to find the distance between two coordinates, and that you want it to work well at short distances. Thus, I will suggest, as the website I pointed you to at the beginning of this posts suggests, a Haversine formula. That website gives lots of good information on it, but this is the formula itself. I'm copying it directly from the site, symbols and all, to make sure I don't make any stupid typos. Thus, this is, of course, JavaScript, but you can basically just change some cases and it will run in C#.

在此,φ是纬度,λ是经度,θ是方位角(以弧度为单位,从北向顺时针方向),δ是角距离(以弧度为单位)d/R; d为行进距离,R为地球半径

In this, φ is latitude, λ is longitude, θ is the bearing (in radians, clockwise from north), δ is the angular distance (in radians) d/R; d being the distance travelled, R the earth’s radius

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是地球的半径.就像评论所暗示的那样,我们已经在以千米为单位进行工作,因此您可能需要为实施而更改,也可以不必更改.幸运的是,通过在线搜索,以您喜欢的单位查找地球的(平均)半径已经足够容易了.

I think the only thing that must be noted here is that R, as declared in the first line, is the radius of the earth. As the comment suggests, we're already working in kilometers so you may or may not have to change that for your implementation. It's easy enough, fortunately, to find the (average) radius of the earth in your favorite units by doing a search online.

当然,您还要注意toRadians就是输入乘以Math.PI然后除以180.很简单.

Of course, you'll also want to note that toRadians is simply the input multiplied by Math.PI, then divided by 180. Simple enough.

替代

这看起来与您的情况无关,但我将包括在内.前面提到的公式将给出准确的结果,但这是以速度为代价的.显然,这对任何个人记录来说都是很小的一笔交易,但是随着您处理越来越多的记录,这可能会成为一个问题.如果是这样,并且您要在一个相对集中的地区进行交易,则可以解决我们星球的巨大本质,找到适合一个纬度和经度之间距离的数字,然后将星球视为或多或少欧几里得"(平坦),并使用勾股定理来计算值.当然,如果您离原始测试站点越远,精度就会越低(我个人可以通过询问Google Earth或类似产品来找到这些数字).但是,如果您要处理密集的用户群,则 way 的速度要比对Math类运行大量公式的速度快.

This doesn't really look relevant to your case, but I will include it. The aforementioned formula will give accurate results, but it will be at the cost of speed. Obviously, it's a pretty small deal on any individual record, but as you build up to handle more and more, this might become an issue. If it does, and if you're dealing in a fairly centralized locale, you could work off the immense nature of our planet and find numbers suitable for the distance between one degree of latitude and longitude, then treat the planet as "more or less Euclidean" (flat, that is), and use the Pythagorean Theorem to figure the values. Of course, that will become less and less accurate the further away you get from your original test site (I'd just find these numbers, personally, by asking Google Earth or a similar product). But if you're dealing with a dense cluster of users, that will be way, way, way faster than running a flurry of formulas to the Math class to work out.

另一个更抽象的选择

您可能还想考虑在哪里执行此逻辑.在这里,我开始超越我的范围,但是如果您碰巧将数据存储在SQL Server中,则它已经内置了一些非常酷的地理功能,可以为您处理距离计算.只需检查 GEOGRAPHY 类型.

You might also want to think about where you're doing this logic. Here I begin to overstep my reach a bit, but if you happen to be storing your data in SQL Server, it already has some really cool geography functionality built right in that will handle distance calculations for you. Just check out the GEOGRAPHY type.

修改

这是对评论的回应,表明所需的结果实际上是一个表示边界的矩形.现在,我建议不要这样做,因为它实际上并不是您的代码所建议的搜索半径".

This is a response to a comment, suggesting that the desired result is really a rectangle denoting boundaries. Now, I would advise against this, because it isn't really a search "radius" as your code may suggest.

但是,如果您确实要坚持使用这种方法,您将需要查看两个单独的距离:一个用于纬度,一个用于经度.这也来自该网页. φ1myLatitudeλ1myLongitude.该公式接受方位角和起始坐标,然后给出结果位置.

But if you do want to stick to that method, you'll be looking at two separate distances: one for latitude and one for longitude. This is also from that webpage. φ1 is myLatitude, and λ1 is myLongitude. This formula accepts a bearing and starting coordinates, then gives the resulting position.

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));

您可以使用它来确定搜索矩形的边界.

You could use that to determine the boundaries of your search rectangle.

这篇关于将米转换为十进制度数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆