Пример #1
0
            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);
            }
Пример #2
0
        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"));
            }
        }
Пример #3
0
        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 },
            });
        }
Пример #4
0
        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);