Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

More than 20 results by pagination with Google Places API

Google's demo has this snippet to capture, by pagination, more than 20 results from place search:

    service.nearbySearch(request, resultList, function(status, results, pagination) {
    if (status != google.maps.places.PlacesServiceStatus.OK) {
     return;
    }
    resultList.addPlaces(results);
    if (pagination.hasNextPage) {
      resultList.button.onClick = pagination.nextPage;
    }
  });

I have problems trying to integret this snippet into the following example, another google map example in Github, gmaps-samples-v3:

 <!DOCTYPE html>
<html>
  <head>
    <title>Places Search Demo</title>
    <link rel="stylesheet" type="text/css"
          href="https://google-developers.appspot.com/css/screen.css">
    <link rel="stylesheet"
          href="https://www.google.com/cse/style/look/default.css" type="text/css">
    <script type="text/javascript"
            src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places">
    </script>
    <script type="text/javascript">
      var map;
      var places;
      var iw;
      var markers = [];

      function initialize() {
        var options = {
          zoom: 12,
          center: new google.maps.LatLng(22.279387,114.164579),
          mapTypeId: google.maps.MapTypeId.ROADMAP,
          streetViewControl: false
        };
        var mapCanvas = document.getElementById('map_canvas');
        map = new google.maps.Map(mapCanvas, options);
        places = new google.maps.places.PlacesService(map);
      }

      function updateKeyword(event) {
        updateRankByCheckbox();
        blockEvent(event);
      }

      function blockEvent(event) {
        if (event.which == 13) {
          event.cancelBubble = true;
          event.returnValue = false;
        }
      }

      function updateRankByCheckbox() {
        var types = getTypes();
        var keyword = document.controls.keyword.value;
        var disabled = !types.length && !keyword;
        var label = document.getElementById('rankbylabel');
        label.style.color = disabled ? '#cccccc' : '#333';
        document.controls.rankbydistance.disabled = disabled;
      }

      function getTypes() {
        var types = []
        for (var i = 0; i < document.controls.type.length; i++) {
          if (document.controls.type[i].checked) {
            types.push(document.controls.type[i].value);
          }
        }
        return types;
      }

      function search(event) {
        if (event) {
          event.cancelBubble = true;
          event.returnValue = false;
        }

        var search = {};

        // Set desired types.
        var types = getTypes();
        if (types.length) {
          search.types = types;
        }

        // Set keyword.
        var keyword = document.controls.keyword.value;
        if (keyword) {
          search.keyword = keyword;
        }

        // Set ranking.
        if (!document.controls.rankbydistance.disabled &&
            document.controls.rankbydistance.checked) {
          search.rankBy = google.maps.places.RankBy.DISTANCE;
          search.location = map.getCenter();
        } else {
          search.rankBy = google.maps.places.RankBy.PROMINENCE;
          search.bounds = map.getBounds()
        }

        // Search.
        places.search(search, function(results, status) {
          if (status == google.maps.places.PlacesServiceStatus.OK) {
            clearResults();
            clearMarkers();
            for (var i = 0; i < results.length; i++) {
              var letter = String.fromCharCode(65 + i);
              markers[i] = new google.maps.Marker({
                position: results[i].geometry.location,
                animation: google.maps.Animation.DROP,
                icon: 'http://maps.gstatic.com/intl/en_us/mapfiles/marker' +
                    letter + '.png'
              });
              google.maps.event.addListener(
                  markers[i], 'click', getDetails(results[i], i));
              dropMarker(markers[i], i * 100);
              addResult(results[i], i);
            }
          }
        });
      }

      function clearMarkers() {
        for (var i = 0; i < markers.length; i++) {
          if (markers[i]) {
            markers[i].setMap(null);
            delete markers[i]

          }
        }
      }

      function dropMarker(marker, delay) {
        window.setTimeout(function() {
          marker.setMap(map);
        }, delay);
      }

      function addResult(result, i) {
        var results = document.getElementById('results');
        var tr = document.createElement('tr');
        tr.style.backgroundColor = i % 2 == 0 ? '#F0F0F0' : '#FFFFFF';
        tr.onclick = function() {
          google.maps.event.trigger(markers[i], 'click');
        };

        var iconTd = document.createElement('td');
        var nameTd = document.createElement('td');
        var icon = document.createElement('img');
        icon.src = result.icon;
        icon.className = 'placeIcon';
        var name = document.createTextNode(result.name);
        iconTd.appendChild(icon);
        nameTd.appendChild(name);
        tr.appendChild(iconTd);
        tr.appendChild(nameTd);
        results.appendChild(tr);
      }

      function clearResults() {
        var results = document.getElementById('results');
        while (results.childNodes[0]) {
          results.removeChild(results.childNodes[0]);
        }
      }

      function getDetails(result, i) {
        return function() {
          places.getDetails({
            reference: result.reference
          }, showInfoWindow(i));
        }
      }

      function showInfoWindow(i) {
        return function(place, status) {
          if (iw) {
            iw.close();
            iw = null;
          }

          if (status == google.maps.places.PlacesServiceStatus.OK) {
            iw = new google.maps.InfoWindow({
              content: getIWContent(place)
            });
            iw.open(map, markers[i]);
          }
        }
      }

      function getIWContent(place) {
        var content = '<table style="border:0"><tr><td style="border:0;">';
        content += '<img class="placeIcon" src="' + place.icon + '"></td>';
        content += '<td style="border:0;"><b><a href="' + place.url + '">';
        content += place.name + '</a></b>';
        content += '</td></tr></table>';
        return content;
      }

      google.maps.event.addDomListener(window, 'load', initialize);
    </script>

    <style type="text/css">
      html, body {
        margin: 0;
        padding: 0;
        height: 100%;
        font-family: arial;
        font-size: 13px;
        overflow: hidden;
      }

      #container {
        margin-top: 6px;
        margin-left: 6px
      }

      #map_canvas {
        float: left;
        width: 320px;
        height: 406px;
        margin-top: 13px; 
      }

      #listing {
        float: left;
        margin-left: 1px;
        margin-top: 13px;
        width: 200px;
        height: 406px;
        overflow: auto;
        cursor: pointer;
      }

      #controls {
        padding: 5px;
      }
      .placeIcon {
        width: 16px;
        height: 16px;
        margin: 2px;
      }

      #results {
        border-collapse: collapse;
        width: 184px;
      }
    </style>
  </head>

  <body class="docs framebox_body">
    <div id="container">
      <div>
        <form name="controls">
          <div style="margin-top: 5px">
            Keyword:
          </div>
          <div style="margin-left: 9px">
            <input id="keyword" type="text" onkeyup="updateKeyword(event)"
                   onkeydown="blockEvent(event)" style="width:110px">
          </div>
          <div style="margin-top: 5px">
            Types:
          </div>
          <div style="margin-left: 9px">
            <input type="checkbox" name="type" value="store"
                   onclick="updateRankByCheckbox()" /> store<br/>
            <input type="checkbox" name="type" value="clothing_store"
                   onclick="updateRankByCheckbox()" /> clothing_store<br/>
            <input type="checkbox" name="type" value="restaurant"
                   onclick="updateRankByCheckbox()" /> restaurant<br>
            <input type="checkbox" name="type" value="lodging"
                   onclick="updateRankByCheckbox()" /> lodging<br>
            <input type="checkbox" name="type" value="subway_station"
                   onclick="updateRankByCheckbox()" />MTR Station<br>
          </div>
          <div id="rankbylabel" style="margin-top: 5px; color: #cccccc">
            <input type="checkbox" disabled="true"
                   name="rankbydistance" /> Rank by distance
          </div>
          <div style="margin-top: 5px">
            <input type="submit" value="Search" onclick="search(event)" />
          </div>
        </form>
      </div>
    <div id="map_canvas"></div>
    <div id="listing">
      <table id="results"></table>
    </div>
  </body>
</html>

Could anyone help? Some light(pointers) on the issue would be good enough, please.

like image 854
Josef Young Avatar asked Jul 26 '12 08:07

Josef Young


2 Answers

here's how i've done it. I'm no guru on this stuff but here's my code.

To start with you may need to strip the search call back out of function() into it's own function.

I've got something like

placesServiceClass.search(request, placesCallback);

in your callback for restuls processing just do something like...

function placesCallback(results, status, pagination) {

// process the resutls  
if (status == google.maps.places.PlacesServiceStatus.OK) {      
    for (var int = 0; int < results.length; int++) {    
        placesManager.addMarker(results[int], int);
    }

 } 

if (pagination.hasNextPage) {
    sleep:2;
    pagination.nextPage();
}

The Google documentation states that you need to wait 2 seconds between next page calls, hence the sleep.

The pagination.nextPage() calls the same callback, in my case placesCallback().

Hope that helps

like image 132
Ben Jerrim Avatar answered Nov 15 '22 05:11

Ben Jerrim


Use Radar Search to get more results at once. You can then call PlacesService.getDetails() for more details on each of those places.

like image 38
jesal Avatar answered Nov 15 '22 03:11

jesal