Google商家信息未通过RouteBoxer

时间:2015-06-24 19:53:43

标签: javascript google-maps google-places-api routeboxer

编辑:我似乎达到了查询限制,但我没有返回完整的200个结果。因此,经过进一步的研究,Google API似乎会让我查询10个框,返回这些结果,然后以剩余的OVER_QUERY_LIMIT状态给我打电话。所以我认为我现在有两个选择:减慢我的查询,或者扩大我的距离以在路线上创建更少的盒子。

我目前正在愚弄建立一个小型网络应用程序,提供有关路线上的地方的详细信息(如加油站和公路旅行中的咖啡)。我已将Google Maps API与地方资料库和RouteBoxer一起使用。 我使用RouteBoxer生成了所有相应的框,但是当这些框传递到地方图书馆时,我只会回到某些地方。通常我会得到路线的前半部分(在较短的路线上)或一些随机的路线(用于较长的路线)。从旧金山到西雅图,我回到了西雅图和梅德福附近的加油站,仅限俄勒冈州。

最初我想也许我的命中率达到了200,但它对每个盒子单独提出要求,而我的总结果通常不会达到200.返回的结果通常非常一致我能看到什么。在查看我的网络请求和响应的详细信息时,似乎脚本正在通过使用“位置”库进行请求的框中移动,并且突然它会在一定程度上停止。

您可以在Heroku上查看结果和框的实时应用。

我的JavaScript无论如何都不是最强大的。这就是为什么我想使用这个API的原因之一,所以如果我犯了一个微不足道的错误,请原谅我的无知。完整的脚本如下。任何方向都非常感谢!

var infowindow = new google.maps.InfoWindow();
var map;
var routeBoxer;
var service;

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();
  var mapOptions = {
    zoom: 4,
    center: new google.maps.LatLng(39, -98),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
  };
  map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
  service = new google.maps.places.PlacesService(map);

  routeBoxer = new RouteBoxer();

  directionService = new google.maps.DirectionsService();
  directionsRenderer = new google.maps.DirectionsRenderer({ map: map })

  directionsDisplay.setMap(map);
  directionsDisplay.setPanel(document.getElementById('directions-panel'));
}

function calcRoute() {
  var start = document.getElementById('start').value;
  var end = document.getElementById('end').value;
  var waypt1 = document.getElementById('waypoint1').value;
  var waypt2 = document.getElementById('waypoint2').value;
  var waypts = []

  if (waypt1) {
    waypts.push({
      location:waypt1,
      stopover:true});  
  }
  if (waypt2) {
    waypts.push({
      location:waypt2,
      stopover:true});  
  }

  var request = {
    origin: start,
    destination: end,
    waypoints: waypts,
    optimizeWaypoints: true,
    travelMode: google.maps.TravelMode.DRIVING
  };

  directionService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);

      // Build boxes around route
      var path = response.routes[0].overview_path;
      var boxes = routeBoxer.box(path, 2); // distance in km from route
      drawBoxes(boxes);
      for (var i=0; i < boxes.length; i++) {
        var bounds = boxes[i];
        findPlaces(bounds);
        findPlacesByText(bounds);
      }
    } else {
      alert("Directions query failed: " + status);
    }
  });
}

function findPlaces(bounds) {
  var selectedTypes = []; 

  var inputElements = document.getElementsByClassName('placeOption');

  for (var i=0; inputElements[i]; i++) {
    if (inputElements[i].checked) {
     selectedTypes.push(inputElements[i].value)
    }
  }

  var request = {
    bounds: bounds,
    types: selectedTypes
  };

  if (selectedTypes.length > 0) {
    service.radarSearch(request, callback);
  }
}

function findPlacesByText(bounds) {
  var selectedTypes = ''; 

  var inputElements = document.getElementsByClassName('textOption');

  for (var i=0; inputElements[i]; i++) {
    if (inputElements[i].checked) {
     selectedTypes += inputElements[i].value + ', '
    }
  }

  var request = {
    bounds: bounds,
    query: selectedTypes
  };

  if (selectedTypes.length > 0) {
    service.textSearch(request, callback);
  }
}

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

function createMarker(place) {
  var marker = new google.maps.Marker({
    map: map,
    position: place.geometry.location
  });

  var request = {
    reference: place.reference
  };

  google.maps.event.addListener(marker,'click',function(){
    service.getDetails(request, function(place, status) {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        var contentStr = '<h5>' + place.name + '</h5><p>' + place.formatted_address;
        if (!!place.formatted_phone_number) contentStr += '<br />' + place.formatted_phone_number;
        if (!!place.website) contentStr += '<br /><a target="_blank" href="' + place.website + '">' + place.website + '</a>';
        contentStr += '<br />' + place.types + '</p>';
        infowindow.setContent(contentStr);
        infowindow.open(map,marker);
      } else {
        var contentStr = "<h5>No Result, status=" + status + "</h5>";
        infowindow.setContent(contentStr);
        infowindow.open(map,marker);
      }
    });
  });
}

google.maps.event.addDomListener(window, 'load', initialize);

1 个答案:

答案 0 :(得分:0)

经过多次实验和进一步研究后,我决定尝试减慢查询速度。我处理的方式是编写一个调用我的查询函数的新函数,然后以下一个路由框的延迟递归调用自身。如果返回OVER_QUERY_LIMIT状态,则会调用延迟增加的框。到目前为止它似乎工作得很好,但是它很快就会将呼叫延迟增加到接近半秒(或更长时间),如果你有很多箱子的长路线,这可能需要一段时间。我的新功能似乎已经解决了这个问题,如下所示。它需要更多微调才能真正做到正确,但它已经接近了!

var delay = 100;

...

function queryPlaces(boxes, searchIndex) {
  // delay calls to Places API to prevent going over query limit (10/sec)
  var bounds = boxes[searchIndex];
  findPlaces(bounds);
  findPlacesByText(bounds);
  if (searchIndex > 0) {
    searchIndex--;
    setTimeout(queryPlaces, delay, boxes, searchIndex);
  }
}