chadly / Geocoding.net

C# GeoCoding / Address Validation API
MIT License
444 stars 156 forks source link

Implement a geocoder for US Census Bureau #116

Open DR9885 opened 5 years ago

DR9885 commented 5 years ago

There is a free api found here: https://geocoding.geo.census.gov/

DR9885 commented 5 years ago

possible example:

    public class UsCensusBureauGeocoder : IGeocoder
    {
        private readonly int _benchmark;
        private readonly HttpClient _client;

        private class UsCensusBureauAddress : Address
        {
            private const string Key = "UsCensusBureau";

            public UsCensusBureauAddress(string formattedAddress, Location coordinates) 
                : base(formattedAddress, coordinates, Key)
            {

            }
        }

        public UsCensusBureauGeocoder(int benchmark = 9)
        {
            _benchmark = benchmark;
            _client = new HttpClient { BaseAddress = new Uri("https://geocoding.geo.census.gov/geocoder/") };
        }

        public async Task<IEnumerable<Address>> GeocodeAsync(string address)
        {
            // Build Query String
            var queryString = HttpUtility.ParseQueryString(string.Empty);
            queryString["address"] = address;
            queryString["benchmark"] = "4";
            queryString["format"] = "json";

            // Get Request
            var response = await _client.GetStringAsync($"locations/onelineaddress?" + queryString);

            // Read Result
            return GetAddresses(response);
        }

        public async  Task<IEnumerable<Address>> GeocodeAsync(string street, string city, string state, string postalCode, string country)
        {
            // Build Query String
            var queryString = HttpUtility.ParseQueryString(string.Empty);
            queryString["street"] = street;
            queryString["city"] = city;
            queryString["state"] = state;
            queryString["zip"] = postalCode;
            queryString["benchmark"] = "4";
            queryString["format"] = "json";

            // Get Request
            var response = await _client.GetStringAsync($"locations/address?" + queryString);

            // Read Result
            return GetAddresses(response);
        }

        public Task<IEnumerable<Address>> ReverseGeocodeAsync(Location location)
        {
            throw new NotImplementedException();
        }

        public Task<IEnumerable<Address>> ReverseGeocodeAsync(double latitude, double longitude)
        {
            throw new NotImplementedException();
        }

        private static IEnumerable<UsCensusBureauAddress> GetAddresses(string response) 
        {
            var result = JObject.Parse(response)["result"];

            return result["addressMatches"]
                .Select(match =>
                {
                    var formatted = match["matchedAddress"].ToString();
                    var coordinates = match["coordinates"];
                    var x = Convert.ToDouble((object) coordinates["x"]);
                    var y = Convert.ToDouble((object) coordinates["y"]);
                    return new UsCensusBureauAddress(formatted, new Location(y, x));
                })
                .ToArray();
        }
    }
DR9885 commented 5 years ago

Opened Pull Request with tests: https://github.com/chadly/Geocoding.net/pull/117

DR9885 commented 5 years ago

when are you guys publishing the new nuget packages? I saw you guys added Here support as well.

DR9885 commented 5 years ago

using a different pull request

118

DR9885 commented 4 years ago

@chadly is there anything were missing or can we pull it back in?