H.Chan
H.Chan

Reputation: 39

Get placeId on google maps when POI is clicked

I'm using Google Maps JS V3 API on my website. I'm able to use getDetails by placeId when user searches for a place. I would like to do the same when user clicks on a POI. However, I can't seem to find a way to get this placeId when user clicks on a POI instead of using the search box.

I have done research for days, and had no luck of finding anything close.

I came across this feature request, I wonder if there is really no way of getting the placeId by POI clicking: https://code.google.com/p/gmaps-api-issues/issues/detail?id=8113&q=poi&colspec=ID%20Type%20Status%20Introduced%20Fixed%20Summary%20Stars%20ApiType%20Internal

Any help is appreciated, thanks!

Upvotes: 3

Views: 4147

Answers (3)

Anirudh
Anirudh

Reputation: 1

I was having the same issue, but using this reference https://developers.google.com/maps/documentation/javascript/examples/event-poi.

I tried it and it worked suprisingly. I hope you find this helpful.

Below is an angular implementation of the given functionality.

1)

private map: google.maps.Map;
this.map = new google.maps.Map(document.getElementById('map'));
  1. Adding a click listener on the map
this.map.addListener("click", this.handleClick.bind(this));
  1. to check whether it is a mouse event, if it is retrieve place Id
public isIconMouseEvent(
    e: google.maps.MapMouseEvent | google.maps.IconMouseEvent
  ): e is google.maps.IconMouseEvent {
    return "placeId" in e;
  }
  1. Below function uses isMouseEvent to get placeId and passes it to getPlaceDetails function to retrieve its details
  private handleClick(event: google.maps.MapMouseEvent | google.maps.IconMouseEvent) {
    console.log("You clicked on: " + event.latLng);
    if (this.isIconMouseEvent(event)) {
      console.log("You clicked on place:" + event.placeId);
      event.stop();
      if (event.placeId) {
        console.log(event.placeId);
        this.getPlaceDetails(event.placeId);
      }
    }
  }
  1. This function is used get the place details of a place using placeService provided placeId of the place
private getPlaceDetails(placeId: string) {
    const placesService = new google.maps.places.PlacesService(this.map);
    placesService.getDetails({ placeId }, (place, status) => {
        if (status === 'OK') {
            console.log('Place Details:', place);
        } else {
            console.error('PlacesService failed due to: ' + status);
        }
    });
}

These may be an angular implementation, but it is more generic and easy to understand.

Upvotes: 0

Mihail Shishkov
Mihail Shishkov

Reputation: 15797

As of 2017-12 this is now supported. Here's the example https://developers.google.com/maps/documentation/javascript/examples/event-poi

Upvotes: 2

cynx
cynx

Reputation: 387

Google doesnt provide any documented API method to get place id by clicking on a POI. However, I was able to get the place id using reverse geocoding.

First, we can get coordinates of POI by a method described in this Stack-overflow answer

Second, you can use the coordinates from getPosition() method to call the geocode method to retrieve address components and place id.

Here is a working JS Fiddle

function initialize() {
  var mapOptions = {
    zoom: 14,
    center: new google.maps.LatLng(38.8862447, -77.02158380000003),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById('map_canvas'),
    mapOptions);

  geocoder = new google.maps.Geocoder;

  //keep a reference to the original setPosition-function
  var fx = google.maps.InfoWindow.prototype.setPosition;

  //override the built-in setPosition-method
  google.maps.InfoWindow.prototype.setPosition = function() {

    //this property isn't documented, but as it seems
    //it's only defined for InfoWindows opened on POI's
    if (this.logAsInternal) {
      google.maps.event.addListenerOnce(this, 'map_changed', function() {
        var map = this.getMap();

        //the infoWindow will be opened, usually after a click on a POI
        if (map) {

          //trigger the click
          google.maps.event.trigger(map, 'click', {
            latLng: this.getPosition()
          });
        }
      });
    }
    //call the original setPosition-method
    fx.apply(this, arguments);
  };

  google.maps.event.addListener(map, 'click', function(e) {
    //alert('clicked @' + e.latLng.toString())
    geocoder.geocode({
      'location': e.latLng
    }, function(results, status) {
      if (status === google.maps.GeocoderStatus.OK) {
        if (results[0]) {

          alert('place id: ' + results[0].place_id);


        } else {
          console.log('No results found');
        }
      } else {
        console.log('Geocoder failed due to: ' + status);
      }
    });

  });
}

google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map_canvas {
  margin: 0;
  height: 100%;
}
<div id="map_canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?callback=initialize" async defer></script>

Upvotes: 4

Related Questions