Use GPS latitude and longitude to locate a nearby location within a certain point of of

  • 2020-05-30 20:58:57
  • OfStack

The database records the latitude and longitude of merchants on baidu (e.g. : 116.412007, 39.947545).

The original idea, with the center point as the center point, to do a cycle of radius, radius every increase 1 pixel (temporary 1 meter) to do a cycle of the circumference, to the database query corresponding to the point of the merchant (is really a long cycle work), the Internet baidu similar articles have a point

The general idea is that given a center point, a radius, you want to find all the points in the circle that are contained in the parabola of the circle, so you need to know the vertices of the diagonals of the circle that you want to find. The problem is that the latitude and longitude are 1 point, the radius is 1 distance, you can't add or subtract directly


/// <summary>
    ///  Latitude and longitude coordinates 
    /// </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;// Radius of the earth ( m )
        /// <summary>
        ///  Convert the number of degrees to the radian formula 
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        private static double radians(double d)
        {
            return d * Math.PI / 180.0;
        }
        /// <summary>
        ///  Radians into the number of degrees formula 
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        private static double degrees(double d)
        {
            return d * (180 / Math.PI);
        }
        /// <summary>
        ///  Calculate the direct distance between two latitude and longitude 
        /// </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>
        ///  Calculate the direct distance between two latitude and longitude (google  algorithm )
        /// </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>
        ///  In order to 1 The latitude and longitude are calculated at the center 4 vertices 
        /// </summary>
        /// <param name="distance"> The radius of ( m )</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);//1 Constant to the number of angles    The original PHP What the article says in this place is not clear at all correct   Later, lz After a lot of research, we finally got it done 
            double dlat = distance / EARTH_RADIUS;
            dlat = degrees(dlat);//1 Constant to the number of angles 
            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
            };
        }
    }

Test method:


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();
        }

I tried it many times and the error was about 1 meter

You get to the top of the circle

The database would perform better if sql 2008 could index the latitude and longitude fields directly (not tried).

The lz company database is still old in 2005 and that doesn't matter, the key is the latitude and longitude split calculation, which goes without saying that there are many on the web is the last implementation of the sql statement


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


Related articles: