0

Are there any gems/ways that would allow me to retrieve a city, state, and postal code from a street address? For example:

results = Search.find("100 Rue de la Paix")
results.each do |address|
  address.city        => "Timbuktu"
  address.state       => "Timbuktu Region"
  address.country     => "Mali"
  address.post_code   => "123456"
end

Preferably something that uses Google Maps.

user2630970
  • 153
  • 2
  • 11
  • I don't think so. Address matching works only probablistically, which means that it does not always give you a single clear matching result. At, best, any such system (if existed) may be able to return an array of possibilities. There is no way you can get a single output on which various attributes are defined. – sawa Jul 29 '13 at 16:00
  • I know this is quite often paid libraries for doing this. Have a look at the Google Map API. If you search for free alternatives they are often implemented per region/country not worldwide. OpenStreetMap seems to do this: http://wiki.openstreetmap.org/wiki/Nominatim – glautrou Jul 29 '13 at 16:01
  • 1
    @sawa I would be happy with something that returns an array! – user2630970 Jul 29 '13 at 16:03
  • @glautrou I looked at Google Maps, but didn't see a way to do this. – user2630970 Jul 29 '13 at 16:03
  • All APIs should return you an array. In your example your address will returns thousands of records in France (and you are targeting Mali). Google Maps do it, but there are a lot of limitations and is expensive. – glautrou Jul 29 '13 at 16:06

4 Answers4

4

The ruby geocoder gem does exactly that:

require 'geocoder'
Geocoder.search('100 Rue de la Paix')
=> # Array of results

This searches for the address and displays results.

ichigolas
  • 7,595
  • 27
  • 50
0

You could try SmartyStreets' autocomplete API. I work at SmartyStreets and helped to write it. You can try it on the homepage. I see you have addresses outside the USA, and SmartyStreets autocomplete is currently US-only, but maybe it'll still be helpful. However, SmartyStreets does offer other services such as verification for international addresses.

Technically it accepts a "prefix" (can be just a street address) and will suggest up to 10 city/state combinations. From there, you would proceed to verify the validity of the address using LiveAddress API to fill out the ZIP code and such.

None of the other answers yet given actually do this, and all of them will actually return invalid results, so always make sure to verify it before you're done. Just note that only a handful of countries actually have data to validate a street address at the delivery point level (like a house, or business), some do street, most do at least city/region granularity.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Matt
  • 22,721
  • 17
  • 71
  • 112
-1

Try OpenStreetMap:

Requests:

Results:

 <searchresults timestamp="Sat, 07 Nov 09 14:42:10 +0000" querystring="135 pilkington, avenue birmingham" polygon="true">
   <place 
     place_id="1620612" osm_type="node" osm_id="452010817" 
     boundingbox="52.548641204834,52.5488433837891,-1.81612110137939,-1.81592094898224" 
     polygonpoints="[['-1.81592098644987','52.5487429714954'],['-1.81592290792183','52.5487234624632'],...]" 
     lat="52.5487429714954" lon="-1.81602098644987" 
     display_name="135, Pilkington Avenue, Wylde Green, City of Birmingham, West Midlands (county), B72, United Kingdom" 
     class="place" type="house">
     <house>135</house>
     <road>Pilkington Avenue</road>
     <village>Wylde Green</village>
     <town>Sutton Coldfield</town>
     <city>City of Birmingham</city>
     <county>West Midlands (county)</county>
     <postcode>B72</postcode>
     <country>United Kingdom</country>
     <country_code>gb</country_code>
   </place>
 </searchresults>
glautrou
  • 3,140
  • 2
  • 29
  • 34
-1

If you can use javascript:

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
    function codeAddress(address) {
        var geocoder = new google.maps.Geocoder();
        geocoder.geocode({ 'address': address }, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {

                city = results[0].address_components[2].long_name;
                state = results[0].address_components[4].long_name;
                country = results[0].address_components[5].long_name;
                postalCode = results[0].address_components[6].long_name;

                // Example...
                alert(city);

            }
        });
    }

    var address = "100 Rue de la Paix";
    codeAddress(address);
</script>

If you need any more information about the location, you can refer to this document: https://developers.google.com/maps/documentation/geocoding/#GeocodingResponses

Also, if you're using the Google Maps API, you must display a map (Google) somewhere on the page according to their terms of service.

Brent Barbata
  • 3,631
  • 3
  • 24
  • 23
  • I am creating a form in HTML and this is a great idea! Thanks! +1 – ReinstateMonica3167040 Aug 19 '17 at 13:47
  • This assumes that the "city" will be in the 2nd address component, which isn't always the case. Wouldn't it be better if you showed how to parse the actual city from the address_components? – Mathew Kleppin May 03 '18 at 21:53
  • @MathewKleppin What is a "city"? – Brent Barbata May 04 '18 at 00:27
  • @MathewKleppin maybe you're looking for something like this: results.map((result) => result.address_components.filter((component) => component.types.indexOf('locality') !== -1)). Then pick. That should get you pointed in the right direction, but feel free to create a new question if you're confused. – Brent Barbata May 04 '18 at 00:50
  • @BrentBarbata Well the point i was trying to address was that the location of each of these components, "city" for example, is nondeterministic in its location within the array. – Mathew Kleppin May 04 '18 at 17:05
  • @MathewKleppin hence the link to the docs. In any case, hopefully the code in my above comment gets you pointed in the right direction. Depending on the application, you'll probably want to apply an Array.reduce() to flatten the result. Good luck with your project and best of luck coming up with a non-arbitrary way to determine city from political or locality tags, especially when there are often multiple, or none. – Brent Barbata May 04 '18 at 20:00