sql server 标量值函数 计算两个经纬度之间的距离

 

标量函数:

View Code
create FUNCTION dbo.fn_GetDistance  
(  
    @LngBegin REAL,
    @LatBegin REAL, 
    @LngEnd REAL,
    @LatEnd REAL    
)  
RETURNS FLOAT  
AS  
BEGIN  
    DECLARE @Distance REAL  
    DECLARE @EARTH_RADIUS REAL  
    SET @EARTH_RADIUS = 6378.137 --地球半径 已经是除以1000的值,所以后面计算出来的是千米及公里  
      
    DECLARE @RadLatBegin REAL, @RadLatEnd REAL, @RadLatDiff REAL, @RadLngDiff REAL  
    SET @RadLatBegin = @LatBegin * PI() / 180.0  
    SET @RadLatEnd = @LatEnd * PI() / 180.0  
    SET @RadLatDiff = @RadLatBegin - @RadLatEnd  
    SET @RadLngDiff = @LngBegin * PI() / 180.0 - @LngEnd * PI() / 180.0  
      
    SET @Distance = 2 * ASIN(SQRT(POWER(Sin(@RadLatDiff / 2), 2) + COS(@RadLatBegin) * COS(@RadLatEnd) * POWER(SIN(@RadLngDiff/2),2)))  
    SET @Distance = @Distance * @EARTH_RADIUS  
    --SET @Distance = Round(@Distance * 10000) / 10000  
      
    RETURN @Distance  
END  

调用方法:方法名称前面一定要加 dbo.

--参数1:开始经度 参数2:开始纬度 参数3:结束点经度 参数4:结束点纬度

select  dbo.fn_GetDistance(115.9856,36.4507,115.75,36.12)
select  dbo.fn_GetDistance('115.9856','36.4507','115.75','36.12')

 以上打印出结果为:如下图,单位为公里或千米

 

 DBO是每个数据库的默认用户,具有所有者权限,即DbOwner

通过用DBO作为所有者来定义对象,能够使数据库中的任何用户引用而不必提供所有者名称。
比如:你以User1登录进去并建表Table,而未指定DBO,
当用户User2登进去想访问Table时就得知道这个Table是你User1建立的,要写上User1.Table,如果他不知道是你建的,则访问会有问题。
如果你建表时把所有者指给了Dbo,则别的用户进来时写上Dbo.Table就行了,不必知道User1。
不光表是如此,视图等等数据库对象建立时也要如此才算是好。

建表、存储过程、视图等数据库对象时,其对应的所有者是创建它的用户。则除了该用户其他登录用户要引用这些东东时,都要加上前缀,很是麻烦。而且,程序因此易出错,你查来查去问题确出在这,浪费你时间。

 C#的实现方法,原理与上面的是一样的,网络上搜集到的。两种方法的原理一样,因为结果也是一样的

View Code
/// <summary>
    /// 计算地球上任意两点距离
    /// </summary>
    /// <param name="long1"></param>
    /// <param name="lat1"></param>
    /// <param name="long2"></param>
    /// <param name="lat2"></param>
    /// <returns>返回长度单位是米</returns>
    private static double Distance(double long1, double lat1, double long2, double lat2)
    {
        double a, b, R;
        R = 6378137; //地球半径
        lat1 = lat1 * Math.PI / 180.0;
        lat2 = lat2 * Math.PI / 180.0;
        a = lat1 - lat2;
        b = (long1 - long2) * Math.PI / 180.0;
        double d;
        double sa2, sb2;
        sa2 = Math.Sin(a / 2.0);
        sb2 = Math.Sin(b / 2.0);
        d = 2 * R * Math.Asin(Math.Sqrt(sa2 * sa2 + Math.Cos(lat1) * Math.Cos(lat2) * sb2 * sb2));
        return d;
    }

 

C#方法2

google maps的脚本里代码
    /**
  * google maps的脚本里代码
  */

    private const double EARTH_RADIUS = 6378.137;

    private static double rad(double d)
    {
        return d * Math.PI / 180.0;
    }

    /**
      * 根据两点间经纬度坐标(double值),计算两点间距离,单位为米
      */
    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;
    }

调用方法:

double dis = Distance(115.9856, 36.4507, 115.75, 36.11);
double dis1 = GetDistance(36.4507, 115.9856,36.11,115.75);
Response.Write("两点之间的距离:"+dis+"---"+dis1);

 

 

 

 

 

posted @ 2013-01-04 14:50  高山-景行  阅读(949)  评论(0编辑  收藏  举报