Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

路漫漫,长修远,我们不能没有钱

通过两个点的经纬度计算距离

最近开始做一个类似gis的东西. 需要求一些经纬度相关的值..

看了通过两个点的经纬度计算距离这篇,据说是Google里扒来的算法,于是决定验证一下。
通过计算发现非常正确。
用30,120和31,121两个坐标点进行验证,同Mapinfo中计算的结果非常的相近。
后来又把坐标系直接当成直角坐标系来计算,发现误差很大。
于是仍然用直角坐标系方法来计算,给纬度加上了个0.86的参数,这样计算下来和结果相近。




c#代码
private const double EARTH_RADIUS = 6378.137; //地球半径
private static double rad(double d)
{
   return d * Math.PI / 180.0;
}

public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
   double radLat1 = rad(lat1);
   double radLat2 = rad(lat2);
   double a = radLat1 - radLat2;
   double b = rad(lng1) - rad(lng2);
   double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) +
    Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2)));
   s = s * EARTH_RADIUS;
   s = Math.Round(s * 10000) / 10000;
   return s;
}


vb代码

Const EARTH_RADIUS = 6378.137
Const Pi = 3.1415926535898

Function rad(ByVal d As Double) As Double
rad = d * Pi / 180
End Function

Function GetDistance(lat1 As Double, lng1 As Double, lat2 As Double, lng2 As Double) As Double
Dim radlat1 As Double, radlat2 As Double
Dim a As Double, b As Double, s As Double, Temp As Double
radlat1 = rad(lat1)
radlat2 = rad(lat2)
a = radlat1 - radlat2
b = rad(lng1) - rad(lng2)
Temp = Sqr(Sin(a / 2) ^ 2 + Cos(radlat1) * Cos(radlat2) * Sin(b / 2) ^ 2)
s = 2 * Atn(Temp / Sqr(-Temp * Temp + 1))     '没有反正弦函数,网上找了个
s = s * EARTH_RADIUS
GetDistance = s
End Function

Private Sub Command1_Click()
Text5.Text = Str(GetDistance(Val(Text1.Text), Val(Text2.Text), Val(Text3.Text), Val(Text4.Text)))
End Sub

Private Sub Command2_Click()
Text5.Text = Str((Sqr((Val(Text3.Text) - Val(Text1.Text)) ^ 2 + (Val(Text4.Text) - Val(Text2.Text)) ^ 2)) * 111.3199338)
End Sub

Private Sub Command3_Click()
Text5.Text = Str((Sqr((Val(Text3.Text) * 0.86 - Val(Text1.Text) * 0.86) ^ 2 + (Val(Text4.Text) - Val(Text2.Text)) ^ 2)) * 111.3199338)
End Sub



同纬度计算比较简单

A(60,30),B(60,90)两点之间,此段代码和我用余弦定理算出来的结果很一致。
余弦定理的步骤是:1、算A、B弦长:地球半径R*cos(经度差60)=R/2;
2、算角AOB,O为地球圆心,利用余弦定理,
cosAOB=(2R*R-(R/2)^2) /2*R*R=7/8;
3、弧AB的长为:R*arc cos(7/8);求毕



原理:

地球赤道上环绕地球一周走一圈共40075.04公里,而@一圈分成360°,而每1°(度)有60,每一度一秒在赤道上的长度计算如下:

  40075.04km/360°=111.31955km

  111.31955km/60=1.8553258km=1855.3m

  而每一分又有60秒,每一秒就代表1855.3m/60=30.92m

  任意两点距离计算公式为

  d=111.12cos{1/[sinΦAsinΦB十cosΦAcosΦBcos(λB—λA)]}

  其中A点经度,纬度分别为λA和ΦA,B点的经度、纬度分别为λB和ΦB,d为距离。


posted on 2008-02-28 15:18 Khan 阅读(15453) 评论(11)  编辑 收藏 引用 所属分类: GCC/G++跨平台开发Java周边技术

评论

# re: 通过两个点的经纬度计算距离 2008-07-10 09:51 Mr.Fan

公式不准  回复  更多评论   

# re: 通过两个点的经纬度计算距离 2008-08-05 21:42

没对  回复  更多评论   

# re: 通过两个点的经纬度计算距离 2008-09-23 22:58 huang

公式 d=111.12cos{1/[sinΦAsinΦB十cosΦAcosΦBcos(λB—λA)]} 肯定是错的:cos 的值在-1 到 1 之间,111.12cos{...} 其绝对值不超过111.12.
这个公式算出的结果意味着任意两点之间的距离小于111.12.  回复  更多评论   

# re: 通过两个点的经纬度计算距离 2009-08-27 15:28 guoke

没有参考价值  回复  更多评论   

# re: 通过两个点的经纬度计算距离[未登录] 2009-12-18 10:32 bo

public static void main(String args[]) {
double latA=rad(36.6),lngA=rad(116.4);
double latB=rad(36.7),lngB=rad(116.4);
//double d=111.12*Math.cos(1/(Math.sin(latA)*Math.sin(latB)+Math.cos(latA)*Math.cos(latB)*Math.cos(lngB-lngA)));
double d=2*Math.asin(Math.sqrt(Math.pow(Math.sin((latA-latB)/2), 2)+Math.cos(latA)*Math.cos(latB)*Math.pow(Math.sin((lngA-lngB)/2), 2)))*6378.137;
System.out.println(d);


}

private static double rad(double d){
return d * Math.PI / 180.0;
}   回复  更多评论   

# re: 通过两个点的经纬度计算距离 2011-08-17 12:02 香香

请问返回的是千米吗?  回复  更多评论   

# re: 通过两个点的经纬度计算距离 2011-08-17 12:03 香香

这个是我的QQ 等楼主有空了 能告诉我一下吗  回复  更多评论   

# re: 通过两个点的经纬度计算距离 2011-08-17 12:03 香香

1608036033  回复  更多评论   

# re: 通过两个点的经纬度计算距离[未登录] 2011-08-27 16:22 1

@huang
那个貌似是Asin 吧,怎么可能会只在在-1~1   回复  更多评论   

# re: 通过两个点的经纬度计算距离[未登录] 2011-08-27 16:23 1

@香香


最后经过一个 round 应该是千米 吧  回复  更多评论   

# re: 通过两个点的经纬度计算距离 2011-10-12 23:26 洛丽塔

你好 ,我看过可以用两个标志物计算经纬度的  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2012年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

公告

短信大全 for android 1.5
豌豆荚一键安装

现在时刻

IM在线情况:
点击这里给我发消息

常用链接

留言簿(33)

随笔分类(218)

随笔档案(163)

相册

技术

友情链接

最新随笔

搜索

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜