一 基本介绍:

位置服务(LBS)解决的主要问题是当前位置周围某个范围内的人或场所.
在传统的解决方案,开发人员需要根据复杂的几何运算与大量的SQL语句进行查找,这无疑加大的开发人员的开发难度.
现在我们需要更为方便的解决方案,MongoDB为我们完美解决此类LBS问题.

二 帮助文档:

http://docs.mongodb.org/manual/core/2d/

三 代码实现:

  表结构:使用double数组存储经纬度信息,x代表经度,y代表纬度。(指定索引:db.Member.ensureIndex( {Position: "2d"} ))

View Code
public class Member:SMCore.Core.BaseModel
    {
        /// <summary>
        /// 会员名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 位置信息
        /// </summary>
        public double[] Position { get; set; }
    }

  底层驱动:

View Code
/// <summary>
        /// 查询以[经度:x,纬度:y]为中心,半径为maxDistance千米的所有东东
        /// </summary>
        public IQueryable<T> GeoNear<T>(double x, double y, double maxDistance, Expression<Func<T, bool>> predicate)
        {
            //3959为地球半径,单位英里。这里将英里转换成千米
            var radius = maxDistance / (3959 * 1.61);
            var items = db.GetCollection<T>(typeof(T).Name).Find(Query.WithinCircle("Position", x, y, radius, true)).AsQueryable().Where(predicate);
            return items;
        }

  计算两地距离和生成随机Name方法:

View Code
#region 计算经纬度两点距离
        private const double EARTH_RADIUS = 6378.137;//地球半径,单位千米
        private static double rad(double d)
        {
            return d * Math.PI / 180.0;
        }

        public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
        {
            double radLat1 = rad(lat1);
            double radLat2 = rad(lat2);
            double a = radLat1 - radLat2;
            double b = rad(lng1) - rad(lng2);

            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;
        }
        #endregion

        #region 生成随机数
        private static char[] constant =   
          {   
            '0','1','2','3','4','5','6','7','8','9',  
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',   
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'   
          };
        public static string GenerateRandomNumber(int Length)
        {
            System.Text.StringBuilder newRandom = new System.Text.StringBuilder(62);
            Random rd = new Random();
            for (int i = 0; i < Length; i++)
            {
                newRandom.Append(constant[rd.Next(62)]);
            }
            return newRandom.ToString();
        }
        #endregion

  添加数据之后,查看两地距离如图:

  

  调用驱动,查询位置信息就完成了

View Code
 public ActionResult Search(double id)
        {
            var first = db.FirstOrDefault<Models.Member>();
            return View(db.GeoNear<Models.Member>(first.Position[0], first.Position[1], id, x => true).ToList());
        }

  效果如下:

  

  以上是使用MongoDB实现LBS部分代码。只是最简单的实现,欢迎感兴趣的朋友一起讨论。

 

posted on 2013-04-10 10:02  marchmagic  阅读(560)  评论(0)    收藏  举报