如何求两个地点的经纬度距离?
我有一组位置的纬度和经度。
- 如何找到从集合中的一个位置到另一个位置的距离?
- 有公式吗?
I have a set of latitudes and longitudes of locations.
- How to find distance from one location in the set to another?
- Is there a formula ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
半正矢公式假定地球是球形的。然而,地球的形状更为复杂。扁球体模型会给出更好的结果。
如果需要这样的精度,最好使用文森特反演公式。
有关详细信息,请参阅 http://en.wikipedia.org/wiki/Vincenty's_formulae。使用它,您可以获得 0.5mm 的球体模型精度。
不存在完美的公式,因为地球的真实形状太复杂,无法用公式来表达。此外,地球的形状会因气候事件而发生变化(请参阅http://www.nasa.gov/centers/goddard/earthandsun/earthshape.html" rel="noreferrer">http://www. nasa.gov/centers/goddard/earthandsun/earthshape.html),并且由于地球自转也会随着时间而变化。
您还应该注意,上述方法没有考虑海拔高度,并假设海平面扁球体。
编辑 2010 年 7 月 10 日: 我发现在极少数情况下 Vincenty 反演公式不会收敛到声明的精度。更好的主意是使用 GeographicLib (请参阅 http://sourceforge.net/projects/geographiclib/)这也更准确。
The Haversine formula assumes a spherical earth. However, the shape of the earh is more complex. An oblate spheroid model will give better results.
If such accuracy is needed, you should better use Vincenty inverse formula.
See http://en.wikipedia.org/wiki/Vincenty's_formulae for details. Using it, you can get a 0.5mm accuracy for the spheroid model.
There is no perfect formula, since the real shape of the earth is too complex to be expressed by a formula. Moreover, the shape of earth changes due to climate events (see http://www.nasa.gov/centers/goddard/earthandsun/earthshape.html), and also changes over time due to the rotation of the earth.
You should also note that the method above does not take altitudes into account, and assumes a sea-level oblate spheroid.
Edit 10-Jul-2010: I found out that there are rare situations for which Vincenty inverse formula does not converge to the declared accuracy. A better idea is to use GeographicLib (see http://sourceforge.net/projects/geographiclib/) which is also more accurate.
这是一个: http://www.movable-type.co.uk/scripts/ latlong.html
使用半正矢公式:
Here's one: http://www.movable-type.co.uk/scripts/latlong.html
Using Haversine formula:
应用半正矢公式求出距离。请参阅下面的 C# 代码来查找 2 个坐标之间的距离。更好的是,如果您想要查找特定半径内的商店列表,您可以在 SQL 中应用
WHERE
子句或在 C# 中应用 LINQ 过滤器。这里的公式以公里为单位,您必须更改相关数字,它将适用于英里。
例如:将 6371.392896 转换为英里。
如果您想在 C# 中执行半正弦公式,
DegreesToRadian 是我自定义创建的一个函数,它是一个简单的 1 行
“Math.PI * 角度” / 180.0
我的博客条目-SQL Haversine
Apply the Haversine formula to find the distance. See the C# code below to find the distance between 2 coordinates. Better still if you want to say find a list of stores within a certain radius, you could apply a
WHERE
clause in SQL or a LINQ filter in C# to it.The formula here is in kilometres, you will have to change the relevant numbers and it will work for miles.
E.g: Convert 6371.392896 to miles.
If you would like to perform the Haversine formula in C#,
DegreesToRadian is a function I custom created, its is a simple 1 liner of
"Math.PI * angle / 180.0
My blog entry - SQL Haversine
您是否在寻找
Haversine 公式
Are you looking for
Haversine formula
看看这个..还有一个 javascript 示例。
查找距离
Have a look at this.. has a javascript example as well.
Find Distance
使用大圆距离公式。
Use the Great Circle Distance Formula.
这是一个通过给定 IP 查找长/纬度位置/附近位置的小提琴:
http://jsfiddle。 net/bassta/zrgd9qc3/2/
这是我用来计算直线距离的函数:
它返回以公里为单位的距离
here is a fiddle with finding locations / near locations to long/lat by given IP:
http://jsfiddle.net/bassta/zrgd9qc3/2/
And here is the function I use to calculate the distance in straight line:
It returns the distance in Kilometers
如果您测量的距离小于(可能)1 度纬度/经度变化,正在寻找性能非常高的近似值,并且愿意接受比半正弦公式更多的不准确 ,考虑这两个替代方案:
(1)来自 计算距离:
(2)毕达哥拉斯定理根据纬度进行调整,如Ewan Todd 的著作中所示所以帖子:
注释:
与 Ewan 的帖子相比,我在
cos( lat0 )
中用average(lat0, lat1)
替换了lat0
。#2 对于值是度、弧度还是公里含糊不清;您还需要一些转换代码。请参阅本文底部的我的完整代码。
#1 的设计即使在极点附近也能正常工作,但如果您测量的距离的端点位于极点的“相反”两侧(经度相差超过 90 度?),建议使用半正弦值,即使距离很短。
我还没有彻底测量这些方法的错误,因此您应该为您的应用程序选取代表点,并将结果与一些高质量的库进行比较,以确定准确性是否可以接受。对于小于几公里的距离,我的直觉是这些距离与正确测量值的误差在 1% 以内。
获得高性能的另一种方法(如果适用):
如果您有一大组静态点,位于经度/纬度的一到两度内,那么您将要计算少量动态(移动)点的距离,请考虑将静态点一次性转换为包含的UTM区域(或任何其他本地笛卡尔坐标系),然后在笛卡尔坐标系中进行所有数学运算。
笛卡尔 = 平坦的地球 = 毕达哥拉斯定理适用,因此距离 = sqrt(dx^2 + dy^2)。
那么,将少数移动点准确转换为UTM的成本就很容易承担。
#1(极地)注意事项:对于小于 0.1(?)米的距离可能会非常错误。即使使用双精度数学,以下坐标(其真实距离约为 0.005 米)在我的 Polar 算法实现中被指定为“零”:
输入:
结果:
这是由于两个因素
u
和v
完全相互抵消:在另一种情况下,当扁球体答案为
0.002887 m
时,它给出的距离为0.067129 m
。问题是cos(lon2 - lon1)
与1
太接近,因此cos
函数返回的正是1
。除了测量亚米级距离之外,我还发现了迄今为止输入的有限小距离数据的最大误差(与扁球体公式相比):
其中“1”代表答案中 100% 的误差;例如,当它返回“0”时,即为“1”错误(从上面的“maxPolar”中排除)。因此“0.01”将是“100 分之一”或 1% 的误差。
将距离小于 2000 米的极坐标误差与半正弦误差进行比较,看看这个更简单的公式有多糟糕。到目前为止,我见过的最差情况是 Polar 为每 1000 份 51 份,而 Haversine 为每 1000 份 4 份。位于北纬58度左右。
现在实施“毕达哥拉斯与纬度调整”。
对于距离小于 1 的距离,它比 Polar 更加一致。 2000米
我原本以为极地问题只有在<<时才会出现。 1米,
但下面显示的结果相当令人不安。
当距离接近零时,毕达哥拉斯/纬度接近半正弦值。
例如,此测量 ~ 217 米:
Polar 对这些输入的误差要大得多;要么是我的代码中存在一些错误,要么是我正在运行的 Cos 函数中存在错误,或者我必须建议不要使用 Polar,即使大多数 Polar 测量结果比这更接近。
OTOH,毕达哥拉斯,甚至使用
* cos(latitude)
调整时,误差的增加速度快于距离(距离越大,max_error/distance 的比率就会增加),因此您需要仔细考虑要测量的最大距离,以及可接受的错误。此外,不建议使用毕达哥拉斯比较两个几乎相等的距离来决定哪个更短,因为不同方向的误差不同(未显示证据)。最坏情况测量,
errorRatio = Abs(error) / distance
(瑞典;最高 2000 m):如前所述,极端极坐标误差适用于亚米距离,其中可能报告零而不是 6 cm,或者报告超过 0.5 m距离为 1 厘米(因此 t_maxPolarErrorRatio 中显示的是“66 x”最坏情况),但在较大距离下也有一些较差的结果。 [需要使用已知高度准确的余弦函数再次进行测试。]
在 Moto E4 上运行的 Xamarin.Android 中使用 C# 代码进行测量。
C#代码:
If you are measuring distances less than (perhaps) 1 degree lat/long change, are looking for a very high performance approximation, and are willing to accept more inaccuracy than Haversine formula, consider these two alternatives:
(1) "Polar Coordinate Flat-Earth Formula" from Computing Distances:
(2) Pythagorean theorem adjusted for latitude, as seen in Ewan Todd's SO post:
NOTES:
Compared to Ewan's post, I've substituted
average(lat0, lat1)
forlat0
inside ofcos( lat0 )
.#2 is vague on whether values are degrees, radians, or kilometers; you will need some conversion code as well. See my complete code at bottom of this post.
#1 is designed to work well even near the poles, though if you are measuring a distance whose endpoints are on "opposite" sides of the pole (longitudes differ by more than 90 degrees?), Haversine is recommended instead, even for small distances.
I haven't thoroughly measured errors of these approaches, so you should take representative points for your application, and compare results to some high-quality library, to decide if the accuracies are acceptable. For distances less than a few kilometers my gut sense is that these are within 1% of correct measurement.
An alternative way to gain high performance (when applicable):
If you have a large set of static points, within one or two degrees of longitude/latitude, that you will then be calculating distances from a small number of dynamic (moving) points, consider converting your static points ONCE to the containing UTM zone (or to any other local Cartesian coordinate system), and then doing all your math in that Cartesian coordinate system.
Cartesian = flat earth = Pythagorean theorem applies, so
distance = sqrt(dx^2 + dy^2)
.Then the cost of accurately converting the few moving points to UTM is easily afforded.
CAVEAT for #1 (Polar): May be very wrong for distances less than 0.1 (?) meter. Even with double precision math, the following coordinates, whose true distance is about 0.005 meters, was given as "zero" by my implementation of Polar algorithm:
inputs:
results:
this was due to the two factors
u
andv
exactly canceling each other:In another case, it gave a distance of
0.067129 m
when the oblate spheroid answer was0.002887 m
. The problem was thatcos(lon2 - lon1)
was too close to1
, socos
function returned exactly1
.Other than measuring sub-meter distances, the max errors (compared to an oblate spheroid formula) I found for the limited small-distance data I've fed in so far:
where "1" would represent a 100% error in the answer; e.g. when it returned "0", that was an error of "1" (excluded from above "maxPolar"). So "0.01" would be an error of "1 part in 100" or 1%.
Comparing Polar error with Haversine error over distances less than 2000 meters to see how much worse this simpler formula is. So far, the worst I've seen is 51 parts per 1000 for Polar vs 4 parts per 1000 for Haversine. At about 58 degrees latitude.
Now implemented "Pythagorean with Latitude Adjustment".
It is MUCH more consistent than Polar for distances < 2000 m.
I originally thought the Polar problems were only when < 1 m,
but the result shown immediately below is quite troubling.
As distances approach zero, pythagorean/latitude approaches haversine.
For example this measurement ~ 217 meters:
Polar has a much worse error with these inputs; either there is some mistake in my code, or in Cos function I am running on, or I have to recommend not using Polar, even though most Polar measurements were much closer than this.
OTOH, Pythagorean, even with
* cos(latitude)
adjustment, has error that increases more rapidly than distance (ratio of max_error/distance increases for larger distances), so you need to carefully consider the maximum distance you will measure, and the acceptable error. In addition, it is not advisable to COMPARE two nearly-equal distances using Pythagorean, to decide which is shorter, as the error is different in different DIRECTIONS (evidence not shown).Worst case measurements,
errorRatio = Abs(error) / distance
(Sweden; up to 2000 m):As mentioned before, the extreme polar errors are for sub-meter distances, where it could report zero instead of 6 cm, or report over 0.5 m for a distance of 1 cm (hence the "66 x" worst case shown in t_maxPolarErrorRatio), but there are also some poor results at larger distances. [Needs to be tested again with a Cosine function that is known to be highly accurate.]
Measurements taken in C# code in Xamarin.Android running on a Moto E4.
C# code:
我已完成使用 SQL 查询
I am done using SQL query
以下是包含前面答案中讨论的三个公式的模块(以 f90 编码)。您可以将此模块放在程序的顶部
(在 PROGRAM MAIN 之前)或单独编译并在编译期间包含模块目录。以下模块包含三个公式。前两个是基于地球是球形的假设的大圆距离。
Following is the module (coded in f90) containing three formulas discussed in the previous answers. You can either put this module at the top of your program
(before PROGRAM MAIN) or compile it separately and include the module directory during compilation. The following module contains three formulas. First two are great-circle distances based on the assumption that earth is spherical.
在此页面上,您可以看到 Android Location 类中如何计算位置距离的完整代码和公式
android/location/Location.java
编辑:根据@Richard的提示,我把将链接函数的代码放入我的答案中,以避免链接无效:
On this page you can see the whole code and formulas how distances of locations are calculated in Android Location class
android/location/Location.java
EDIT: According the hint from @Richard I put the code of the linked function into my answer, to avoid invalidated link:
只需使用距离公式
Sqrt( (x2-x1)^2 + (y2-y1)^2 )
just use the distance formula
Sqrt( (x2-x1)^2 + (y2-y1)^2 )