a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C# > 正文

使用GPS經緯度定位附近地點(某一點范圍內查詢)

2020-01-24 02:57:36
字體:
來源:轉載
供稿:網友

數據庫中記錄了商家在百度標注的經緯度(如:116.412007, 39.947545)

最初想法,以圓心點為中心點,對半徑做循環,半徑每增加一個像素(暫定1米)再對周長做循環,到數據庫中查詢對應點的商家(真是一個長時間的循環工作),上網百度類似的文章有了點眉目

大致想法是已知一個中心點,一個半徑,求圓包含于圓拋物線里所有的點,這樣的話就需要知道所要求的這個圓的對角線的頂點,問題來了 經緯度是一個點,半徑是一個距離,不能直接加減

復制代碼 代碼如下:

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

試了很多次 誤差在1米左右

拿到圓的頂點就好辦了

數據庫要是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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧美日韩不卡在线 | 在线碰 | 亚洲成av人片一区二区三区 | 亚洲精品午夜国产va久久成人 | 精品国产欧美一区二区 | 精品在线视频免费观看 | 欧美一区二区三区在线 | 日本一区二区精品视频 | 欧美精品二区 | 久久视频在线 | 3bmm在线观看视频免费 | 欧美性猛交xxxx免费看漫画 | 欧美精品在线一区 | 亚洲自拍一区在线 | 欧美电影一区二区三区 | 欧美成人第一页 | 欧美激情综合五月色丁香小说 | 色综合久久伊人 | 在线免费观看色视频 | 在线免费视频一区 | 亚洲高清视频一区二区 | 日本久久网 | 成人免费淫片aa视频免费 | 欧美激情一区二区三级高清视频 | 欧美日韩在线第一页 | 色伊人 | 亚洲一区中文 | 性色视频在线观看 | 日韩欧美在线看 | 国产一级毛片电影 | 九九av| 不卡一区 | 久久一二| 成人午夜视频在线观看 | 欧美日韩国产精品成人 | 国产一级大片 | 中文字幕第一页在线视频 | 亚洲jizzjizz日本少妇 | 羞羞视频网页 | 国产一二区在线观看 | 日韩成人tv |