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


              摘要:目前的工作是需要手机查找附近N米以内的商户,功能如下图数据库中记录了商家在百度标注的经纬度(如:116.412007,39.947545),最初想法以圆心点为中心点,对半径做循环,半径每增加一个像素(暂定1米)再对周长做循环,到数据库中查询对应点的商家(真是一个长时间的循环工作)上网百度类似的文章有了点眉目大致想法是已知一个中心点,一个半径,求圆包含于圆抛物线里所有的点,这样的话就需要知道所要求的这个圆的对角线的顶点,问题来了经纬度是一个点,半径是一个距离

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

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

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

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

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

    终于找到想要的文章

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

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

    /// <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
         {
             private const double EARTH_RADIUS = 6378137.0;//地球半径(米)
     
             /// <summary>
             /// 角度数转换为弧度公式
             /// </summary>
             /// <param name="d"></param>
             /// <returns></returns>
             private static double radians(double d)
             {
                 return d * Math.PI / 180.0;
             }
     
             /// <summary>
             /// 弧度转换为角度数公式
             /// </summary>
             /// <param name="d"></param>
             /// <returns></returns>
             private static double degrees(double d)
             {
                 return d * (180 / Math.PI);
             }
     
             /// <summary>
             /// 计算两个经纬度之间的直接距离
             /// </summary>
     
             public static double GetDistance(Degree Degree1, Degree Degree2)
             {
                 double radLat1 = radians(Degree1.X);
                 double radLat2 = radians(Degree2.X);
                 double a = radLat1 - radLat2;
                 double b = radians(Degree1.Y) - radians(Degree2.Y);
     
                 double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
                  Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
                 s = s * EARTH_RADIUS;
                 s = Math.Round(s * 10000) / 10000;
                 return s;
             }
     
             /// <summary>
             /// 计算两个经纬度之间的直接距离(google 算法)
             /// </summary>
             public static double GetDistanceGoogle(Degree Degree1, Degree Degree2)
             {
                 double radLat1 = radians(Degree1.X);
                 double radLng1 = radians(Degree1.Y);
                 double radLat2 = radians(Degree2.X);
                 double radLng2 = radians(Degree2.Y);
     
                 double s = Math.Acos(Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Cos(radLng1 - radLng2) + Math.Sin(radLat1) * Math.Sin(radLat2));
                 s = s * EARTH_RADIUS;
                 s = Math.Round(s * 10000) / 10000;
                 return s;
             }
     
             /// <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);//一定转换成角度数  原PHP文章这个地方说的不清楚根本不正确 后来lz又查了很多资料终于搞定了
     
                 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
                 };
     
             }
         }
    
            //调用方法
            static void Main(string[] args)
            {
                double a = CoordDispose.GetDistance(new Degree(116.412007, 39.947545), new Degree(116.412924, 39.947918));//116.416984,39.944959
                double b = CoordDispose.GetDistanceGoogle(new Degree(116.412007, 39.947545), new Degree(116.412924, 39.947918));
                Degree[] dd = CoordDispose.GetDegreeCoordinates(new Degree(116.412007, 39.947545), 102);
                Console.WriteLine(a+" "+b);
                Console.WriteLine(dd[0].X + "," + dd[0].Y );
                Console.WriteLine(dd[3].X + "," + dd[3].Y);
                Console.ReadLine();
            }

    拿到圆的顶点就好办了

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

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

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

    转载:http://www.cxyclub.cn/n/20556/

     

  • 相关阅读:
    Android 3.0 r1 API中文文档(108) —— ExpandableListAdapter
    Android 3.0 r1 API中文文档(113) ——SlidingDrawer
    Android 3.0 r1 API中文文档(105) —— ViewParent
    Android 中文 API (102)—— CursorAdapter
    Android开发者指南(4) —— Application Fundamentals
    Android开发者指南(1) —— Android Debug Bridge(adb)
    Android中文API(115)——AudioFormat
    Android中文API(116)——TableLayout
    Android开发者指南(3) —— Other Tools
    Android中文API (110) —— CursorTreeAdapter
  • 原文地址:https://www.cnblogs.com/pingming/p/4709127.html
Copyright © 2020-2023  润新知