-1

Using GoogleMaps API in JavaScript, I am trying to get the name (and the location) of city clicked on my map.

Firstly, I though I could use the PointOfInterest Event feature as explained in this example, however cities do not seem to provide the placeId required.

Secondly, I tried to use the reverse geocoding mechanism described here to get the complete address of the location, and from here, extract the name of the city (locality):

this.map.addListener('click', (event) => {
    this.geocoder.geocode({
        location: event.latLng,
    }, (results, status) => {
        if(status === 'OK')
        {
            if(results && results.length)
            {
                const addressResult = results[0];

                if(addressResult.address_components)
                {
                    addressResult.address_components.forEach((component) => {
                        if(component.types.includes('locality'))
                        {
                            console.log(component.long_name);
                        }
                    });
                }
            }
        }
    });
});

This method gave me pretty good results however it also showed some issues:

  • Despite setting the map locale to en, I am still getting the name of the city as it appears in the address returned by the geocoder. For example, I got Genève (french name of Geneva) instead of Geneva, I got Munchen (german name of Munich) instead of Munich

  • Clicking on a city, I sometime get another city if the location clicked belong to another locality.

Any advise to get the name of the city clicked would be much appreciated.

xomena
  • 31,125
  • 6
  • 88
  • 117
Félix Veysseyre
  • 259
  • 2
  • 16

1 Answers1

1

When you execute reverse geocoding, the service will return results of different types. The first is typically a nearest street address, after that you will have other results like neighborhood, POIs, locality, administrative areas and country.

In your code you choose the first result (nearest street address) to get the name of the city. In this case you should be aware that geocoding service returns names of streets and localities in local language rather than in the language you specified in Maps JavaScript API initialization. You can read about this policy in this blog post:

https://maps-apis.googleblog.com/2014/11/localization-of-street-addresses-in.html

For political entities this rule is not applied, so you will get items of type locality or administrative area in language you specified in your JavaScript API initialization.

In order to get the name of the locality in English you should filter the results by type locality and read its address components to get locality name.

I slightly modified your code to get localities in English, note the variable filtered_array that does a trick.

var map;
function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: 47.295077, lng: 9.211874},
      zoom: 8
    });

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

    map.addListener('click', (event) => {
      geocoder.geocode({
        location: event.latLng,
      }, (results, status) => {
        if(status === 'OK') {
            if(results && results.length) {
                var filtered_array = results.filter(result => result.types.includes("locality")); 
                var addressResult = filtered_array.length ? filtered_array[0]: results[0];

                if(addressResult.address_components) {
                    addressResult.address_components.forEach((component) => {
                        if(component.types.includes('locality')) {
                            console.log(component.long_name);
                        }
                    });
                }
            }
        }
    });
  });
} 
#map {
  height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&language=en&callback=initMap"
    async defer></script>

I hope this helps!

xomena
  • 31,125
  • 6
  • 88
  • 117
  • Thanks @xomena, your method seems give better results than mine ! If I can not find a solution not using geocoding, I think I will go for your method :) – Félix Veysseyre Nov 14 '17 at 20:20