通过Google Places API分页获得20多项结果

时间:2012-07-26 08:52:03

标签: javascript google-places-api

谷歌的演示有一个片段,通过分页捕获来自地方搜索的20多个结果:

    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;
    }
  });

我在尝试将此代码段整合到以下示例中时遇到问题,Github中的另一个Google地图示例,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>

有人可以帮忙吗?关于这个问题的一些亮点(指针)就足够了。

2 个答案:

答案 0 :(得分:6)

这是我如何做到的。我不是这个东西的大师,但这是我的代码。

首先,您可能需要将搜索调用从函数()中删除回自己的函数。

我有类似

的东西
placesServiceClass.search(request, placesCallback);

在你的回调处理中,只需执行类似......

的操作
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();
}

Google文档说明您需要在下次呼叫之间等待2秒,因此需要等待睡眠。

pagination.nextPage()调用相同的回调,在我的例子中是placesCallback()。

希望有所帮助

答案 1 :(得分:3)

使用Radar Search一次获得更多结果。然后,您可以调用PlacesService.getDetails()以获取有关每个位置的更多详细信息。