计算地图两点的距离的sql 函数

一、计算地图两点的距离

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函数就算比较容易做到,但对于系统库移到其他库时不方便,建议还是用程序实现(方便库移植,搬迁到其他数据库)

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页