在javascript中(jquery/PHP/ASPX/JSP等原理相似)用两点之间的经纬度计算两点之间距离的最佳实践
地球上某点的经度(latitude)和纬度(longitude)的获取:在Google maps页面()
上点击左下角的“Google地图实验室”,在弹出的新窗口中找到“经纬度工具提示”,点击启用后点击“保存更改”,之后关闭这个弹出的窗口,这时候在
Google地图上某一点单击右键,即可看到在右键菜单中看到“放置经纬度标记”选项了,点击这个选项,即可将这一点的经纬度放置在地图上。下面开始说正
事儿:如何用两点的经纬度计算两点之间的距离:
-
function getRad(d){
-
var PI = Math.PI;
-
return d*PI/180.0;
-
}
-
-
-
-
-
-
-
-
function CoolWPDistance(lat1,lng1,lat2,lng2){
-
var f = getRad((lat1 + lat2)/2);
-
var g = getRad((lat1 - lat2)/2);
-
var l = getRad((lng1 - lng2)/2);
-
var sg = Math.sin(g);
-
var sl = Math.sin(l);
-
var sf = Math.sin(f);
-
var s,c,w,r,d,h1,h2;
-
var a = 6378137.0;
-
var fl = 1/298.257;
-
sg = sg*sg;
-
sl = sl*sl;
-
sf = sf*sf;
-
s = sg*(1-sl) + (1-sf)*sl;
-
c = (1-sg)*(1-sl) + sf*sl;
-
w = Math.atan(Math.sqrt(s/c));
-
r = Math.sqrt(s*c)/w;
-
d = 2*w*a;
-
h1 = (3*r -1)/2/c;
-
h2 = (3*r +1)/2/s;
-
s = d*(1 + fl*(h1*sf*(1-sg) - h2*(1-sf)*sg));
-
s = s/1000;
-
s = s.toFixed(0);
-
return s;
-
}
-
-
var strat1=40.0823;
-
var strat2=116.6032;
-
var end1=22.320;
-
var end2=113.937;
-
var abc=CoolWPDistance(strat1,strat2,end1,end2);
-
alert(abc);
上述代码的第34行已经过滤掉了小数点以及小数点之后的字符。
上述代码的第38行起为演示数据,计算的是北京首都机场到深圳宝安机场的距离。显示为:
在百度知道中,看到有人如此作答:
-
北京首都机场到深圳机场飞行距离:2077公里。
-
飞行时间是3个小时左右。
这是某网友对于问题“从北京首都机场飞到深圳机场有多少公里?”的回答;另外,查看现在的航班,采用波音公司739机型的飞机(波音公司270-
N/A座的737-900客机,此机型的正常飞行时的平均时速为:785公里)在这两个机场之间的飞行时间大多在3个小时10分钟左右(当然,还有更长
的),3hx785km/h=2355km,可见,这位网友的回答是靠谱的,但是考虑到规划的航线不可能是最佳路径(以地心为圆心的弧形)、并且存在偏航
的可能等因素,这个计算结果应该是基本靠谱的。、
另外,如果想采用英里,可以使用如下示例中的第二个函数,示例如下:
-
>
-
<html lang="zh_CN">
-
<head>
-
<meta charset="UTF-8">
-
<meta name="author" content="Suifengtec">
-
<title>javascript distance functiontitle>
-
head>
-
<body>
-
<div id="dis">div>
-
<div id="dismiles">div>
-
<div id="diskm">div>
-
<script src="">script>
-
<script>
-
///////////////////////////define function 1
-
function getRad(d){
-
var PI = Math.PI;
-
return d*PI/180.0;
-
}
-
function CoolWPDistance(lat1,lng1,lat2,lng2){
-
var f = getRad((lat1 + lat2)/2),
-
g = getRad((lat1 - lat2)/2),
-
l = getRad((lng1 - lng2)/2),
-
sg = Math.sin(g),
-
sl = Math.sin(l),
-
sf = Math.sin(f),
-
s,c,w,r,d,h1,h2,
-
a = 6378137.0,
-
fl = 1/298.257;
-
sgsg = sg*sg;
-
slsl = sl*sl;
-
sfsf = sf*sf;
-
s = sg*(1-sl) + (1-sf)*sl;
-
c = (1-sg)*(1-sl) + sf*sl;
-
w = Math.atan(Math.sqrt(s/c));
-
r = Math.sqrt(s*c)/w;
-
d = 2*w*a;
-
h1 = (3*r -1)/2/c;
-
h2 = (3*r +1)/2/s;
-
s = d*(1 + fl*(h1*sf*(1-sg) - h2*(1-sf)*sg));
-
ss = s/1000;
-
ss = s.toFixed(0);//指定小数点后的位数。
-
return s;
-
}
-
-
///////////////////////////define function 2
-
var GeoDis = {};
-
GeoDis.RadiusInMiles = 3956.0;
-
GeoDis.RadiusInKilometers = 6367.0;
-
GeoDis.ToRadian = function(v) { return v * (Math.PI / 180);};
-
GeoDis.DiffRadian = function(v1, v2) {
-
return GeoDis.ToRadian(v2) - GeoDis.ToRadian(v1);
-
};
-
GeoDis.CalcDistance = function(lat1, lng1, lat2, lng2, radius) {
-
return radius * 2 * Math.asin( Math.min(1, Math.sqrt( ( Math.pow(Math.sin((GeoDis.DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.cos(GeoDis.ToRadian(lat1)) * Math.cos(GeoDis.ToRadian(lat2)) * Math.pow(Math.sin((GeoDis.DiffRadian(lng1, lng2)) / 2.0), 2.0) ) ) ) );
-
};
-
///////////demo
-
var lat1=40.0823,
-
lng1=116.6032,
-
lat2=22.320,
-
lng2=113.937;
-
// Calculate distance in Milesvar
-
var disinmile = GeoDis.CalcDistance(lat1, lng1, lat2, lng2, GeoDis.RadiusInMiles).toFixed(0);
-
// Calculate distance in Kilometersvar
-
var disinkim = GeoDis.CalcDistance(lat1, lng1, lat2, lng2, GeoDis.RadiusInKilometers).toFixed(0);
-
var dis=CoolWPDistance(lat1, lng1, lat2, lng2);
-
$(function(){
-
$('#dis').html('函数1:北京首都机场到深圳宝安机场之间的地球表面最短距离的公里数大致为:'+ dis);
-
$('#dismiles').html('函数2:北京首都机场到深圳宝安机场之间的地球表面最短距离的英里数大致为:'+ disinmile);
-
$('#diskm').html('函数2:北京首都机场到深圳宝安机场之间的地球表面最短距离的公里数大致为:'+disinkim);
-
})
-
script>
-
body>
-
html>
这个示例的显示结果为:
-
函数1:北京首都机场到深圳宝安机场之间的地球表面最短距离的公里数大致为:1985
-
函数2:北京首都机场到深圳宝安机场之间的地球表面最短距离的英里数大致为:1236
-
函数2:北京首都机场到深圳宝安机场之间的地球表面最短距离的公里数大致为:1990
第二个函数与上一个函数的计算相比,多了5公里,这是因为第二个函数的地球半径的值没有第第一个函数准确,但是,地球不是个正圆球体,而是一个椭圆形,所以,事情看上去很复杂,那就“大致”吧!
两个函数相比,第二个函数多了一个参数,但是能够返回两种值,并且相对来说比较简洁,第一个函数比较容易看懂,自己看着用吧!
本例中的经纬度22.320,113.937实为香港国际机场,文中描述为深圳宝安机场,是错误的,特此更正。
顺便说下经度和纬度这两个词:
经度对应的英文单词为latitude,这个词的词根是lat,表示拉扯之类的意思;纬度对应的英文单词是longtitude,可以理解其词根为
long,在现代英语中,大家应该都知道long是什么意思了。这两个词的后缀都是itude,这是一个名词后缀,表示程度,状态,性质等抽象的意思。可
见,这两个词在英语中出现的时候,英国人应该已经明白了地球不是个正圆球体,而是一个椭圆球体,因为lat的被动状态的程度显然没有long的主动性描述
的程度高。扯的有点儿远了,现在回来,这篇文章到此告一段落。
阅读(3898) | 评论(0) | 转发(0) |