-1

So I am trying to make a simple application that will allow the user to search for restaurants and have the results show as markers on the map and as text below. The results object that returns from the textSearch doesn't provide detailed information like: phone number, pictures, etc. So i decided to create an array of place id's pushed from the results object, get the place details for each id, then push that into an array. The problem I get is a message from google saying I'm over my quota and I think it's because I'm requesting the place details for every single search result.

Is there a way I can request the place details only for the marker I click? Or is there a better solution to my problem? Thank you in advance for your help.

<!DOCTYPE html>
<html>
<head>
  <title>gMap test</title>

 <style type="text/css">
    #map-canvas{
      height:500px;
    }
  </style>

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <script src="https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
  <script type="text/javascript">



function performSearch(){

  var locationBox;
  var address = document.getElementById("address").value;
  var searchRadius = metricConversion(document.getElementById("radius").value); 
  //gMaps method to find coordinates based on address
  geocoder.geocode({'address':address}, function(results,status){

      if(status == google.maps.GeocoderStatus.OK){
        map.setCenter(results[0].geometry.location);
        var marker = new google.maps.Marker({
          map:map,
          position: results[0].geometry.location
        });      
        var latitude =  results[0].geometry.location.A;
        var longitude =  results[0].geometry.location.F;
        locationBox = new google.maps.LatLng(latitude, longitude); 

      }else{
        errorStatus(status);
        return;
      }


      //search request object
      var request = {
        query: document.getElementById('keyword').value,  
        location: locationBox,
        radius: searchRadius, 
        //minPriceLvl: minimumPrice,
        //maxPriceLvl: maximumPrice,
        types: ["restaurant"]
      }    

      //search method. sending request object and callback function
      service.textSearch(request, handleSearchResults);          
  });   
};

  var latLngArray = [];
  var placeIdArray = [];

  //callback function
  function handleSearchResults(results,status){

    if( status == google.maps.places.PlacesServiceStatus.OK) {
      for (var i = 0; i < results.length; i++) {          
          placeIdArray.push(results[i].place_id)
          latLngArray.push(results[i].geometry.location);  
      };
      for(var j = 0; j<placeIdArray.length; j++){
        service.getDetails({placeId: placeIdArray[j]},getDetails)
      };  
    }
    else{errorStatus(status)};         
  };
  var detailedArray = [];

  function getDetails(results,status){
    if (status == google.maps.places.PlacesServiceStatus.OK) {
      detailedArray.push(results);
      for(var i = 0; i<detailedArray.length; i++){
      createMarker(detailedArray[i],i);
      }
    }
    else{
      errorStatus(status)
    };   
  }


  //array of all marker objects
  var allMarkers = [];
  //creates markers and info windows for search results
  function createMarker(place, i) {
    var image = 'images/number_icons/number_'+(i+1)+'.png';
    var marker = new google.maps.Marker({
      map: map,
      position: place.geometry.location,
      html: 
        "<div class = 'markerPop'>" + "<h3>" + (i+1) + ". " + place.name + "</h3><br>" + "<p>Address: "
        + place.formatted_address + "</p><br>" + "<p> Price Range: "+ priceLevel(place.price_level)
        + "</p>" + "</div>",
      icon: image

    });

    allMarkers.push(marker);
    marker.infowindow = new google.maps.InfoWindow();

    //on marker click event do function
    google.maps.event.addListener(marker, 'click', function() {
      //service.getDetails({placeId: placeIdArray[j]},getDetails)
      //sets infowindow content and opens infowindow
      infowindow.setContent(this.html);
      infowindow.open(map,this);

    });

    //create new bounds object
    var bounds = new google.maps.LatLngBounds();
    //iterates through all coordinates to extend bounds
    for(var i = 0;i<latLngArray.length;i++){
      bounds.extend(latLngArray[i]);
    };
    //recenters map around bounds
    map.fitBounds(bounds);

  };

  var map;
  var service;
  var geocoder;
  var infowindow;

  function initialize(location){

    var mapOptions = {
      center: new google.maps.LatLng(37.804, -122.271),
      zoom: 8,
      mapTypeId: google.maps.MapTypeId.ROADMAP 
    };

    geocoder = new google.maps.Geocoder();
    map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);
    service = new google.maps.places.PlacesService(map)
    infowindow = new google.maps.InfoWindow();
  };

  $(document).ready(function(){
    initialize();

    $('#search').on('click', function(){
      removeMarkers();
      performSearch();

    });     
  });


  //::::::Random Functions:::::::

  //Clears all markers between searches
  function removeMarkers(){
    for(var i = 0; i<allMarkers.length;i++){
      allMarkers[i].setMap(null);
    };
  };

  //converts miles to meters for search object
  function metricConversion(miles){
    var meters;
    meters = miles * 1609.34;
    return meters;
  }

  //converts number value to $ sign
  function priceLevel(number){
    var moneySigns = ""
    for(var i =0;i<=number;i++){
      moneySigns += "$";
    };
    return moneySigns;
  }


  //errors for search results
  function errorStatus(status){
    switch(status){
      case "ERROR": alert("There was a problem contacting Google Servers");
        break;
      case "INVALID_REQUEST": alert("This request was not valid");
        break;
      case "OVER_QUERY_LIMIT": alert("This webpage has gone over its request quota");
        break;
      case "NOT_FOUND": alert("This location could not be found in the database");
        break;
      case "REQUEST_DENIED": alert("The webpage is not allowed to use the PlacesService");
        break;
      case "UNKNOWN_ERROR": alert("The request could not be processed due to a server error. The request may succeed if you try again");
        break;
      case "ZERO_RESULTS": alert("No result was found for this request. Please try again");
        break;
      default: alert("There was an issue with your request. Please try again.")
    };
  };

    </script>
</head>

<body>


  <div id="map-canvas"></div>
  <div id="searchBar">
  <h3>search options</h3>
  Location:<input type="text" id="address" value="enter address here" /><br>
  Keyword<input type="text" id="keyword" value="name or keyword" /><br>
  Advanced Filters:<br>
  Search Radius:<select id="radius">
    <option>5</option>
    <option>10 </option>
    <option>15 </option>
    <option>20 </option>
    <option>25 </option>
  </select>miles<br>
  <div id="minMaxPrice">
    Min Price<select id="minPrice">
      <option>$</option>
      <option>$$</option>
      <option>$$$</option>
      <option>$$$$</option>
    </select>
    Max Price<select id="maxPrice">
      <option>$</option>
      <option>$$</option>
      <option>$$$</option>
      <option>$$$$</option>
    </select>
  </div>
  <input type="button" id="search" value="Submit Search"/><br>
  </div>
  <div id='searchResults'>

  </div>

</body>
</html>

2 Answers2

0

I had the same issue some time ago. The geocoding function by google is done in order to avoid the user executing it on a large set of data (and then, avoid you to get a large amount of geocoded address easily).

My solution was to execute the geocoding function only when the user choose a particular place, and then, display this particular data (handled by the click on the pin).

I think it would be very useful to initiate a jsfiddle with a working version of your code.

Basically on your function :

google.maps.event.addListener(marker, 'click', function() {
  //Execute geocoding function here on marker object
  //Complete your html template content
  infowindow.setContent(this.html);
  infowindow.open(map,this);

});
Burgi
  • 421
  • 8
  • 24
Mahmal Sami
  • 689
  • 7
  • 12
  • Thank you for the quick response! The reason I used the geocode method in the performSearch function is because I needed to geocode whatever address the user inputs into coordinates. Then I would take those coordinates and input them into the location key of the request object. Is there another way to get coordinates based on a user address input? – chungsquared May 21 '15 at 01:27
0

The radarSearch example in the documentation requests the details of the marker on click.

code snippet:

var map;
var infoWindow;
var service;

function initialize() {
  map = new google.maps.Map(document.getElementById('map-canvas'), {
    center: new google.maps.LatLng(-33.8668283734, 151.2064891821),
    zoom: 15,
    styles: [{
      stylers: [{
        visibility: 'simplified'
      }]
    }, {
      elementType: 'labels',
      stylers: [{
        visibility: 'off'
      }]
    }]
  });

  infoWindow = new google.maps.InfoWindow();
  service = new google.maps.places.PlacesService(map);

  google.maps.event.addListenerOnce(map, 'bounds_changed', performSearch);
}

function performSearch() {
  var request = {
    bounds: map.getBounds(),
    keyword: 'best view'
  };
  service.radarSearch(request, callback);
}

function callback(results, status) {
  if (status != google.maps.places.PlacesServiceStatus.OK) {
    alert(status);
    return;
  }
  for (var i = 0, result; result = results[i]; i++) {
    createMarker(result);
  }
}

function createMarker(place) {
  var marker = new google.maps.Marker({
    map: map,
    position: place.geometry.location,
    icon: {
      // Star
      path: 'M 0,-24 6,-7 24,-7 10,4 15,21 0,11 -15,21 -10,4 -24,-7 -6,-7 z',
      fillColor: '#ffff00',
      fillOpacity: 1,
      scale: 1 / 4,
      strokeColor: '#bd8d2c',
      strokeWeight: 1
    }
  });

  google.maps.event.addListener(marker, 'click', function() {
    service.getDetails(place, function(result, status) {
      if (status != google.maps.places.PlacesServiceStatus.OK) {
        alert(status);
        return;
      }
      var htmlStr = "<b>"+result.name+"</b><br>";
      if (result.website) htmlStr += "<a href='"+result.website+"'>"+result.website+"</a><br>";
      if (result.adr_address) htmlStr += result.adr_address+"<br>";
      infoWindow.setContent(htmlStr);
      infoWindow.open(map, marker);
    });
  });
}

google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&libraries=places"></script>
<div id="map-canvas"></div>
geocodezip
  • 158,664
  • 13
  • 220
  • 245