Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easiest way to get Zip Code from City Name [closed]

I wanted to mess around with an assignment of mine and search for weather by city name rather than by zip code(how i have it set up now). What would be the easiest way to use a city name input string and get a zip code out of it? Help is much appreciated! Thanks!

like image 911
Troy Loberger Avatar asked Dec 05 '22 17:12

Troy Loberger


2 Answers

Google can help you out here!

https://developers.google.com/maps/documentation/geocoding/

The zip is actually called "postal_code" by Google.

  "long_name": "94043",
  "short_name": "94043",
  "types": postal_code

For example, let's say you want to get the zip for Clarkston, MI...

http://maps.googleapis.com/maps/api/geocode/json?address=Clarkston+MI&sensor=true

This returns:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Clarkston",
               "short_name" : "Clarkston",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Oakland",
               "short_name" : "Oakland",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Michigan",
               "short_name" : "MI",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "48346",
               "short_name" : "48346",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "Clarkston, MI 48346, USA",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 42.7418310,
                  "lng" : -83.41402409999999
               },
               "southwest" : {
                  "lat" : 42.7252370,
                  "lng" : -83.42880730000002
               }
            },
            "location" : {
               "lat" : 42.73511960,
               "lng" : -83.41929410
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 42.74331460,
                  "lng" : -83.40328670
               },
               "southwest" : {
                  "lat" : 42.72692350,
                  "lng" : -83.43530149999999
               }
            }
         },
         "types" : [ "locality", "political" ]
      }
   ],
   "status" : "OK"
}

EDIT

If you're not receiving a postal code with that first call, you'll have to make a second call to the same web service using the coordinates from the first call. Still very simple - the call for Stevens Point, WI would be as follows:

http://maps.googleapis.com/maps/api/geocode/json?latlng=44.52357920000001,-89.5745630&sensor=true

You can grab the lat/lng values from "location". Hope this helps!

like image 125
Alec Sanger Avatar answered Dec 29 '22 00:12

Alec Sanger


The most popular answer above is incomplete. Please check my more up-to date answer below, where I describe my personal proven method to get the most accurate results from Google Maps API. Tested on a website with over 100 million unique locations.

There are many postcodes in each city.

I've had an issue like this one before when I had to generate over 1 million combinations of links for sitemaps with mixed locations + keywords.

At first, I have tried adding keywords "center", "central" & "centre" to the city name as well as the country and it worked 80% of the time, which was not good enough due to the volume I've had to accomplish.

So I kept digging for a better solution and eventually, I have found 2 NEW parameters for Google Maps Geocode API, simply by copy/pasting parts of the results in the query URL.

Please note: This is not documented by Google and whilst it is working just now, it might not work in the future.

1st Parameter:

&components=country:UK // where "UK" is a country of choice, by utilising this method, rather than adding the Country to the City name, you will avoid clashes and reduce the risk of not getting the postcode.

2nd Parameter:

&location_type=GEOMETRIC_CENTER& // as is, this will get you a place closest to the central geometrical location of the town/city. 

Full Example:

var city_name = 'Edinburgh'; // City/Town/Place Name
var country_code = 'GB'; // Great Britain 
var key = 'AIzaSyBk********************cM' // Google API Key

var query = https://maps.googleapis.com/maps/api/geocode/json?address='+city_name+'&components=country:'+country_code+'&location_type=GEOMETRIC_CENTER&key='+key+'&sensor=false

Also when looping through JSON sometimes POSTCODE is not in the 1st hierarchy of results, so be sure to loop through the 2nd row, if the 1st one is missing the POSTCODE.

Here is a looping example through the array:

url = geocode_query;

fetch(url)
.then(res => res.json())
.then((out) => {
   result = JSON.parse(out);
   postcode = get_postcode(result); // HERE is Your Postcode do what you need with it
})
.catch(err => { throw err });

function get_postcode(results){ 

    city_data = results['results'][0]['address_components'];
    for(i=0;i<city_data.length;i++){
        var cv = city_data[i];
        if(typeof cv['types'][0] != 'undefined')){
            if(cv['types'][0] === 'postal_code'){
                city['postcode'] = cv['long_name'];
            }else if(cv['types'][0] === 'postal_town'){
                city['place_name'] = cv['postal_town'];
            }
        }
    }

    if(typeof city == 'undefined'){
        city_data = results['results'][1]['address_components'];
        for(i=0;i<city_data.length;i++){
            var cv = city_data[i];
            if(typeof cv['types'][0] != 'undefined')){
                if(cv['types'][0] === 'postal_code'){
                    city['postcode'] = cv['long_name'];
                }
            }
        }
    }

    return city;

}

Enjoy!

like image 24
SergeDirect Avatar answered Dec 29 '22 02:12

SergeDirect