Ejemplo n.º 1
0
        /// <summary>
        /// 附近的人,最多返回100个
        /// </summary>
        /// <param name="lat">维度</param>
        /// <param name="lng">经度</param>
        /// <param name="radius">半径,单位为米,当radius为零时表示使用默认初始范围,并自动扩大范围, 每次扩大20km,最大到500km</param>
        private IEnumerable <GeoRadiusResult> NearbyUsers(double lat, double lng, double radius, ref PageViewModel page,
                                                          Func <int[], int[]> filterUser = null, string key = RedisConfigureDbModel.GEODbModel)
        {
            var       needExt = radius == 0; //是否需要自动扩展
            Stopwatch watch   = new Stopwatch();

            watch.Start();
            var extStep = 100000;
            var extMax  = 20000000;

            if (radius == 0)
            {
                radius = extStep;
            }
            page = page ?? PageViewModel.Default();

            var       db  = getRedis().GetDatabase((int)RedisDbIndex.GEO);
            var       pos = new GeoPosition(lng, lat);
            GeoRadius geoRadius;
            List <GeoRadiusResult> finalResult = new List <GeoRadiusResult>();

            var extTimes = 0;
            var preCount = 0;//记录上次查询到的数量,, 再过滤时跳过

            while (extTimes == 0 || (needExt && !page.CurrentPageIsFull && radius < extMax))
            {
                geoRadius = new GeoRadius(
                    key,
                    pos, radius, 20000000,
                    GeoUnit.Meters,
                    DTO.GeoRadiusOptions.WithCoordinates | DTO.GeoRadiusOptions.WithDistance
                    );
                var result = db.GeoRadius(key, geoRadius.GeoPosition.Longitude, geoRadius.GeoPosition.Latitude, radius);
                if (result.Count() > preCount) //有新id拿到才需要过滤
                {
                    var newResult  = result.Skip(preCount).ToArray();
                    var newUserIds = newResult.Select(e => Int32.Parse(e.Member)).ToArray();
                    //找出新查询到的UserId,
                    if (filterUser != null)//Remove excluded
                    {
                        newUserIds = filterUser(newUserIds).ToArray();
                    }
                    finalResult.AddRange(newResult.Where(e => newUserIds.Contains(Int32.Parse(e.Member))));
                }
                preCount = result.Count();
                extTimes++;
                radius          += extStep;
                page.RecordCount = finalResult.Count();
            }
            //处理最后页一条正好满的情况. 再增加一页
            if (page.CurrentPageIsFull && page.PageNo == page.PageCount)
            {
                page.RecordCount += 1;
            }
            watch.Stop();
            return(finalResult.Skip(page.Skip).Take(page.PageSize));
        }