GPS定位,经纬度附近地点查询–C 实现方法

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

目前的工作是需要手机查找附近N米以内的商户,功能如下图

数据库中记录了商家在百度标注的经纬度(如:116.412007, 39.947545),

最初想法  以圆心点为中心点,对半径做循环,半径每增加一个像素(暂定1米)再对周长做循环,到数据库中查询对应点的商家(真是一个长时间的循环工作)

上网百度类似的文章有了点眉目

大致想法是已知一个中心点,一个半径,求圆包含于圆抛物线里所有的点,这样的话就需要知道所要求的这个圆的对角线的顶点,问题来了 经纬度是一个点,半径是一个距离,不能直接加减

 终于找到想要的文章

http://digdeeply.org/archives/06152067.html

PHP,Mysql-根据一个给定经纬度的点,进行附近地点查询–合理利用算法,效率提高2125倍

参考原文章 lz改成了C#类

废话不多少直接上代码:

  1 /// <summary>  2     /// 经纬度坐标  3     /// </summary>      4   5   public class Degree  6     {  7         public Degree(double x, double y)  8         {  9             X = x; 10             Y = y; 11         } 12         private double x; 13  14         public double X 15         { 16             get { return x; } 17             set { x = value; } 18         } 19         private double y; 20  21         public double Y 22         { 23             get { return y; } 24             set { y = value; } 25         } 26     } 27  28  29     public class CoordDispose 30     { 31         private const double EARTH_RADIUS = 6378137.0;//地球半径(米) 32  33         /// <summary> 34         /// 角度数转换为弧度公式 35         /// </summary> 36         /// <param name="d"></param> 37         /// <returns></returns> 38         private static double radians(double d) 39         { 40             return d * Math.PI / 180.0; 41         } 42  43         /// <summary> 44         /// 弧度转换为角度数公式 45         /// </summary> 46         /// <param name="d"></param> 47         /// <returns></returns> 48         private static double degrees(double d) 49         { 50             return d * (180 / Math.PI); 51         } 52  53         /// <summary> 54         /// 计算两个经纬度之间的直接距离 55         /// </summary> 56  57         public static double GetDistance(Degree Degree1, Degree Degree2) 58         { 59             double radLat1 = radians(Degree1.X); 60             double radLat2 = radians(Degree2.X); 61             double a = radLat1 - radLat2; 62             double b = radians(Degree1.Y) - radians(Degree2.Y); 63  64             double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + 65              Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))); 66             s = s * EARTH_RADIUS; 67             s = Math.Round(s * 10000) / 10000; 68             return s; 69         } 70  71         /// <summary> 72         /// 计算两个经纬度之间的直接距离(google 算法) 73         /// </summary> 74         public static double GetDistanceGoogle(Degree Degree1, Degree Degree2) 75         { 76             double radLat1 = radians(Degree1.X); 77             double radLng1 = radians(Degree1.Y); 78             double radLat2 = radians(Degree2.X); 79             double radLng2 = radians(Degree2.Y); 80  81             double s = Math.Acos(Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Cos(radLng1 - radLng2) + Math.Sin(radLat1) * Math.Sin(radLat2)); 82             s = s * EARTH_RADIUS; 83             s = Math.Round(s * 10000) / 10000; 84             return s; 85         } 86  87         /// <summary> 88         /// 以一个经纬度为中心计算出四个顶点 89         /// </summary> 90         /// <param name="distance">半径(米)</param> 91         /// <returns></returns> 92         public static Degree[] GetDegreeCoordinates(Degree Degree1, double distance) 93         { 94             double dlng = 2 * Math.Asin(Math.Sin(distance / (2 * EARTH_RADIUS)) / Math.Cos(Degree1.X)); 95             dlng = degrees(dlng);//一定转换成角度数  原PHP文章这个地方说的不清楚根本不正确 后来lz又查了很多资料终于搞定了 96  97             double dlat = distance / EARTH_RADIUS; 98             dlat = degrees(dlat);//一定转换成角度数 99 100             return new Degree[] { new Degree(Math.Round(Degree1.X + dlat,6), Math.Round(Degree1.Y - dlng,6)),//left-top101                                   new Degree(Math.Round(Degree1.X - dlat,6), Math.Round(Degree1.Y - dlng,6)),//left-bottom102                                   new Degree(Math.Round(Degree1.X + dlat,6), Math.Round(Degree1.Y + dlng,6)),//right-top103                                   new Degree(Math.Round(Degree1.X - dlat,6), Math.Round(Degree1.Y + dlng,6)) //right-bottom104             };105 106         }107     }

测试方法:

 1  static void Main(string[] args) 2         { 3             double a = CoordDispose.GetDistance(new Degree(116.412007, 39.947545), new Degree(116.412924, 39.947918));//116.416984,39.944959 4             double b = CoordDispose.GetDistanceGoogle(new Degree(116.412007, 39.947545), new Degree(116.412924, 39.947918)); 5             Degree[] dd = CoordDispose.GetDegreeCoordinates(new Degree(116.412007, 39.947545), 102); 6             Console.WriteLine(a+" "+b); 7             Console.WriteLine(dd[0].X + "," + dd[0].Y ); 8             Console.WriteLine(dd[3].X + "," + dd[3].Y); 9             Console.ReadLine();10         }

       lz试了很多次 误差在1米左右

拿到圆的顶点就好办了

数据库要是sql 2008的可以直接进行空间索引经纬度字段,这样应该性能更好(没有试过)

lz公司数据库还老 2005的 这也没关系,关键是经纬度拆分计算,这个就不用说了 网上多的是 最后上个实现的sql语句

SELECT id,zuobiao FROM dbo.zuobiao WHERE zuobiao<>'' AND dbo.Get_StrArrayStrOfIndex(zuobiao,',',1)>116.41021 ANDdbo.Get_StrArrayStrOfIndex(zuobiao,',',1)<116.413804 ANDdbo.Get_StrArrayStrOfIndex(zuobiao,',',2)<39.949369 ANDdbo.Get_StrArrayStrOfIndex(zuobiao,',',2)>39.945721

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

猜你喜欢

转载自blog.csdn.net/ugfdfgg/article/details/84076749