public async Task <Candidate> Handle(Command request, CancellationToken cancellationToken)
            {
                _log.Verbose("Testing for delivery points");

                if (!request.Address.Zip5.HasValue)
                {
                    _log.Debug("No delivery point for {address} because of no zip5", request.Address);

                    return(null);
                }

                _driveCache.UspsDeliveryPoints.TryGetValue(request.Address.Zip5.Value.ToString(), out var items);

                if (items == null || !items.Any())
                {
                    _log.Debug("No delivery point for {zip} in cache", request.Address.Zip5.Value);

                    return(null);
                }

                if (!(items.FirstOrDefault() is UspsDeliveryPointLink deliveryPoint))
                {
                    return(null);
                }

                var result = new Candidate {
                    Address     = deliveryPoint.MatchAddress,
                    AddressGrid = deliveryPoint.Grid,
                    Locator     = "USPS Delivery Points",
                    Score       = 100,
                    Location    = new Point(deliveryPoint.X, deliveryPoint.Y)
                };

                _log.Information("Found delivery point for {address}", request.Address);

                if (request.Options.SpatialReference == 26912)
                {
                    return(result);
                }

                _log.Debug("Reprojecting delivery point to {wkid}", request.Options.SpatialReference);

                var reproject =
                    new Reproject.Command(new PointReprojectOptions(26912, request.Options.SpatialReference,
                                                                    new[] {
                    deliveryPoint.X,
                    deliveryPoint.Y
                }));

                var pointReprojectResponse = await _mediator.Send(reproject, cancellationToken);

                if (!pointReprojectResponse.IsSuccessful || !pointReprojectResponse.Geometries.Any())
                {
                    _log.Fatal("Could not reproject point for {address}", request.Address);

                    return(null);
                }

                var points = pointReprojectResponse.Geometries.FirstOrDefault();

                if (points != null)
                {
                    result.Location = new Point(points.X, points.Y);
                }

                return(result);
            }
        public async Task <ObjectResult> Reverse(double x, double y, [FromQuery] ReverseGeocodingOptions options)
        {
            var inputLocation = new Point(x, y);

            if (options.SpatialReference != 26912)
            {
                var reprojectCommand =
                    new Reproject.Command(new PointReprojectOptions(options.SpatialReference, 26912, new[] { x, y }));
                var pointReprojectResponse = await _mediator.Send(reprojectCommand);

                if (!pointReprojectResponse.IsSuccessful || !pointReprojectResponse.Geometries.Any())
                {
                    _log.Fatal("Could not reproject point for {x},{y} {wkid}", x, y, options);

                    return(new ObjectResult(new ApiResponseContainer {
                        Message = "There was a problem reprojecting your input location",
                        Status = (int)HttpStatusCode.InternalServerError
                    })
                    {
                        StatusCode = (int)HttpStatusCode.InternalServerError
                    });
                }

                var points = pointReprojectResponse.Geometries.FirstOrDefault();

                if (points != null)
                {
                    x = points.X;
                    y = points.Y;
                }
            }

            var locatorLookup = new LocatorsForReverseLookup.Command();
            var locators      = await _mediator.Send(locatorLookup);

            if (locators == null || !locators.Any())
            {
                _log.Debug("No locators found for address reversal");

                return(NotFound(new ApiResponseContainer {
                    Message = $"No address candidates found within {options.Distance} meters of {x}, {y}.",
                    Status = (int)HttpStatusCode.NotFound
                }));
            }

            // there's only one
            var locator = locators.First();

            locator.Url = string.Format(locator.Url, x, y, options.Distance, options.SpatialReference);

            var reverseGeocodeCommand = new ReverseGeocode.Command(locator);

            try {
                var response = await _mediator.Send(reverseGeocodeCommand);

                if (response == null)
                {
                    return(NotFound(new ApiResponseContainer {
                        Message = $"No address candidates found within {options.Distance} meters of {x}, {y}.",
                        Status = (int)HttpStatusCode.NotFound
                    }));
                }

                var result = response.ToResponseObject(inputLocation);

                return(Ok(new ApiResponseContainer <ReverseGeocodeApiResponse> {
                    Result = result,
                    Status = (int)HttpStatusCode.OK
                }));
            } catch (Exception ex) {
                _log.Fatal(ex, "Error reverse geocoding {locator}", locator.Url);

                return(new ObjectResult(new ApiResponseContainer {
                    Message = "There was a problem handling your request",
                    Status = (int)HttpStatusCode.InternalServerError
                })
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError
                });
            }
        }
Ejemplo n.º 3
0
            public async Task <Candidate> Handle(Command request, CancellationToken cancellationToken)
            {
                if (!request.Address.Zip5.HasValue)
                {
                    _log.Debug("No zip code, can't be po box {address}", request.Address);

                    return(null);
                }

                if (_poBoxes is null)
                {
                    _log.Warning("Po Box cache is empty!");

                    return(null);
                }

                if (!_poBoxes.ContainsKey(request.Address.Zip5.Value))
                {
                    _log.Debug("{zip} is not in the po box cache", request.Address.Zip5.Value);

                    return(null);
                }

                Candidate candidate;
                var       key = request.Address.Zip5.Value * 10000 + request.Address.PoBox;

                if (_zipExclusions.Any(x => x == request.Address.Zip5) &&
                    _exclusions.ContainsKey(key))
                {
                    _log.Information("{Using Post Office Point Exclusion for {zip}", key);

                    var exclusion = _exclusions[key];
                    candidate = new Candidate {
                        Address     = request.Address.StandardizedAddress,
                        Locator     = "Post Office Point Exclusions",
                        Score       = 100,
                        Location    = new Point(exclusion.X, exclusion.Y),
                        AddressGrid = request.Address?.AddressGrids?.FirstOrDefault()?.Grid
                    };
                }
                else if (_poBoxes.ContainsKey(request.Address.Zip5.Value))
                {
                    _log.Information("Using post office point for {zip}", key);

                    var result = _poBoxes[request.Address.Zip5.Value];
                    candidate = new Candidate {
                        Address     = request.Address.StandardizedAddress,
                        Locator     = "Post Office Point",
                        Score       = 100,
                        Location    = new Point(result.X, result.Y),
                        AddressGrid = request.Address.AddressGrids.FirstOrDefault()?.Grid
                    };
                }
                else
                {
                    return(null);
                }

                if (request.Options.SpatialReference == 26912)
                {
                    return(candidate);
                }

                var reprojectCommand =
                    new Reproject.Command(new PointReprojectOptions(26912, request.Options.SpatialReference,
                                                                    new[] {
                    candidate.Location.X,
                    candidate.Location.Y
                }));

                var pointReprojectResponse = await _mediator.Send(reprojectCommand, cancellationToken);

                if (!pointReprojectResponse.IsSuccessful || !pointReprojectResponse.Geometries.Any())
                {
                    _log.Fatal("Could not reproject point for {candidate}", candidate);

                    return(null);
                }

                var points = pointReprojectResponse.Geometries.FirstOrDefault();

                if (points != null)
                {
                    candidate.Location = new Point(points.X, points.Y);
                }

                return(candidate);
            }