using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using StackExchange.Redis; using WIDESEAWCS_RedisService.Connection; using WIDESEAWCS_RedisService.Options; namespace WIDESEAWCS_RedisService.Geo { public class RedisGeoLocationService : IGeoLocationService { private readonly IRedisConnectionManager _connectionManager; private readonly RedisOptions _options; private readonly ILogger _logger; public RedisGeoLocationService( IRedisConnectionManager connectionManager, IOptions options, ILogger logger) { _connectionManager = connectionManager; _options = options.Value; _logger = logger; } private string BuildKey(string key) => $"{_options.KeyPrefix}geo:{key}"; public bool Add(string key, double longitude, double latitude, string member) { return _connectionManager.GetDatabase().GeoAdd(BuildKey(key), longitude, latitude, member); } public GeoPosition? GetPosition(string key, string member) { var pos = _connectionManager.GetDatabase().GeoPosition(BuildKey(key), member); if (pos == null) return null; return new GeoPosition { Longitude = pos.Value.Longitude, Latitude = pos.Value.Latitude }; } public double? GetDistance(string key, string member1, string member2) { return _connectionManager.GetDatabase().GeoDistance(BuildKey(key), member1, member2, GeoUnit.Meters); } public List SearchRadius(string key, double longitude, double latitude, double radiusMeters, int count = 10) { var results = _connectionManager.GetDatabase() .GeoRadius(BuildKey(key), longitude, latitude, radiusMeters, GeoUnit.Meters, count, Order.Ascending, GeoRadiusOptions.WithDistance | GeoRadiusOptions.WithCoordinates); return results.Select(r => new GeoRadiusResult { Member = r.Member.ToString(), Distance = r.Distance, Position = r.Position.HasValue ? new GeoPosition { Longitude = r.Position.Value.Longitude, Latitude = r.Position.Value.Latitude } : null }).ToList(); } public bool Remove(string key, string member) { return _connectionManager.GetDatabase().SortedSetRemove(BuildKey(key), member); } } }