static GeoJsonPolygon <GeoJson2DGeographicCoordinates> BuildLimitBox (DbGetGeoFilterRequest request) { double yShift = (180 / Math.PI) * (request.DistanceLat / EarthRadiusMeters); double xShift = (180 / Math.PI) * (request.DistanceLong / EarthRadiusMeters) / Math.Cos(request.CenterLat); var polygon = new GeoJsonPolygon <_2DCoord>( new GeoJsonPolygonCoordinates <_2DCoord>( new GeoJsonLinearRingCoordinates <_2DCoord>( new List <_2DCoord> { new _2DCoord(request.CenterLong - xShift, request.CenterLat - yShift), new _2DCoord(request.CenterLong + xShift, request.CenterLat - yShift), new _2DCoord(request.CenterLong + xShift, request.CenterLat + yShift), new _2DCoord(request.CenterLong - xShift, request.CenterLat + yShift), new _2DCoord(request.CenterLong - xShift, request.CenterLat - yShift), }))); return(polygon); }
public async Task <ListResponse <Geo> > Handle (DbGetGeoFilterRequest request, CancellationToken cancellationToken) { try { Logger.LogInformation(LogEvent.DatabaseRequest, "Request={Request}.", request.ToDictionary()); var validation = new DbGetGeoFilterRequestValidator() .Validate(request); if (!validation.IsValid) { Logger.LogWarning (LogEvent.DatabaseRequestArgumentError, "Database request validation" + " error. Error={Error}.", validation.Errors); return(ErrorResult("Database request validation error")); } var db = DbContext.Db; var query = BuildQuery(request); var totalCount = await query .CountAsync() .ConfigureAwait(false); if (totalCount == 0) { return(new ListResponse <Geo>(new List <Geo>(), totalCount)); } var pagedQuery = AddPagination(query, request); var dbEntityList = await pagedQuery .ToListAsync() .ConfigureAwait(false); if (dbEntityList is null) { Logger.LogWarning (LogEvent.DatabaseEmptyResponse, "Database Geo null response."); return(ErrorResult("Database Geo null response.")); } var entities = dbEntityList.Select(x => x.ToEntity <Geo>()); var result = new ListResponse <Geo>(entities, totalCount); return(result); } catch (Exception e) { Logger.LogWarning(LogEvent.DatabaseExceptionError, e, "Database exception error. Error={Error}.", e.Message); return(ErrorResult("Database exception error")); } }
public static Dictionary <string, object> ToDictionary (this DbGetGeoFilterRequest from) { if (from is null) { return(null); } return(new Dictionary <string, object> { { nameof(from.Archived), from.Archived }, { nameof(from.Contains), from.Contains }, { nameof(from.Limit), from.Limit }, { nameof(from.Offset), from.Offset }, { nameof(from.DistanceLat), from.DistanceLat }, { nameof(from.DistanceLong), from.DistanceLong }, { nameof(from.CenterLat), from.CenterLat }, { nameof(from.CenterLong), from.CenterLong }, { nameof(from.ProjectId), from.ProjectId }, }); }
private IMongoQueryable <DbGeo> BuildQuery ( DbGetGeoFilterRequest request ) { var query = DbContext.Db.GetCollection <DbGeo> (Defaults.GeoCollectionName) .AsQueryable(); if (!string.IsNullOrWhiteSpace(request.Contains)) { query = query.WhereText(request.Contains); } if (request.Archived.HasValue) { query = query.Where(x => x.IsArchived == request.Archived); } if (!string.IsNullOrWhiteSpace(request.ProjectId)) { query = query.Where(x => x.ProjectId == request.ProjectId); } // Add geospatial filter if (request.DistanceLat > 0 && request.DistanceLong > 0) { var polygon = BuildLimitBox(request); var filterBuilder = Builders <DbGeo> .Filter; var filter = filterBuilder .GeoIntersects <GeoJson2DGeographicCoordinates> ((FieldDefinition <DbGeo>) "GeoJson.features.geometry", polygon); query = query.Where(x => filter.Inject()); } return(query);