2014-09-28 4 views
1

첫 번째로 나는 Google Maps Javascript API v3의 경험이 없다고 말하고 싶습니다. (내 유일한 경험은 지난 3 일간입니다.) 나는 마커의 목록과지도를 표시하고 DirectionsService를 사용하여 연결을 관리했다, 그러나 때때로 내 목록은 매우 크고, 나는 다음과 같은 오류 얻을 :요청 엔터티가 너무 큽니다. - Google지도 길 찾기 오류 413

// List of all locations for device 
var locations = []; 
// example: locations = [ 
//  {datetime: '2014/09/28 20:20', location: '41.99999 21.99999 30.0'}, 
//  ... {...} ... may be more than 200 entries for locations 
//  {datetime: '2014/09/28 20:25', location: '41.99999 21.99999 30.0'} 
// ] 

var map; 
var markers = []; 
var bounds = new google.maps.LatLngBounds(); 
var pathPoints = []; 
var infoWindow = new google.maps.InfoWindow(); 
var accuracy = new google.maps.Circle({ 
    fillColor: '#ff4080', 
    fillOpacity: 0.5, 
    strokeOpacity: 0, 
    zIndex: 0 
}); 
var path = new google.maps.Polyline(polyOptions); 
var geocoder; 
var directionsService = new google.maps.DirectionsService(); 
var directionsDisplay; 
var polyOptions = { 
    geodesic: true, 
    strokeColor: '#28b8b8', 
    strokeOpacity: 1.0, 
    strokeWeight: 8, 
    zIndex: 1 
} 
function showInfoWindow(marker, datetime, acc){ 
    geocoder = new google.maps.Geocoder(); 
    geocoder.geocode({ 
     'latLng': marker.getPosition() 
    }, function(results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
      if (results[1]) { 
       infoWindow.close(); 
       var date = datetime.split(" ")[0]; 
       var time = datetime.split(" ")[1]; 
       var content = '<div class="infowindow">' 
         + results[1].formatted_address.trim() + '<br />' 
         + 'Date: ' + date + '<br />' 
         + 'Time: ' + time + '<br />' 
         + 'Accuracy: ' + acc + 'm' 
         + '</div>'; 
       infoWindow.setContent(content); 
       infoWindow.open(map, marker); 
       accuracy.setMap(null); 
       accuracy.setMap(map); 
       accuracy.setCenter(marker.getPosition()); 
       accuracy.setRadius(acc/1.6); 
      } else { 
       // alert('No results found'); 
      } 
     } else { 
      alert('Geocoder failed due to: ' + status); 
     } 
    }); 
} 
function addMultiMarker(latLng, num, datetime, acc){ 
    // Create marker at provided location 
    var marker = new google.maps.Marker({ 
     position: latLng, 
     map: map, 
     icon: image_circle, 
     title: 'Location #' + num, 
     zIndex: num + 1 
    }); 
    // On marker click center it inside map and show infoWindow 
    google.maps.event.addListener(marker, 'click', function() { 
     map.panTo(marker.getPosition()); 
     showInfoWindow(marker, datetime, acc); 
    }); 
    return marker; 
} 
function showRoute() { 
    var rendererOptions = { 
     draggable: false, 
     hideRouteList: true, 
     suppressMarkers: true, 
     infoWindow: infoWindow, 
     polylineOptions: polyOptions, 
     map: map 
    }; 
    directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions); 
    var len = markers.length; 
    var start = markers[0].getPosition(); 
    var end = markers[len - 1].getPosition(); 
    new google.maps.event.trigger(markers[len - 1], 'click'); 
    var wayPts = []; 
    for(var i = 1; i < len - 1; i++){ 
     wayPts.push({ 
      location: markers[i].getPosition(), 
      stopover: true 
     }); 
    } 
    var request = { 
     origin: start, 
     destination: end, 
     waypoints: wayPts, 
     optimizeWaypoints: true, 
     travelMode: google.maps.TravelMode.DRIVING 
    }; 
    directionsService.route(request, function(response, status) { 
     if (status == google.maps.DirectionsStatus.OK) { 
      directionsDisplay.setDirections(response); 
     } 
    }); 
} 
function showMapPeriod(periodStart, periodEnd){ 
    // Simple map options 
    var mapOptions = { 
     zoom: 15, 
     center: new google.maps.LatLng(41, 21), 
     mapTypeId : google.maps.MapTypeId.ROADMAP, 
     mapTypeControl: true, 
     mapTypeControlOptions: { 
      style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, 
      position: google.maps.ControlPosition.TOP_RIGHT 
     }, 
     zoomControl: true, 
     zoomControlOptions: { 
      style: google.maps.ZoomControlStyle.LARGE, 
      position: google.maps.ControlPosition.LEFT_CENTER 
     }, 
     panControl: false, 
     streetViewControl: false 
    }; 
    $("#map").html(""); 
    // Create and show map 
    openMapContainer(); // just a function that shows the map <div> element 
    map = new google.maps.Map(document.getElementById('map'), mapOptions); 
    // Create and display markers 
    bounds = new google.maps.LatLngBounds(); 
    markers = []; 
    var len = 0; 
    for(var i = periodStart; i <= periodEnd; i++, len++){ 
     var loc_vals = locations[i].location.trim().split(" "); 
     var lat = parseFloat(loc_vals[0]); 
     var lng = parseFloat(loc_vals[1]); 
     var acc = parseFloat(loc_vals[2]); 
     // Create marker at provided location 
     var datetime = locations[i].datetime; 
     var latLng = new google.maps.LatLng(lat, lng); 
     markers[len] = addMultiMarker(latLng, len+1, datetime, acc); 
     bounds.extend(latLng); 
    } 
    showRoute(); 
    map.fitBounds(bounds); 
} 
: 이것은 내 코드입니다

Failed to load resource: the server responded with a status of 413 (Request Entity Too Large) 

글쎄, 내 코드가 부분적으로 작동하고, 누군가 내가이 문제를 제거하는데 도움을 줄 수 있다면, 나는 그것을 매우 고맙게 생각할 것이다. 더 잘 설명하기 위해 도로를 통해 위치를 연결하는 많은 방법 (200+ 개) 또는 일부 방법으로 Directions을 요청하는 솔루션이 필요합니다. (실제로 길 찾기가 필요하지는 않지만 연결하고 싶지는 않습니다. 위치는 간단합니다 Polyline).

편집 : Here 간단한 해독을 제공하여 문제를 보시려면 line 15에서 주석을 제거하십시오.

+0

문제가있는 예제를 제공해주십시오. – geocodezip

+0

문제점을 표시하려면 어떻게 변경합니까? – geocodezip

+0

여기이 피들 (http://jsfiddle.net/o3zqhsaz/6/)에서 포인트가 연결되어 있지 않다는 것을 알 수 있습니다 – kiko283

답변

5

아무도 내 문제를 도와 줄 수 없었기 때문에, 나는 그것을 스스로 풀어야했습니다. 이 질문은 많은 사람들에게 상당히 문제가되는 것으로 보입니다. 웹에서 설명이 잘되어 있지 않아서 비슷한 문제가있는 개발자에게 도움이 될 수 있습니다.

어쨌든, 요점을 알려 드리겠습니다. OxyDesign가 제안 오류 때문에 구글의 한계로 던져졌다, 오류 :

  • google.maps.DirectionsResult.MAX_WAYPOINTS_EXCEEDED - 나는 기원, 대상 이상 8 (구글 제한) 중간 지점을 가진 요청을 보낸 때문이다 .
  • 내가 쉽게 해결

(난 그냥 다음의 첫 번째 지점으로 하나 개의 요청의 마지막 점과 10 점의 덩어리의 배열을 분할), 그러나 나는 다른 오류 가지고 :

  • google.maps.DirectionsResult.OVER_QUERY_LIMIT - 이것은 초당 10 건 (다시 Google 제한) 이상의 요청을 보내려고했기 때문입니다.

좀 더 실험하고 검색하고 테스트하여 해결되었지만 문제가 해결되었습니다. (구글이 뭔가 변경 될 때까지, 적어도 게시시)

지금은 여기에 나를 위해 작동 코드입니다 :

// list of randomly generated locations (max 288) 
var locations = []; 
for(var i=0; i<288; i++){ 
    locations[i] = { 
     datetime: '2014/10/01 12:10', 
     location: (51 + Math.random()) + 
     ' ' + (-0.5 + Math.random()) + ' 30.0' 
    }; 
} 
// Marker images 
var image_pin = new google.maps.MarkerImage(
    'http://stedkomerc.com.mk/gpslocator/images/mPin.svg', 
    new google.maps.Size(25, 41), // size 
    new google.maps.Point(0, 0), // origin, top-left corner 
    new google.maps.Point(12, 40) // anchor 
); 
var image_circle = new google.maps.MarkerImage(
    'http://stedkomerc.com.mk/gpslocator/images/mCircle.svg', 
    new google.maps.Size(19, 19), // size 
    new google.maps.Point(0, 0), // origin, top-left corner 
    new google.maps.Point(9, 9) // anchor 
); 
// Variables 
var map; 
var bounds = new google.maps.LatLngBounds(); 
var markers = []; 
var pathPoints = []; 
var geocoder; 
var infoWindow = new google.maps.InfoWindow(); 
var accuracy = new google.maps.Circle({ 
    fillColor: '#ff4080', 
    fillOpacity: 0.4, 
    strokeOpacity: 0, 
    zIndex: 0 
}); 
var polyOptions = { 
    geodesic: true, 
    strokeColor: '#28b8b8', 
    strokeOpacity: 1.0, 
    strokeWeight: 8, 
    zIndex: 1 
}; 
var path = new google.maps.Polyline(polyOptions); 
var directionsService = new google.maps.DirectionsService(); 
var directions = []; 
var rendererOptions = { 
    draggable: false, 
    hideRouteList: true, 
    suppressMarkers: true, 
    preserveViewport: true, 
    infoWindow: infoWindow, 
    polylineOptions: polyOptions 
}; 
var requests = []; 
var MAX_POINTS_PER_REQUEST = 10; // 8*waypts Google limit + start + end 
var MAX_REQUESTS_PER_SECOND = 10; // Google limit 
// functions 
function showInfoWindow(marker, datetime, acc){ 
    geocoder = new google.maps.Geocoder(); 
    geocoder.geocode({ 
     'latLng': marker.getPosition() 
    }, function(results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
      if (results[1]) { 
       infoWindow.close(); 
       var date = datetime.split(" ")[0]; 
       var time = datetime.split(" ")[1]; 
       var content = '<div class="infowindow">' + 
        results[1].formatted_address.trim() + '<br />' + 
        'Date: ' + date + '<br />' + 
        'Time: ' + time + '<br />' + 
        'Accuracy: ' + acc + 'm' + 
        '</div>'; 
       infoWindow.setContent(content); 
       infoWindow.open(map, marker); 
       accuracy.setMap(null); 
       accuracy.setMap(map); 
       accuracy.setCenter(marker.getPosition()); 
       accuracy.setRadius(acc); 
      } 
     } else { 
      console.log('Geocoder failed due to: ' + status); 
     } 
    }); 
} 
function addMultiMarker(latLng, num, datetime, acc){ 
    // Create marker at provided location 
    var marker = new google.maps.Marker({ 
     position: latLng, 
     map: map, 
     icon: image_circle, 
     title: 'Location #' + num, 
     zIndex: num + 1 
    }); 
    // On marker click center it inside map and show infoWindow 
    google.maps.event.addListener(marker, 'click', function() { 
     //map.panTo(marker.getPosition()); 
     showInfoWindow(marker, datetime, acc); 
    }); 
    return marker; 
} 
function connectMarkersPolyline(mrkrs){ 
    path.setMap(map); 
    pathPoints = path.getPath(); 
    len = mrkrs.length; 
    for(var i = 0; i < len; i++){ 
     pathPoints.push(mrkrs[i].getPosition()); 
    } 
} 
function connectMarkersRoute(mrkrs, part, maxParts){ 
    var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions); 
    directionsDisplay.setMap(map); 
    var len = mrkrs.length; 
    var start = mrkrs[0].getPosition(); 
    var end = mrkrs[len - 1].getPosition(); 
    var wayPts = []; 
    for(var i = 1; i < len - 1; i++){ 
     wayPts.push({ 
      location: mrkrs[i].getPosition(), 
      stopover: true 
     }); 
    } 
    var request = { 
     origin: start, 
     destination: end, 
     waypoints: wayPts, 
     optimizeWaypoints: false, 
     travelMode: google.maps.TravelMode.DRIVING, 
     unitSystem: google.maps.UnitSystem.METRIC 
    }; 
    directionsService.route(request, function(response, status) { 
     if (status == google.maps.DirectionsStatus.OK) { 
      // request status OK, display route 
      directionsDisplay.setDirections(response); 
      // save it in array in case we want to remove it later 
      directions.push(directionsDisplay); 
      // if not last chunk, send next chunk after 100ms 
      // 1 request per 100ms => 10 requests per 1s 
      if(part+1 < maxParts) 
       setTimeout(connectMarkersRoute(requests[part+1], part+1, maxParts), 100); 
      else showLastMarker(); 
     } else if (status == google.maps.DirectionsStatus.OVER_QUERY_LIMIT) { 
      // if we get error, send same request after bigger delay (120ms) 
      setTimeout(connectMarkersRoute(requests[part], part, maxParts), 120); 
     } else { 
      // if all fails, connect with simple polyline 
      console.log('Directions failed due to: ' + status); 
      connectMarkersPolyline(mrkrs); 
     } 
    }); 
} 
function connectMarkers(markers){ 
    path.setMap(null); 
    path.setPath([]); 
    directions = []; 
    requests = []; 
    var len = markers.length; 
    console.log('connecting ' + len + ' markers'); 
    var i, j; 
    // split markers array into chunks of 10 (start + waypts + end) 
    for(i=0; i<len; i+=MAX_POINTS_PER_REQUEST-1){ 
     if(i<len-1) 
      requests.push(markers.slice(i, i+MAX_POINTS_PER_REQUEST)); 
    } 
    // send first chunk to connectMarkersRoute() 
    connectMarkersRoute(requests[0], 0, requests.length); 
} 
function showMapPeriod(periodStart, periodEnd){ 
    // Map options 
    var mapOptions = { 
     zoom: 16, 
     center: new google.maps.LatLng(41.995922, 21.431465), 
     mapTypeId : google.maps.MapTypeId.ROADMAP, 
     mapTypeControl: true, 
     mapTypeControlOptions: { 
      style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, 
      position: google.maps.ControlPosition.TOP_RIGHT 
     }, 
     zoomControl: true, 
     zoomControlOptions: { 
      style: google.maps.ZoomControlStyle.LARGE, 
      position: google.maps.ControlPosition.LEFT_CENTER 
     }, 
     panControl: false, 
     streetViewControl: false 
    }; 
    $("#map").html(""); 
    //openMapContainer(); 
    // Create and show map 
    map = new google.maps.Map(document.getElementById('map'), mapOptions); 
    // Create and display markers 
    bounds = new google.maps.LatLngBounds(); 
    markers = []; 
    var len = 0; 
    for(var i = periodStart; i <= periodEnd; i++, len++){ 
     var loc_vals = locations[i].location.trim().split(" "); 
     var lat = parseFloat(loc_vals[0]); 
     var lng = parseFloat(loc_vals[1]); 
     var acc = parseFloat(loc_vals[2]); 
     // Create marker at provided location 
     var datetime = locations[i].datetime; 
     var latLng = new google.maps.LatLng(lat, lng); 
     markers[len] = addMultiMarker(latLng, len+1, datetime, acc); 
     bounds.extend(latLng); 
    } 
    connectMarkers(markers); 
    map.fitBounds(bounds); 
    if(map.getZoom() > 16) map.setZoom(16); 
} 
function showLastMarker(){ 
    new google.maps.event.trigger(markers[markers.length - 1], 'click'); 
} 
// show map 
showMapPeriod(1, 280); 
// -------- 

당신이 볼 수 있듯이를, 내가 만든 유일한 진짜 변화는 showRoute()했다 기능이 및 connectMarkersPolyline()과 결합 된 connectMarkers()이되어 두 오류가 모두 처리됩니다.

예제는 here입니다.모든 경로 청크를로드하는 데 약간의 시간이 필요하지만 적어도 작동합니다. 희망이 다른 사람도 도움이되기를 바랍니다.

하루에 2,500 Directions 개의 요청에 대한 Google 한도가 있으므로주의하십시오. 즉,이 답변은 200 개 이상의 대규모 요청에 대해서도 작동합니다. 테스트 한 위치는 1250 개이며 작동했습니다.

2

것 같다가이 서비스 Gmaps Waypoints (또는 , 나는 시도하고 40하지 않았다 다음 39까지 일)과 폴리 라인을 제외하고 다른 방법으로 그것을 할 방법이 없습니다에 대한 제한하지만, 당신은 그것을 원하지 않으므로 실행 가능한 해결책이 없다고 생각합니다.

+0

정보에 대해 고마워, 한계에 대해 읽었으며 지금은 어떤 종류를 찾고 있습니다. 해결 방법은 – kiko283

+0

좋습니다. 행운을 빈다. 솔루션을 찾은 경우 여기에 추가하십시오. 감사합니다 – OxyDesign

+0

해결책을 찾았습니까? 내 답변 [아래]에서 확인할 수 있습니다. (http://stackoverflow.com/questions/26088925/request-entity-too-large-google-map-directions-error-413/#26153175). – kiko283

관련 문제