Get City Name from Zip Code google geocoding
Asked Answered
N

4

9

I've found code on this site to get the sate from a zipcode, but I also need to get the city name.

Here is my code for getting the state: (Note I also use jQuery)

var geocoder = new google.maps.Geocoder();

    $('.zip').bind('change focusout', function () {
        var $this = $(this);
        if ($this.val().length == 5) {
            geocoder.geocode({ 'address': $this.val() }, function (result, status) {
                var state = "N/A";
                //start loop to get state from zip
                for (var component in result[0]['address_components']) {
                    for (var i in result[0]['address_components'][component]['types']) {
                        if (result[0]['address_components'][component]['types'][i] == "administrative_area_level_1") {
                            state = result[0]['address_components'][component]['short_name'];
                            // do stuff with the state here!
                            $this.closest('tr').find('select').val(state);
                        }
                    }
                }
            });
        }
    });  
Nickelic answered 26/4, 2012 at 20:7 Comment(1)
Can you share me the other jquery codes for getting the name of the place using zip code.I am also in search for it......Hippo
G
12

Just add result[0]['address_components'][1]['long_name']

So it would be

var geocoder = new google.maps.Geocoder();

$('.zip').bind('change focusout', function () {
    var $this = $(this);
    if ($this.val().length == 5) {
        geocoder.geocode({ 'address': $this.val() }, function (result, status) {
            var state = "N/A";
            var city = "N/A";
            //start loop to get state from zip
            for (var component in result[0]['address_components']) {
                for (var i in result[0]['address_components'][component]['types']) {
                    if (result[0]['address_components'][component]['types'][i] == "administrative_area_level_1") {
                        state = result[0]['address_components'][component]['short_name'];
                        // do stuff with the state here!
                        $this.closest('tr').find('select').val(state);
                        // get city name
                        city = result[0]['address_components'][1]['long_name'];
                        // Insert city name into some input box
                        $this.closest('tr').find('.city').val(city);
                    }
                }
            }
        });
    }
});  
Gamages answered 26/4, 2012 at 20:21 Comment(2)
Be careful using the indexes of the address_components AS THEY ARE NOT CONSISTENT!Inbound
Hello Marco, is it possible to adapt this for France? I need to check if an entered french city (input fields) is correct relative to an entered zip code.Cloche
E
7

I've rewritten above solution to look more elegant:

var zipCode = '48201';
var country = 'United States';               

var geocoder = new google.maps.Geocoder();

geocoder.geocode({ 'address': zipCode + ',' + country }, function (result, status) {

    var stateName = '';
    var cityName = '';

    var addressComponent = result[0]['address_components'];

    // find state data
    var stateQueryable = $.grep(addressComponent, function (x) {
        return $.inArray('administrative_area_level_1', x.types) != -1;
    });

    if (stateQueryable.length) {
        stateName = stateQueryable[0]['long_name'];

        var cityQueryable = $.grep(addressComponent, function (x) {
            return $.inArray('locality', x.types) != -1;
        });

        // find city data
        if (cityQueryable.length) {
            cityName = cityQueryable[0]['long_name'];
        }
    }
});
Eglanteen answered 10/1, 2013 at 12:9 Comment(1)
Looks like there is some issues with google geocode to find cities from zip code. For instance asking for "59650, France" returns Wattrelos instead of Villeneuve d'Ascq. Same for (a few) other cities tested in France and Germany. don't know why, don't know how to fix it.Sussna
T
6

Below is code to check City name from Zipcode using googleapis.

<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Geocoding service</title>    
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>      
<script>    
        var geocoder;
        var map;        
        function codeAddress() {
            geocoder = new google.maps.Geocoder();
            var address = document.getElementById('address').value;
            geocoder.geocode({ 'address': address }, function (results, status) {
                if (status == google.maps.GeocoderStatus.OK) {                       

                    for (var component in results[0]['address_components']) {
                        for (var i in results[0]['address_components'][component]['types']) {
                            if (results[0]['address_components'][component]['types'][i] == "administrative_area_level_1") {
                                state = results[0]['address_components'][component]['long_name'];
                                alert(results[0]['address_components'][1]['long_name'] + ' , '  + state);
                            }
                        }
                    }                                           
                } else {
                    alert('Invalid Zipcode');
                }
            });
        }         

    </script>
  </head>
  <body>
    <div id="panel">
      <input id="address" type="textbox" value="Sydney, NSW">
      <input type="button" value="Geocode" onclick="codeAddress()">
    </div>
    <div id="map-canvas"></div>
  </body>
</html>
Tellurate answered 18/11, 2014 at 6:6 Comment(1)
you have't used jquery like op asked, this is exactly what i wanted +1Charlean
A
-2

This TypeScript will return JSON result such as:

{ 
  country : { long_name : "someString", short_name : "someStrong" },
  city : { long_name : "someString", short_name : "someString" },
  state : { long_name : "someString", short_name : "someString" }
}

and can be called using the code : let test = new ZipCodeDeconstructor().deconstruct('20009');

let rp = require('request-promise');
enum IGoogleMapResultType {
  COUNTRY = <any>'country',
  LOCALITY = <any>'locality',
  SUBLOCALITY_LEVEL_1 = <any>'sublocality_level_1',
  ADMINISTRATIVE_AREA_LEVEL_1 = <any>'administrative_area_level_1',
    // These may be used later, don't delete them, they're for reference
  POSTAL_CODE = <any>'postal_code',
  NEIGHBORHOOD = <any>'neighborhood',
  POLITICAL = <any>'political',
  ADMINISTRATIVE_AREA_LEVEL_2 = <any>'administrative_area_level_2',
  ADMINISTRATIVE_AREA_LEVEL_3 = <any>'administrative_area_level_3'
}
interface IGoogleMapResult {
  address_components : {
    long_name? : string
    short_name? : string
    types : IGoogleMapResultType[]
  }[],
  formatted_address : string,
  geometry: any,
  place_id: string,
  types: IGoogleMapResultType[]
}
type IGoogleMapResults = any[];
type ZipCodeDeconstructorProperty = {
  long_name: string,
  short_name: string
}
// What we return from this component
export type ZipCodeDeconstructorResponse = {
  city: ZipCodeDeconstructorProperty,
  state: ZipCodeDeconstructorProperty,
  country: ZipCodeDeconstructorProperty
}
export class ZipCodeDeconstructor {
  static apiUrl = "http://maps.googleapis.com/maps/api/geocode/json?address=";
  constructor() {}
  // main entry point, deconstruct a 5 digit zip into city, state, zip into the corresponding properties
  async deconstruct(zip):Promise<ZipCodeDeconstructorResponse> {
    let response:any = await this._makeCall(zip);
    let firstResult = response.results[0];
    let returnObject = {
      city :  this._extractCity(firstResult),
      state : this._extractState(firstResult),
      country : this._extractCountry(firstResult)
    };
    console.log("[Zip Code Deconstructor] returning: ", returnObject);
    return returnObject;
  }
  private _createZipcodeUrl(zip) {
    return ZipCodeDeconstructor.apiUrl + zip + '&sensor=true';
  }
  private async _makeCall(zip) {
    return await rp({uri : this._createZipcodeUrl(zip), json : true });
  }
  private _extractOfTypeFromResult(typesArray:IGoogleMapResultType[], result:IGoogleMapResult) {
    for(let i = 0; i < result.address_components.length; i++) {
      let addressComponentAtIndex = result.address_components[i];
      let type:IGoogleMapResultType = addressComponentAtIndex.types[0];
      if(typesArray.indexOf(type) !== -1) {
        return {
          long_name : addressComponentAtIndex.long_name,
          short_name : addressComponentAtIndex.short_name
        }
      }
    }
  }
  private _extractCity(result:IGoogleMapResult) {
    return this._extractOfTypeFromResult([IGoogleMapResultType.SUBLOCALITY_LEVEL_1, 
      IGoogleMapResultType.LOCALITY], result)
  }
  private _extractState(result:IGoogleMapResult) {
    return this._extractOfTypeFromResult([IGoogleMapResultType.ADMINISTRATIVE_AREA_LEVEL_1], result);
  }
  private _extractCountry(result:IGoogleMapResult) {
    return this._extractOfTypeFromResult([IGoogleMapResultType.COUNTRY], result);
  }
}
// let test = new ZipCodeDeconstructor().deconstruct('20009');

The interfaces at the top should help you along the way of understanding what gets returned and what should be passed in.

Aleut answered 18/5, 2017 at 8:52 Comment(1)
You are very kind for sharing. However, you have VERY helpfully illustrated and helped me put to words WHY I have such a gut-negative reaction to Typescript (5 years after you posted LOL) - it's so frickin wordy! It reads like Java did in the 2000's, and maybe that's just poor code formatting, not sure, but still - it's just so difficult to read and grok and work with, I'll pass. But, that's my rant against TS, not you - thank you for sharing your code!Christenachristendom

© 2022 - 2024 — McMap. All rights reserved.