.NET计算2个经纬度之间距离采用的百度算法

在网上找了一些相关的方法,但是测算出来的结果与百度官方测算出的结果误差较大,于是根据百度官方的JS API的函数更改成了.NET和sql版本,计算出的结果与百度官方测算结果基本一致。

 

1.百度JS API的版本javascript

            function fD(a, b, c) {
                for (; a > c;)
                    a -= c - b;
                for (; a < b;)
                    a += c - b;
                return a;
            };
            function jD(a, b, c) {
                b != null && (a = Math.max(a, b));
                c != null && (a = Math.min(a, c));
                return a;
            };
            function yk(a) {
                return Math.PI * a / 180
            };
            function Ce(a, b, c, d) {
                var dO = 6370996.81;
                return dO * Math.acos(Math.sin(c) * Math.sin(d) + Math.cos(c) * Math.cos(d) * Math.cos(b - a));
            };
            function getDistance(a, b) {
                if (!a || !b)
                    return 0;
                a.lng = fD(a.lng, -180, 180);
                a.lat = jD(a.lat, -74, 74);
                b.lng = fD(b.lng, -180, 180);
                b.lat = jD(b.lat, -74, 74);
                return Ce(yk(a.lng), yk(b.lng), yk(a.lat), yk(b.lat));
            };
            
            alert(getDistance({ lng: 106.486654, lat: 29.490295 }, { lng: 106.581515, lat: 29.615467 }));

2 .NET版本

        public double fD(double a, double b, double c)
        {
             
            for (; a > c;)
                a -= c - b;
            for (; a < b;)
                a += c - b;
            return a;
        }
        public double jD(double a, double b, double c)
        {
            if (b != 0)
            {
                a = Math.Max(a, b);
            }
            if (c != 0)
            {
                a = Math.Min(a, c);
            }
            return a;
        }
        public double yk(double a)
        {
            return Math.PI * a / 180;
        }
        public double Ce(double a, double b, double c, double d)
        {
            var dO = 6370996.81;
            return dO * Math.Acos(Math.Sin(c) * Math.Sin(d) + Math.Cos(c) * Math.Cos(d) * Math.Cos(b - a));
        }
        public double getDistance(double lat1, double lng1, double lat2, double lng2)
        {

            lng1 = fD(lng1, -180, 180);
            lat1 = jD(lat1, -74, 74);
            lng2 = fD(lng2, -180, 180);
            lat2 = jD(lat2, -74, 74);
            return Ce(yk(lng1), yk(lng2), yk(lat1), yk(lat2));
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            Response.Write(getDistance(29.490295, 106.486654, 29.615467, 106.581515));
        }

3 SQL函数版本,直接执行代码就可以自动创建相关方法。

USE [数据库名]
GO
/****** Object:  UserDefinedFunction [dbo].[Ce]    Script Date: 2016/4/8 18:14:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[Ce](@a REAL,@b REAL,@c REAL,@d REAL) 
returns REAL
as
begin
    DECLARE @dO REAL=6370996.81;
     return @dO * Acos(Sin(@c) * Sin(@d) + Cos(@c) * Cos(@d) * Cos(@b - @a));
end
GO
/****** Object:  UserDefinedFunction [dbo].[fD]    Script Date: 2016/4/8 18:14:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[fD](@a REAL,@b REAL,@c REAL) 
returns REAL
as
begin
             WHILE @a > @c
             BEGIN
               SET @a =@a- (@c - @b);
             END
             WHILE @a < @b
             BEGIN
              SET  @a =@a+(@c - @b);
             END
      return @a;
end

GO
/****** Object:  UserDefinedFunction [dbo].[getNewDistance]    Script Date: 2016/4/8 18:14:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[getNewDistance](@lat1 REAL,@lng1 REAL,@lat2 REAL,@lng2 REAL) 
returns REAL
as
begin
            SET @lng1 = [dbo].fD(@lng1, -180, 180);
            SET @lat1 = [dbo].jD(@lat1, -74, 74);
            SET @lng2 = [dbo].fD(@lng2, -180, 180);
            SET @lat2 = [dbo].jD(@lat2, -74, 74);
            return [dbo].Ce([dbo].yk(@lng1), [dbo].yk(@lng2), [dbo].yk(@lat1), [dbo].yk(@lat2));
end
GO
/****** Object:  UserDefinedFunction [dbo].[jD]    Script Date: 2016/4/8 18:14:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[jD](@a REAL,@b REAL,@c REAL) 
returns REAL
as
begin
     IF @b!=0
        BEGIN
            IF @a<@b
                BEGIN
                    SET @a=@b
                END
        END
     IF @c!=0
        BEGIN
            IF @a>@C
                BEGIN
                SET @a=@C
                END
        END
     return @a
end
GO
/****** Object:  UserDefinedFunction [dbo].[yk]    Script Date: 2016/4/8 18:14:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[yk](@a REAL) 
returns REAL
as
begin
    DECLARE @yk REAL;
    SET @yk=PI() * @a / 180;
    RETURN @yk;
end
GO

SQL版本调用方式:[dbo].[getNewDistance](29.490295, 106.486654, 29.615467, 106.581515)

 

posted @ 2016-04-11 09:35  唐学阳  阅读(214)  评论(0)    收藏  举报