首页 > 代码库 > 两点经纬度之间距离计算
两点经纬度之间距离计算
2024-08-10 12:45:58 218人阅读
辅助类
GaoDeCoord.cs
GaoDeCoord.csusing System;using System.Collections.Generic;using System.Configuration;using System.Linq;using System.Text;namespace RB.Common{ #region 高德地图求范围自有数据 /// <summary> /// 经纬度坐标 /// </summary> public class Degree { public Degree(double x, double y) { X = x; Y = y; } private double x; public double X { get { return x; } set { x = value; } } private double y; public double Y { get { return y; } set { y = value; } } } public class CoordDispose { //WGS84坐标系 private const double EARTH_RADIUS = 6378137.0;//地球半径(米) /// <summary> /// 弧度转换为角度数公式 /// </summary> /// <param name="d"></param> /// <returns></returns> private static double degrees(double d) { return d * (180 / Math.PI); } /// <summary> /// 以一个经纬度为中心计算出四个顶点 /// </summary> /// <param name="distance">半径(米)</param> /// <returns></returns> public static Degree[] GetDegreeCoordinates(Degree Degree1, double distance) { double dlng = 2 * Math.Asin(Math.Sin(distance / (2 * EARTH_RADIUS)) / Math.Cos(Degree1.X)); dlng = degrees(dlng);//一定转换成角度数 /*** * |←0.435→| * —— ————————————————— * ↑ | | | * 0.5 | | | * ↓ | | | * —— |———————|———————| * | | | * | | | * | | | * ————————————————— * 0.5*2/0.435*2=1.149 * 如果需要求左右范围内所有数据,所以就需要*1.149 * ***/ distance = distance * 1.149; double dlat = distance / EARTH_RADIUS; dlat = degrees(dlat);//一定转换成角度数 return new Degree[] { new Degree(Math.Round(Degree1.X + dlat,6), Math.Round(Degree1.Y - dlng,6)),//left-top new Degree(Math.Round(Degree1.X - dlat,6), Math.Round(Degree1.Y - dlng,6)),//left-bottom new Degree(Math.Round(Degree1.X + dlat,6), Math.Round(Degree1.Y + dlng,6)),//right-top new Degree(Math.Round(Degree1.X - dlat,6), Math.Round(Degree1.Y + dlng,6)) //right-bottom }; } /// <summary> /// 获取两个经纬度之间的距离 /// </summary> /// <param name="LonA">经度A</param> /// <param name="LatA">纬度A</param> /// <param name="LonB">经度B</param> /// <param name="LatB">经度B</param> /// <returns>距离(米)</returns> public static double getDistance(double LonA, double LatA, double LonB, double LatB) { // 东西经,南北纬处理,只在国内可以不处理(假设都是北半球,南半球只有澳洲具有应用意义) double MLonA = LonA; double MLatA = LatA; double MLonB = LonB; double MLatB = LatB; // 地球半径(千米) //double R = 6371.004; // 地球半径(米) //double R = 6378137.0; double C = Math.Sin(rad(LatA)) * Math.Sin(rad(LatB)) + Math.Cos(rad(LatA)) * Math.Cos(rad(LatB)) * Math.Cos(rad(MLonA - MLonB)); return (EARTH_RADIUS * Math.Acos(C)); } /// <summary> /// 角度数转换为弧度公式 /// </summary> /// <param name="d"></param> /// <returns></returns> private static double rad(double d) { return d * Math.PI / 180.0; } /// <summary> /// 冒泡排序 /// </summary> /// <param name="m"></param> /// <returns></returns> public static double[] sort(double[] m) { //执行多少次 for (double i = 0; i < m.Length; i++) { //每执行1次,将最大的排在最后 //m.Length-1,因为 m[j + 1] <= m[5] for (int j = 0; j < m.Length - 1; j++) { double a = m[j]; double b = m[j + 1]; if (a > b) { m[j + 1] = a; m[j] = b; } } } return m; } } #endregion}
调用方法
Recommend
Recommend #region 04 推荐好友 + Recommend /// <summary> /// 推荐好友 /// </summary> /// <param name="userid">关注者ID</param> /// <param name="longitude">经度</param> /// <param name="latitude">纬度</param> /// <returns></returns> public JsonResponse Recommend(int userid, double longitude, double latitude) { //设置查询距离 int distance = int.Parse(ConfigurationManager.AppSettings["Distance"].ToString()); //获取不了经纬度,默认为(0,0) if (longitude == 0 && latitude == 0) { var z = new SelectSqlSection<DTemporaryRecord>().Join<DUserDetail>((a, b) => a.User_id == b.User_id).Take(10); IList<UserDetail> list = DDataBase.DataBase.ToIList<UserDetail>(z); //返回个人信息 return Response.ReturnFun(list); } //1.设定范围求圆的4个角度 Degree[] dd = CoordDispose.GetDegreeCoordinates(new Degree(longitude, latitude), distance); //2.使用冒泡排序求最大值和最小值 X,Y double[] arrX = { dd[0].X, dd[1].X, dd[2].X, dd[3].X }; double[] arrY = { dd[0].Y, dd[1].Y, dd[2].Y, dd[3].Y }; //从小到大 double[] vvX = CoordDispose.sort(arrX); double[] vvY = CoordDispose.sort(arrY); //3.经度在X最小值和最大值范围内,纬度同上 var xyz = new SelectSqlSection<DTemporaryRecord>().Join<DUserDetail>((a, b) => a.User_id == b.User_id). Where(a => a.PositionX > vvX[0] && a.PositionX < vvX[3] && a.PositionY > vvY[0] && a.PositionY < vvY[3]). Take(10); var xylist = DDataBase.DataBase.ToDataSet(xyz).Tables[0]; //4.在圆的4个角度范围内 更精确查询每个点的距离 for (int i = 0; i < xylist.Rows.Count; i++) { double DIST = CoordDispose.getDistance(longitude, latitude, double.Parse(xylist.Rows[i].ItemArray[2].ToString()), double.Parse(xylist.Rows[i].ItemArray[3].ToString())); //如果得到的距离大于设定的距离,则去掉 if (DIST > distance) { xylist.Rows.Remove(xylist.Rows[i]); i--; //游标也需要跟着-1 } } #region 数据库交互 //判断 (临时表) 关注者ID var xxx = new SelectSqlSection<DTemporaryRecord>().Where(a => a.User_id == userid); IList<TemporaryRecord> realTimelist = DDataBase.DataBase.ToIList<TemporaryRecord>(xxx); TemporaryRecord ret = new TemporaryRecord(); ret.User_id = userid; ret.PositionX = longitude; ret.PositionY = latitude; if (realTimelist == null || realTimelist.Count == 0) { //添加并返回id int id = DDataBase.DataBase.InsertScalar(ret); } else { //修改 ret.Id = realTimelist[0].Id; DDataBase.DataBase.Update(ret); } #endregion //返回查询的结果 return Response.ReturnFun(xylist); } #endregion
两点经纬度之间距离计算
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。