get city from geocoder results?

84,678

Solution 1

Got this working in the end using:

var arrAddress = item.address_components;
var itemRoute='';
var itemLocality='';
var itemCountry='';
var itemPc='';
var itemSnumber='';

// iterate through address_component array
$.each(arrAddress, function (i, address_component) {
    console.log('address_component:'+i);

    if (address_component.types[0] == "route"){
        console.log(i+": route:"+address_component.long_name);
        itemRoute = address_component.long_name;
    }

    if (address_component.types[0] == "locality"){
        console.log("town:"+address_component.long_name);
        itemLocality = address_component.long_name;
    }

    if (address_component.types[0] == "country"){ 
        console.log("country:"+address_component.long_name); 
        itemCountry = address_component.long_name;
    }

    if (address_component.types[0] == "postal_code_prefix"){ 
        console.log("pc:"+address_component.long_name);  
        itemPc = address_component.long_name;
    }

    if (address_component.types[0] == "street_number"){ 
        console.log("street_number:"+address_component.long_name);  
        itemSnumber = address_component.long_name;
    }
    //return false; // break the loop   
});

Solution 2

tried a couple of different requests:

MK107BX

Cleveland Park Crescent, UK

like you say, array size returned is inconsistent but the Town for both results appears to be in the address_component item with type of [ "locality", "political" ]. Perhaps you could use that as an indicator?

EDIT: get the locality object using jQuery, add this to your response function:

var arrAddress = item.results[0].address_components;
// iterate through address_component array
$.each(arrAddress, function (i, address_component) {
    if (address_component.types[0] == "locality") // locality type
        console.log(address_component.long_name); // here's your town name
        return false; // break the loop
    });

Solution 3

I had to create a program that would fill in the latitude, longitude, city, county, and state fields in a user form when the user clicks on a location on the map. The page can be found at http://krcproject.groups.et.byu.net and is a user form to allow the public to contribute to a database. I don't claim to be an expert, but it works great.

<script type="text/javascript">
  function initialize() 
  {
    //set initial settings for the map here
    var mapOptions = 
    {
      //set center of map as center for the contiguous US
      center: new google.maps.LatLng(39.828, -98.5795),
      zoom: 4,
      mapTypeId: google.maps.MapTypeId.HYBRID
    };

    //load the map
    var map = new google.maps.Map(document.getElementById("map"), mapOptions);

    //This runs when the user clicks on the map
    google.maps.event.addListener(map, 'click', function(event)
    {
      //initialize geocoder
      var geocoder = new google.maps.Geocoder()

      //load coordinates into the user form
      main_form.latitude.value = event.latLng.lat();
      main_form.longitude.value = event.latLng.lng();

      //prepare latitude and longitude
      var latlng = new google.maps.LatLng(event.latLng.lat(), event.latLng.lng());

      //get address info such as city and state from lat and long
      geocoder.geocode({'latLng': latlng}, function(results, status) 
      {
        if (status == google.maps.GeocoderStatus.OK) 
        {
          //break down the three dimensional array into simpler arrays
          for (i = 0 ; i < results.length ; ++i)
          {
            var super_var1 = results[i].address_components;
            for (j = 0 ; j < super_var1.length ; ++j)
            {
              var super_var2 = super_var1[j].types;
              for (k = 0 ; k < super_var2.length ; ++k)
              {
                //find city
                if (super_var2[k] == "locality")
                {
                  //put the city name in the form
                  main_form.city.value = super_var1[j].long_name;
                }
                //find county
                if (super_var2[k] == "administrative_area_level_2")
                {
                  //put the county name in the form
                  main_form.county.value = super_var1[j].long_name;
                }
                //find State
                if (super_var2[k] == "administrative_area_level_1")
                {
                  //put the state abbreviation in the form
                  main_form.state.value = super_var1[j].short_name;
                }
              }
            }
          }
        }
      });
    });
  }
</script>

Solution 4

I am assuming you want to get the city and the state / province:

var map_center = map.getCenter();
reverseGeocode(map_center);


function reverseGeocode(latlng){
  geocoder.geocode({'latLng': latlng}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
            var level_1;
            var level_2;
            for (var x = 0, length_1 = results.length; x < length_1; x++){
              for (var y = 0, length_2 = results[x].address_components.length; y < length_2; y++){
                  var type = results[x].address_components[y].types[0];
                    if ( type === "administrative_area_level_1") {
                      level_1 = results[x].address_components[y].long_name;
                      if (level_2) break;
                    } else if (type === "locality"){
                      level_2 = results[x].address_components[y].long_name;
                      if (level_1) break;
                    }
                }
            }
            updateAddress(level_2, level_1);
       } 
  });
}

function updateAddress(city, prov){
   // do what you want with the address here
}

Don't try to return the results as you will find that they are undefined - a result of an asynchronous service. You must call a function, such as updateAddress();

Solution 5

I created this function to get the main info of geocoder results:

const getDataFromGeoCoderResult = (geoCoderResponse) => {
  const geoCoderResponseHead = geoCoderResponse[0];
  const geoCoderData = geoCoderResponseHead.address_components;
  const isEmptyData = !geoCoderResponseHead || !geoCoderData;

  if (isEmptyData) return {};

  return geoCoderData.reduce((acc, { types, long_name: value }) => {
    const type = types[0];

    switch (type) {
      case 'route':
        return { ...acc, route: value };
      case 'locality':
        return { ...acc, locality: value };
      case 'country':
        return { ...acc, country: value };
      case 'postal_code_prefix':
        return { ...acc, postalCodePrefix: value };
      case 'street_number':
        return { ...acc, streetNumber: value };
      default:
        return acc;
    }
  }, {});
};

So, you can use it like this:

const geoCoderResponse = await geocodeByAddress(value);
const geoCoderData = getDataFromGeoCoderResult(geoCoderResponse);

let's say that you are going search Santiago Bernabéu Stadium, so, the result will be:

{
  country: 'Spain',
  locality: 'Madrid',
  route: 'Avenida de Concha Espina',
  streetNumber: '1',
}
Share:
84,678

Related videos on Youtube

v3nt
Author by

v3nt

Updated on March 14, 2021

Comments

  • v3nt
    v3nt over 3 years

    Having problems getting the different arrays content from geocoder results.

    item.formatted_address works but not item.address_components.locality?

    geocoder.geocode( {'address': request.term }, function(results, status) {
    
            response($.map(results, function(item) {
    
            alert(item.formatted_address+" "+item.address_components.locality)
        }            
    }); 
    

    // the array returned is;

     "results" : [
          {
             "address_components" : [
                {
                   "long_name" : "London",
                   "short_name" : "London",
                   "types" : [ "locality", "political" ]
                } ],
              "formatted_address" : "Westminster, London, UK" // rest of array...
    

    any help appreciated!

    Dc

  • v3nt
    v3nt about 13 years
    afraid that doesn't work. Not sure how it would as there's no variables/arrays for 'addresses' ?
  • Ruslan
    Ruslan about 13 years
    sorry, I was on about different google maps api request. Edited.
  • v3nt
    v3nt about 13 years
    no worries! any idea how i could get the locality though? I just get undefined in my attempts ;-/ If item.formatted_address works am i wrong in thinking this should too - item.address_components.locality ?
  • Ruslan
    Ruslan about 13 years
    no, because formatted_address is a string but address_components is an array. I'll add the code on how to look through it.
  • Ruslan
    Ruslan about 13 years
    first line might be var arrAddress = item.address_components; in your case. And your code doesn't work because address_components is an array.
  • Grant
    Grant about 10 years
    Works nicely but would be more elegant and less code as a 'switch' statement.
  • kosemuckel
    kosemuckel over 8 years
    Works like a charme. Using '.short_name' I finally receive the Cityname without trailing ', Country'. Thanks!
  • John
    John over 5 years
    Do not expect this to work reliable, Google's geocode is flawed in many ways. "locality" is not always available, sometimes the city is actually in the state (level_1) field. Especially when the return type is ROOFTOP the Google Geocode results are bad. In foreign countries they suddenly switch format. You can trust "APPROXIMATE" results a lot more than "ROOFTOP"
  • bjornl
    bjornl over 3 years
    Correct. Doesn't work reliably. Google notes that there's no consistency in the components you get in your response. Also that it might change over time. developers.google.com/maps/documentation/places/web-service/‌​… under "Place Details Results"
  • luke_mclachlan
    luke_mclachlan about 2 years
    I love this, thank you, the only thing I would suggest is maybe a check/break for when a component has been found.
  • luke_mclachlan
    luke_mclachlan about 2 years
    you need to break out of every loop, check your console, however the code works great so many thanks!