一、计算地图两点的距离
1 Oracle 中的PI v_PI:=asin(1) * 2,
赤道半径: V_DIST_R:=6370856;--赤道半径(单位m)
2 计算每个点弧度点(v_long1,v_lat1),(v_long2,v_lat2),
v_rad_lon1:=v_PI * v_lon1 / 180.00;------转化为弧度(rad)
v_rad_lat1:=v_PI * v_lat1 / 180.00;------转化为弧度(rad)
v_rad_lon2:=v_PI * v_lon2 / 180.00;------转化为弧度(rad)
v_rad_lat2:=v_PI * v_lat2 / 180.00;------转化为弧度(rad)
3 取弧度对应弧长,取绝对值
(1)弧长v_rad_lon1
if v_rad_lon1 < 0 then
v_rad_lon1:=v_PI* 2 - abs(v_rad_lon1);
end if;
(2)弧长v_rad_lat1
if v_rad_lat1 < 0 then
v_rad_lat1:=v_PI / 2 + abs(v_rad_lat1);
else
v_rad_lat1:=v_PI / 2 - abs(v_rad_lat1);
end if;
(3)弧长v_rad_lon2
if v_rad_lon2 < 0 then
v_rad_lon2:=v_PI* 2 - abs(v_rad_lon2);
end if;
(4)弧长v_rad_lat2
if v_rad_lat2 < 0 then
v_rad_lat2:=v_PI / 2 + abs(v_rad_lat2);
else
v_rad_lat2:=v_PI / 2 - abs(v_rad_lat2);
end if;
四、 计算每点(以半径)对应的x,y,z的值(利用余弦,正弦)
v_x1:= V_DIST_R*cos(v_rad_lon1) * sin(v_rad_lat1);---x1
v_y1:= V_DIST_R*sin(v_rad_lon1) * sin(v_rad_lat1);---x1
v_z1:= V_DIST_R*cos(v_rad_lat1); ---z1
v_x2:= V_DIST_R*cos(v_rad_lon2) * sin(v_rad_lat2);---x2
v_y2:= V_DIST_R*sin(v_rad_lon2) * sin(v_rad_lat2);---x2
v_z2:= V_DIST_R*cos(v_rad_lat2); ---z2
五、计算平方和
v_dist_d:=sqrt(power((v_x1-v_x2),2)+power((v_y1-v_y2),2)+power((v_z1-v_z2),2));----计算平方和
六、余弦定理求夹角
v_theta:=acos((V_DIST_R*V_DIST_R*2-v_dist_d*v_dist_d)/(V_DIST_R*V_DIST_R*2));---余弦定理求夹角
夹角与半径的距离
v_dist:=v_theta*V_DIST_R;
返回 v_dist;
七、Oracle 对应函数function getLantitudeLongitudeDist(v_lon1 number,v_lat1 number,v_lon2 number,v_lat2 number) return number
八、Ibaits 调用函数(在where条件加函数比较)将空转换为0,便于计算
<![CDATA[nvl(a.error_range,0) > nvl(PK_ACOS_LNG_LAT_DIST.getLantitudeLongitudeDist(nvl(f.longitude,0),
nvl(f.latitude,0),
nvl(s.longitude,0),
nvl(s.latitude,0)),999999)]]>
九、总结
由于系统数据太多,将数据从库中查出来 再比较(有存在在有的店暂时没有确定经纬度)比较麻烦,所以自己写了一个oracle函数就算比较容易做到,但对于系统库移到其他库时不方便,建议还是用程序实现(方便库移植,搬迁到其他数据库)
---------------------
作者:xingjun058
来源:CSDN
原文:https://blog.csdn.net/xingjun058/article/details/90707811
版权声明:本文为博主原创文章,转载请附上博文链接!