经纬度相关计算
2010-07-13 03:01 韩龙 阅读(5019) 评论(7) 编辑 收藏 举报近期做一个与GRPS相关的应用,涉及到经纬度的计算,找资料时颇费了一番功夫,特此将其相关资料整理了一下,发布出来,希望对用到的同学有所帮助。
闲话少说,经纬度计算主要有两种:
1. 知道两点的经纬度值,计算两点间的距离
2. 知道一点的经纬度,知道另一点相对于此点的角度,距离。计算另一点的经纬度信息
对于第一种计算,网上搜索到大概有三种:
1. 把地球当球体,根据球面公式计算
2. 根据如下公式进行计算:
其中A点纬度、经度分别为lat1和lon1,B点的纬度、经度分别为lat2和lon2,D为距离。
这个公式搜索结果挺多,在百度搜索"经纬度 计算距离"很多都是这个公式。
3. 从Google地图中反推出的算法(详见参考文档1)。公式如下图
公式中经纬度均用弧度表示;lat1,lon1 表示A点经纬度,lat2,lon2 表示B点经纬度;
a= lat1 – lat2 为两点纬度之差 ; b= lon1 - lon2 为两点经度之差;
6378.137为地球半径,单位为公里;
第一种没做验证,第二种测试了一下,偏差较大(以圆明园、动物园之间的距离进行测定)目前采用的是第三种算法。
第二种计算,找到的资料很少,倒是找到不少遇到相同问题的朋友。不过最终还是找到了(详见参考文档2)。并使用第一种计算进行反验证,偏差很小。
整理后的代码如下:
经纬度类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; namespace GeoSite { /// <summary> /// 经纬度表示类 /// 经纬度计算主要有两种: /// 1. 知道两点的经纬度值,计算两点间的距离 /// 2. 知道一点的经纬度,知道另一点相对于此点的角度,距离。计算另一点的经纬度信息 /// http://blog.csdn.net/fdnike/archive/2007/07/18/1696603.aspx /// </summary> public class LatLon { /// <summary> /// 赤道半径 earth radius /// </summary> public const double EARTH_RADIUS = 6378137; /// <summary> /// 极半径 polar radius /// </summary> public const double POLAR_RADIUS = 6356725; /// <summary> /// /// </summary> public LatLon() { } /// <summary> /// 构造函数 /// </summary> /// <param name="lat">维度</param> /// <param name="lon">经度</param> public LatLon( double lat, double lon) { this .Lat = lat; this .Lon = lon; } /// <summary> /// 纬度 /// </summary> public double Lat { get ; set ; } /// <summary> /// 经度 /// </summary> public double Lon { get ; set ; } /// <summary> /// 纬度的弧度 /// </summary> public double RadLat { get { return Lat * Math.PI / 180; } } /// <summary> /// 经度的弧度 /// </summary> public double RadLon { get { return Lon * Math.PI / 180; } } /// <summary> /// ? /// </summary> public double Ec { get { return POLAR_RADIUS + (EARTH_RADIUS - POLAR_RADIUS) * (90 - Lat) / 90; } } /// <summary> /// ? /// </summary> public double Ed { get { return Ec * Math.Cos(RadLat); } } } } |
计算类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; namespace GeoSite { /// <summary> /// Geo辅助类 /// </summary> public static class GeoHelper { /// <summary> /// 根据两点的经纬度计算两点距离 /// </summary> /// <param name="src">A点维度</param> /// <param name="dest">B点经度</param> /// <returns></returns> public static double GetDistance(LatLon src, LatLon dest) { if (Math.Abs(src.Lat) > 90 || Math.Abs(dest.Lat) > 90 || Math.Abs(src.Lon) > 180 || Math.Abs(dest.Lon) > 180) throw new ArgumentException( "经纬度信息不正确!" ); double latDis = src.RadLat - dest.RadLat; double lonDis = src.RadLon - dest.RadLon; double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(latDis / 2), 2) + Math.Cos(src.Lat) * Math.Cos(dest.Lat) * Math.Pow(Math.Sin(lonDis / 2), 2))); s = s * LatLon.EARTH_RADIUS / 1000; s = Math.Round(s * 10000) / 10000; return s; } /// <summary> /// 根据两点的经纬度计算两点距离 /// </summary> /// <param name="lat1">A点维度</param> /// <param name="lon1">A点经度</param> /// <param name="lat2">B点维度</param> /// <param name="lon2">B点经度</param> /// <returns></returns> public static double GetDistance( double lat1, double lon1, double lat2, double lon2) { LatLon src = new LatLon(lat1, lon1); LatLon dest = new LatLon(lat2, lon2); return GetDistance(src, dest); } /// <summary> /// 已知点A经纬度,根据B点据A点的距离,和方位,求B点的经纬度 /// </summary> /// <param name="a">已知点A</param> /// <param name="distance">B点到A点的距离 </param> /// <param name="angle">B点相对于A点的方位,12点钟方向为零度,角度顺时针增加</param> /// <returns>B点的经纬度坐标</returns> public static LatLon GetLatLon(LatLon a, double distance, double angle) { double dx = distance * 1000 * Math.Sin(angle * Math.PI / 180); double dy = distance * 1000 * Math.Cos(angle * Math.PI / 180); double lon = (dx / a.Ed + a.RadLon) * 180 / Math.PI; double lat = (dy / a.Ec + a.RadLat) * 180 / Math.PI; LatLon b = new LatLon(lat, lon); return b; } /// <summary> /// 已知点A经纬度,根据B点据A点的距离,和方位,求B点的经纬度 /// </summary> /// <param name="longitude">已知点A经度</param> /// <param name="latitude">已知点A纬度</param> /// <param name="distance">B点到A点的距离</param> /// <param name="angle">B点相对于A点的方位,12点钟方向为零度,角度顺时针增加</param> /// <returns>B点的经纬度坐标</returns> public static LatLon GetLatLon( double longitude, double latitude, double distance, double angle) { LatLon a = new LatLon(latitude, longitude); return GetLatLon(a, distance, angle); } } } |
示例运行结果:
参考文档:
1. 通过经纬度计算距离的公式
2. 经纬度距离计算
http://blog.csdn.net/fdnike/archive/2007/07/18/1696603.aspx
开发环境:VS2008
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端