<!-- Copyright (c) 2015 Google Inc. All rights reserved. --> <link rel="import" href="../polymer/polymer.html"> <!-- `google-map-search` provides Google Maps Places API functionality. See https://developers.google.com/maps/documentation/javascript/places for more information on the API. #### Example: <template is="dom-bind"> <google-map-search map="[[map]]" query="Pizza" results="{{results}}"> </google-map-search> <google-map map="{{map}}" latitude="37.779" longitude="-122.3892"> <template is="dom-repeat" items="{{results}}" as="marker"> <google-map-marker latitude="{{marker.latitude}}" longitude="{{marker.longitude}}"> <h2>{{marker.name}}</h2> <span>{{marker.formatted_address}}</span> </google-map-marker> </template> </google-map> </template> --> <script> Polymer({ is: 'google-map-search', properties: { /** * The Google map object. */ map: { type: Object, value: null }, /** * The search query. */ query: { type: String, value: null }, /** * Latitude of the center of the search area. * Ignored if `globalSearch` is true. */ latitude: { type: Number, value: null }, /** * Longitude of the center of the search area. * Ignored if `globalSearch` is true. */ longitude: { type: Number, value: null }, /** * Search radius, in meters. * If `latitude` and `longitude` are not specified, * the center of the currently visible map area is used. * * If not set, search will be restricted to the currently visible * map area, unless `globalSearch` is set to true. */ radius: { type: Number, value: null }, /** * By default, search is restricted to the currently visible map area. * Set this to true to search everywhere. * * Ignored if `radius` is set. */ globalSearch: { type: Boolean, value: false }, /** * Space-separated list of result types. * The search will only return results of the listed types. * See https://developers.google.com/places/documentation/supported_types * for a list of supported types. * Leave empty or null to search for all result types. */ types: { type: String, value: null }, /** * The search results. */ results: { type: Array, value: function() { return []; }, notify: true }, /** * The lat/lng location. */ location: { type: Object, value: null, readOnly: true } }, observers: [ 'search(query,map,location,radius,types,globalSearch)', '_updateLocation(latitude,longitude)' ], /** * Fired when the details of a place are returned. * * @event google-map-search-place-detail * @param {google.maps.MarkerPlace} detail The place details. */ /** * Fired when the search element returns a result. * * @event google-map-search-results * @param {Array<{latitude: number, longitude: number}>} detail An array of search results */ /** * Perform a search using for `query` for the search term. */ search: function() { if (this.query && this.map) { var places = new google.maps.places.PlacesService(this.map); if (this.types && typeof this.types == 'string') { var types = this.types.split(' '); } if (!this.globalSearch) { var bounds = this.map.getBounds(); } else if (this.radius) { var radius = this.radius; var location = this.location ? this.location : this.map.getCenter(); } places.textSearch({ query: this.query, types: types, bounds: bounds, radius: radius, location: location }, this._gotResults.bind(this)); } }, /** * Fetches details for a given place. * @param {String} placeId The place id. * @return {Promise} place The place information. */ getDetails: function(placeId) { var places = new google.maps.places.PlacesService(this.map); return new Promise(function(resolve, reject) { places.getDetails({placeId: placeId}, function(place, status) { if (status === google.maps.places.PlacesServiceStatus.OK) { resolve(place); this.fire('google-map-search-place-detail', place); } else { reject(status); } }.bind(this)); }.bind(this)); }, _gotResults: function(results, status) { this.results = results.map(function(result) { // obtain lat/long from geometry result.latitude = result.geometry.location.lat(); result.longitude = result.geometry.location.lng(); return result; }); this.fire('google-map-search-results', this.results); }, _updateLocation: function() { if (!this.map) { return; } else if (typeof this.latitude !== 'number' || isNaN(this.latitude)) { throw new TypeError('latitude must be a number'); } else if (typeof this.longitude !== 'number' || isNaN(this.longitude)) { throw new TypeError('longitude must be a number'); } // Update location. This will trigger a new search. this._setLocation({lat: this.latitude, lng: this.longitude}); } }); </script>