.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)

浙公网安备 33010602011771号