var producers = new Array(); var consumers = new Array(); var postback_url = "${c.postback_url}"; /* The URL encoding changes all of our double quotes to ", so we * have to convert them back before we do anything with the JSON * data. */ var locations_json = "${c.json}"; locations_json = locations_json.replace(/"/g, '"'); var locations = JSON.parse(locations_json); for (var location_idx = 0; location_idx < locations.length; location_idx++) { if (locations[location_idx].type == 'producer') { producers.push(locations[location_idx]); } else { consumers.push(locations[location_idx]); } } // Start another JSON array, this time containing our route data. var json_string = '['; var completed_requests = 0; var total_requests = (producers.length * consumers.length); function routing_callback(result, status) { /* This is the callback that gets applied to each * DirectionsResult. It occurs asynchronously, which is why we keep * track of the total/completed requests. Only the last call to * complete should actually do something with the final result. */ if (status == google.maps.DirectionsStatus.OK) { json_string += JSON.stringify(result); for (var route_idx = 0; route_idx < result.routes.length; route_idx++) { var num_legs = result.routes[route_idx].legs.length; if (num_legs > 1) { alert("Unexpected number of legs (" + result.routes.legs.length.toString() + ") on route number " + route_idx.toString() + '.'); } } } else { alert("Error, status: " + status); } completed_requests += 1; if (completed_requests == total_requests) { // Close the array, and do something with the result. json_string += ']'; var F = new Form(); F.post_data(postback_url, json_string); } else { // Continue the array. json_string += ','; } } function get_directions(pairs_to_skip) { /* We can only get directions for 10 producer/consumer pairs at a * time. We pass the pairs_to_skip variable back to this function * via setTimeout so that we can skip the ones we've already * submitted. */ // Create the object that will do the direction-getting. var directions_service = new google.maps.DirectionsService(); var requests_submitted = 0; // And ask it to get directions for each producer/consumer pair. for (var i = 0; i < producers.length; i++) { for (var j = 0; j < consumers.length; j++) { var pair_number = (i * consumers.length) + (j+1); if (pair_number <= pairs_to_skip || requests_submitted > 9) { continue; } /* We'll pass these to the DirectionsRequest object. They aren't * necessarily LatLngs, since if either the latitude or * longitude is missing, we'll fall back to using the name. */ var producer_latlng; var consumer_latlng; if (producers[i].latitude && producers[i].longitude) { producer_latlng = new google.maps.LatLng(producers[i].latitude, producers[i].longitude); } else { producer_latlng = producers[i].name; } if (consumers[j].latitude && consumers[j].longitude) { consumer_latlng = new google.maps.LatLng(consumers[j].latitude, consumers[j].longitude); } else { consumer_latlng = consumers[j].name; } var directions_request = { origin: producer_latlng, destination: consumer_latlng, provideTripAlternatives: true, travelMode: google.maps.DirectionsTravelMode.DRIVING } /* The function routing_callback(...) gets applied to the result * of route(). Ideally, that result will be a DirectionsResult * object containing directions. This executes * asynchronously. */ directions_service.route(directions_request, routing_callback); requests_submitted += 1; } } if (pairs_to_skip < total_requests) { // Next time around, skip whatever requests we submitted this // time. pairs_to_skip += requests_submitted; /* 5 seconds is the smallest timeout that will work here. */ window.setTimeout("get_directions(" + pairs_to_skip + ");", 5000); } return; } function onload_handler(e) { // Avoid problems with the implicit event argument to onload // handlers. get_directions(0); } window.onload = onload_handler;