C#经纬度距离计算仅输出单值 如何按升序输出全部最近地点
C# 地点球面距离排序输出问题修复方案
- 已定义包含
Place(地点名称)、Latitude(纬度)、Longitude(经度)属性的Location实体类,初始化10个带经纬度的地点集合 - 需求:计算所有地点与当前定位点(纬度19、经度74)的球面距离,按距离升序排序后逐行输出地点名称和对应距离
- 原有代码问题:运行后仅输出1个最近地点,无法全量输出,存在3处明确错误
原有代码3处错误说明
GetDistance方法第一个return语句后编写的逻辑属于不可达代码,永远不会执行- 调用
GetDistance时重复传入当前遍历地点的经纬度作为冗余参数,参数传递逻辑错误 - 结果输出阶段仅取升序排序后第一个Key对应的第一个地点元素,未遍历全量排序后的结果集
修正后可运行实现
实体类定义
public class Location { public string Place { get; set; } public double Latitude { get; set; } public double Longitude { get; set; } }
修复后的Haversine距离计算方法
Haversine公式用于计算球面上两点经纬度对应的大圆距离,地球平均半径取6371km,结果单位为公里
/// <summary> /// 计算两个经纬度点之间的球面距离(单位:公里) /// </summary> /// <param name="lat1">点1纬度</param> /// <param name="lon1">点1经度</param> /// <param name="lat2">点2纬度</param> /// <param name="lon2">点2经度</param> public static double GetDistance(double lat1, double lon1, double lat2, double lon2) { const double earthRadius = 6371; // 角度转弧度 double lat1Rad = lat1 * Math.PI / 180; double lon1Rad = lon1 * Math.PI / 180; double lat2Rad = lat2 * Math.PI / 180; double lon2Rad = lon2 * Math.PI / 180; double deltaLat = lat2Rad - lat1Rad; double deltaLon = lon2Rad - lon1Rad; double a = Math.Sin(deltaLat / 2) * Math.Sin(deltaLat / 2) + Math.Cos(lat1Rad) * Math.Cos(lat2Rad) * Math.Sin(deltaLon / 2) * Math.Sin(deltaLon / 2); double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); // 全量计算完成后返回结果,无提前return导致的不可达代码 return earthRadius * c; }
主逻辑实现
public static void Main() { // 固定当前定位点坐标 const double currentLat = 19; const double currentLon = 74; // 初始化10个测试地点,可替换为实际业务数据 List<Location> locations = new List<Location> { new Location { Place = "地点A", Latitude = 18.5, Longitude = 73.8 }, new Location { Place = "地点B", Latitude = 20.1, Longitude = 75.2 }, new Location { Place = "地点C", Latitude = 19.2, Longitude = 74.1 }, new Location { Place = "地点D", Latitude = 28.6, Longitude = 77.2 }, new Location { Place = "地点E", Latitude = 12.9, Longitude = 77.6 }, new Location { Place = "地点F", Latitude = 22.5, Longitude = 88.3 }, new Location { Place = "地点G", Latitude = 8.5, Longitude = 76.9 }, new Location { Place = "地点H", Latitude = 25.6, Longitude = 85.1 }, new Location { Place = "地点I", Latitude = 19.0, Longitude = 74.0 }, new Location { Place = "地点J", Latitude = 30.7, Longitude = 76.8 } }; // 构建距离-地点映射,修复参数传递逻辑:固定传入当前定位点坐标,第二个点为遍历到的目标地点 Dictionary<double, List<Location>> distanceMap = new Dictionary<double, List<Location>>(); foreach (var loc in locations) { double distance = GetDistance(currentLat, currentLon, loc.Latitude, loc.Longitude); if (!distanceMap.ContainsKey(distance)) { distanceMap[distance] = new List<Location>(); } distanceMap[distance].Add(loc); } // 修复输出逻辑:按距离升序遍历所有键,逐行输出全量结果 foreach (var dist in distanceMap.Keys.OrderBy(d => d)) { foreach (var loc in distanceMap[dist]) { Console.WriteLine($"地点名称:{loc.Place},与当前定位点距离:{dist:F2} 公里"); } } }
修复点对应说明
- 移除
GetDistance方法中提前return后的冗余不可达代码,保证Haversine公式全流程执行后返回正确距离值 - 调用
GetDistance时固定传入当前定位点经纬度作为第一个点参数,遍历到的地点经纬度作为第二个点参数,删除冗余错误的重复传参 - 输出阶段先对字典的所有键(距离值)升序排序,再遍历每个距离下的所有地点逐行输出,保证全量结果按距离从小到大展示
内容的提问来源于stack exchange,提问作者Mahi Patil
相关产品推荐
相关产品推荐

