Example #1
0
        private async Task <IEnumerable <Location> > GetLocationsByCoordinates(double latitude, double longitude, double?radiusInKm, string iso3Code)
        {
            string geohash                    = null;
            var    locationsCount             = 0;
            IEnumerable <Location> locations  = null;
            const int locationsLimit          = 20;
            var       shouldSearchIteratively = !radiusInKm.HasValue;

            radiusInKm = radiusInKm ?? 8;

            //Try to get locations in radius if there are not locations in this radius,
            //increase it and try again until you find location or the radius exceeds the maximum allowed
            do
            {
                var geohashLevel = DistanceHelper.GetGeohashLevelByRadius(radiusInKm.Value);
                geohash = _geohasher.Encode(latitude, longitude, precision: geohashLevel);

                locations = await _locationRepository.GetLocationsByFilterAsync(geohash, iso3Code);

                if (locations.Any())
                {
                    var locationDistances = new Dictionary <Guid, double>();
                    foreach (var location in locations)
                    {
                        var distance = DistanceHelper.GetDistanceInKmBetweenTwoPoints(
                            latitude, longitude, location.Latitude.Value,
                            location.Longitude.Value);

                        if (distance <= radiusInKm.Value)
                        {
                            locationDistances.Add(location.Id, distance);
                        }
                    }

                    //Additional precise filtering
                    locations = locations
                                .Where(l => locationDistances.ContainsKey(l.Id))
                                .OrderBy(l => locationDistances[l.Id]);
                }

                locationsCount = locations.Count();
                radiusInKm    *= 2;
            } while (shouldSearchIteratively && radiusInKm.Value <= MaxRadiusInKm && locationsCount < locationsLimit);

            return(locations);
        }
Example #2
0
        public async Task <Guid[]> GetPartnerIdsInRadiusByCoordinatesAsync(double radiusInKm, double longitude, double latitude)
        {
            if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180)
            {
                throw new ArgumentException("Invalid argument value for get near partners request");
            }

            var geohashLevel = DistanceHelper.GetGeohashLevelByRadius(radiusInKm);
            var geohash      = _geohasher.Encode(latitude, longitude, precision: geohashLevel);
            var locations    = await _locationRepository.GetLocationsByGeohashAsync(geohash);

            var result = locations
                         .Where(l => DistanceHelper.GetDistanceInKmBetweenTwoPoints(latitude, longitude, l.Latitude.Value,
                                                                                    l.Longitude.Value) <= radiusInKm)
                         .Select(l => l.PartnerId)
                         .Distinct()
                         .ToArray();

            return(result);
        }