Domanda

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);
                        }
                    }
                }
            });
        }
    });  
È stato utile?

Soluzione

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);
                    }
                }
            }
        });
    }
});  

Altri suggerimenti

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'];
        }
    }
});

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>

I'm generous enough to provide the exact module I rolled to do this for us. It returns an object 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');

This is written in TypeScript (get on that train) and used in node.js (you should already be on that train.

If you don't have request-promise yet, run npm i request-promise --save and be sure your TypeScript configuration allows for the async/await keywords to be used.

This is basically using everything "new" as of the time this has been written, so it should be quite useful for some time to come.

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top