注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Mr.7

我将骄傲的活在这个大唐盛世

 
 
 

日志

 
 

两个经纬度点之间的距离各个版本实现  

2013-10-09 19:43:08|  分类: 挨踢咋活 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

总是用到;存个档纪念下。该方法听说比较粗略,但是和MapABC的很一致!

1. MySQL 版

create function fnCalcDistance(x1 double, y1 double, x2 double , y2 double) return double
begin
declare Result double default -1.0;
declare PI double default 3.141592653589793;
declare EARTH_RADIUS double default 6378137.0;

declare tmpx1 double default 1.0;
declare tmpy1 double default 1.0;
declare tmpx2 double default 1.0;
declare tmpy2 double default 1.0;

declare radLng1 double;
declare radLng2 double;
declare radLat1 double;
declare radLat2 double;
declare dx double;
declare dy double;
declare s double;

if x1 > 180 then set tmpx1 = 3600; end if;
if y1 > 180 then set tmpy1 = 3600; end if;
if x2 > 180 then set tmpx2 = 3600; end if;
if y2 > 180 then set tmpy2 = 3600; end if;

set radLng1 = (x1 * PI / 180.0)/tmpx1;
set radLng2 = (x2 * PI / 180.0)/tmpy1;
set radLat1 = (y1 * PI / 180.0)/tmpx2;
set radLat2 = (y2 * PI / 180.0)/tmpy2;

set dx = radLng1 - radLng2;
set dy = radLat1 - radLat2;

set s = 2*asin(sqrt(power(sin(dy/2),2) + cos(radLat1)*cos(radLat2)*power(sin(dx/2),2)));
set s = s*EARTH_RADIUS;
set s = round(s*10000)/10000.0;
set Result=s;
return(Result);
end ;

2. Oracle 版

create or replace function fnCalcDistance(x1 in BINARY_FLOAT, y1 in BINARY_FLOAT, x2 in BINARY_FLOAT, y2 in BINARY_FLOAT) return BINARY_FLOAT is
Result BINARY_FLOAT;
PI BINARY_FLOAT:=3.141592653589793;
EARTH_RADIUS BINARY_FLOAT:=6378137.0;

radLng1 BINARY_FLOAT;
radLng2 BINARY_FLOAT;
radLat1 BINARY_FLOAT;
radLat2 BINARY_FLOAT;

tmpx1 BINARY_FLOAT:=1.0;
tmpy1 BINARY_FLOAT:=1.0;
tmpx2 BINARY_FLOAT:=1.0;
tmpy2 BINARY_FLOAT:=1.0;

dx BINARY_FLOAT;
dy BINARY_FLOAT;
s BINARY_FLOAT;

begin
if x1>180 then
tmpx1 :=3600;
end if;
if y1>180 then
tmpy1 :=3600;
end if;
if x2>180 then
tmpx2 :=3600;
end if;
if y2>180 then
tmpy2 :=3600;
end if;
radLng1 := (x1 * PI / 180.0)/tmpx1;
radLng2 := (x2 * PI / 180.0)/tmpx2;
radLat1 := (y1 * PI / 180.0)/tmpy1;
radLat2 := (y2 * PI / 180.0)/tmpy2;
dx := radLng1 - radLng2;
dy := radLat1 - radLat2;

s := 2*asin(sqrt(power(sin(dy/2),2) + cos(radLat1)*cos(radLat2)*power(sin(dx/2),2)));
s := s*EARTH_RADIUS;
s := round(s*10000)/10000.0;
Result:=s;
return(Result);
end fnCalcDistance;

3. JS 版

var EARTH_RADIUS = 6378137.0; //单位M
var PI = Math.PI;
function getRad(d)
{
return d*PI/180.0;
}

//算法1:求两点之间的距离
function getGreatCircleDistance(lng1,lat1,lng2,lat2)
{
var radLat1 = getRad(lat1);
var radLat2 = getRad(lat2);

var dy = radLat1 - radLat2; //a
var dx = getRad(lng1) - getRad(lng2); //b

var s = 2*Math.asin(Math.sqrt(Math.pow(Math.sin(dy/2),2) + Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(dx/2),2)));
s = s*EARTH_RADIUS;
s = Math.round(s*10000)/10000.0;

return s;
}

4. Java 版

public class CaclDistance
{
static double EARTH_RADIUS = 6378137.0; //单位M
static double PI = Math.PI;
private static double getRad(double d)
{
return d*PI/180.0;
}

//算法1:求两点之间的距离,输入单位:度; 返回单位:米
private static double getGreatCircleDistance(double lng1, double lat1, double lng2,double lat2)
{
double radLat1 = getRad(lat1);
double radLat2 = getRad(lat2);

double dy = radLat1 - radLat2; //a
double dx = getRad(lng1) - getRad(lng2); //b

double s = 2*Math.asin(Math.sqrt(Math.pow(Math.sin(dy/2),2) + Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(dx/2),2)));
s = s*EARTH_RADIUS;
s = Math.round(s*10000)/10000.0;

return s;
}

public static double calcDistance(double x1, double y1, double x2, double y2)
{
if(x1>180)
x1/=3600;
if(y1>180)
y1/=3600;
if(x2>180)
x2/=3600;
if(y2>180)
y2/=3600;

return getGreatCircleDistance(x1,y1, x2,y2);
}

public static void main(String[] args)
{
double len = calcDistance(109.1*3600, 34.0*3600,109.1*3600, 34.0*3600+1);
System.out.println("len="+len);
}
}

5. C++ 版

#ifndef PI
#define PI (3.14159265358)
#endif

// 计算当前坐标位置上, 纬度上的1秒对应的距离(米)
double CalLatLength(double dLat, double dLon, double dH)
{
double dLat1,dLon1,dH1,dLat2,dLon2,dH2;
double B1,L1,B2,L2;
double X1,Y1,Z1,X2,Y2,Z2;
double dLen;

dLat1 = dLat;
dLon1 = dLon;
dH1 = dH;

dLat2 = dLat + 1;
dLon2 = dLon;
dH2 = dH;

B1 = dLat1 / 3600;
B1 = B1 * PI / 180; L1 = dLon1 / 3600;
L1 = L1 * PI / 180;

double N1 = 6378137 / sqrt(1 - 6.69437999014132E-03 * sin(B1) * sin(B1));
X1 = (N1 + dH1) * cos(B1) * cos(L1);
Y1 = (N1 + dH1) * cos(B1) * sin(L1);
Z1 = (N1 * (1 - 6.69437999014132E-03) + dH1) * sin(B1);

B2 = dLat2 / 3600 * PI / 180;
L2 = dLon2 / 3600 * PI / 180;

double N2 = 6378137 / sqrt(1 - 6.69437999014132E-03 * sin(B2) * sin(B2));
X2 = (N2 + dH2) * cos(B2) * cos(L2);
Y2 = (N2 + dH2) * cos(B2) * sin(L2);
Z2 = (N2 * (1 - 6.69437999014132E-03) + dH2) * sin(B2);

dLen = sqrt((X1 - X2)*(X1 - X2) + (Y1 - Y2)*(Y1 - Y2) + (Z1 - Z2)*(Z1 - Z2));
return dLen;
}

// 计算当前坐标位置上, 经度上的1秒对应的距离(米)
double CalLonLength(double dLat, double dLon, double dH)
{
double dLat1,dLon1,dH1,dLat2,dLon2,dH2;
double B1,L1,B2,L2;
double X1,Y1,Z1,X2,Y2,Z2;
double dLen;

dLat1 = dLat;
dLon1 = dLon;
dH1 = dH;

dLat2 = dLat;
dLon2 = dLon + 1;
dH2 = dH;

B1 = dLat1 / 3600 * PI / 180;
L1 = dLon1 / 3600 * PI / 180;

double N1 = 6378137 / sqrt(1 - 6.69437999014132E-03 * sin(B1) * sin(B1));
X1 = (N1 + dH1) * cos(B1) * cos(L1);
Y1 = (N1 + dH1) * cos(B1) * sin(L1);
Z1 = (N1 * (1 - 6.69437999014132E-03) + dH1) * sin(B1);

B2 = dLat2 / 3600 * PI / 180;
L2 = dLon2 / 3600 * PI / 180;

double N2 = 6378137 / sqrt(1 - 6.69437999014132E-03 * sin(B2) * sin(B2));
X2 = (N2 + dH2) * cos(B2) * cos(L2);
Y2 = (N2 + dH2) * cos(B2) * sin(L2);
Z2 = (N2 * (1 - 6.69437999014132E-03) + dH2) * sin(B2);

dLen = sqrt((X1 - X2)*(X1 - X2) + (Y1 - Y2)*(Y1 - Y2) + (Z1 - Z2)*(Z1 - Z2));
return dLen;
}

  评论这张
 
阅读(695)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018