• 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);

  • 相关阅读:
    学习windows的半天+学习Git分布式系统的半天
    输出从1加到100的结果、打印100以内的质数、计算一个文件中的每个英文单词出现的次数
    Linux操作系统--初级--进程管理的命令
    Linux操作系统--初级--防火墙
    Linux操作系统--初级--dns服务
    Linux操作系统--初级--网络安全基础
    Linux操作系统--初级--进程管理
    Linux操作系统--初级--Linux网络
    Linux操作系统--初级--Linux磁盘管理
    Linux操作系统--初级--Linux的用户与用户组(权限管理)
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/2844203.html
Copyright © 2020-2023  润新知