set depart and arrival time in google transit Api - google-maps

I am currently working on one travel domain where I need to integrate "Trip Planner" using "Google Transit API V3". I am done with setting up map and all required option for trip planner. But here I am facing on problem.
I want to set "arrival_time" and "departure_time" in "TransitDetails" object in google API. I have created an object which returns me transit details on the route. But not as per "Departure" and "Arrival" Option passed in object.
This is what I have done in code
var directions = new google.maps.DirectionsService();
var renderer = new google.maps.DirectionsRenderer();
var startLocationAutocomplete;
var endLocationAutocomplete;
var map, transitLayer;
function initialize() {
var mapOptions = {
zoom:14,
center:new google.maps.LatLng(51.538551, -0.016633),
mapTypeId:google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
google.maps.event.addDomListener(document.getElementById('go'), 'click', route);
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(35.371359, -79.319916),
new google.maps.LatLng(36.231424, -77.752991));
var autocompleteOptions = {
bounds:defaultBounds,
types:[ "locality", "political", "geocode" ]
};
startLocationAutocomplete = new google.maps.places.Autocomplete(document.getElementById('from'));
endLocationAutocomplete = new google.maps.places.Autocomplete(document.getElementById('to'));
startLocationAutocomplete.bindTo('bounds', map);
endLocationAutocomplete.bindTo('bounds', map);
transitLayer = new google.maps.TransitLayer();
var control = document.getElementById('transit-wpr');
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control);
google.maps.event.addDomListener(control, 'click', function () {
transitLayer.setMap(transitLayer.getMap() ? null : map);
});
addDepart();
route();
}
function addDepart() {
var departHr = document.getElementById('departHr');
var departMin = document.getElementById('departMin');
for (var hr = 1; hr < 12; hr++) {
departHr.innerHTML += '<option value = "'+hr+'">' + hr + '</option>';
}
for (var i = 0; i < 12; i++) {
for (var j = 0; j < 60; j += 5) {
var x = i < 10 ? '0' + i : i;
var y = j < 10 ? '0' + j : j;
departMin.innerHTML += '<option value = "'+y+'">' + y + '</option>';
}
}
}
function formatAMPM() {
var date = new Date();
var hours = document.getElementById('departHr').value;
var minutes = document.getElementById('departMin').value;
var ampm = document.getElementById('timeFormat').value;
/*hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
minutes = minutes < 10 ? '0' + minutes : minutes;*/
console.log(hours);
if(ampm == 'pm'){
hours = 12 + parseInt(hours); }
var strTime = hours + ':' + minutes;
return strTime;
}
function route() {
var startLocation = document.getElementById('from').value;
var endLocation = document.getElementById('to').value;
var selectedMode = document.getElementById('modeOfTransportation').value;
var departure = formatAMPM();
var bits = departure.split(':');
var now = new Date();
var tzOffset = (now.getTimezoneOffset() + 60) * 60 * 1000;
var time = ($('#travelDate').val() != '') ? new Date($('#travelDate').val()) : new Date();
time.setHours(bits[0]);
time.setMinutes(bits[1]);
var ms = time.getTime() - tzOffset;
var departureTime = time;
var request = {
origin:startLocation,
destination:endLocation,
travelMode:google.maps.TravelMode[selectedMode],
provideRouteAlternatives:true,
transitOptions:{
departureTime:departureTime
}
};
console.log(request);
var panel = document.getElementById('panel');
panel.innerHTML = '';
directions.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
renderer.setDirections(response);
renderer.setMap(map);
renderer.setPanel(panel);
console.log(status);
} else {
renderer.setPanel(null);
alert(status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
Can somebody help me out with any reference or any code hint to it correct.
Thanks

You need to do something like this
//TranDep and TranArr have a valid date or ''
if ((TranDep == '') && (TranArr == '')) var Transit = null;
else {
if ((TranDep != '') && (TranArr != ''))
var Transit = {arrivalTime: new Date(TranArr), departureTime: new Date(TranDep)}
else {
if ((TranDep == '') && (TranArr != ''))
var Transit = {arrivalTime: new Date(TranArr)}
else
var Transit = {departureTime: new Date(TranDep)}
}
}
var Dir = new google.maps.DirectionsService();
var request = {
transitOptions: Transit,
......... // the others properties
};
If you specifies a arrivalTime, the departureTime will be ignored.
Regards

Related

Monty Hall Problem, resetGame is behaving weirdly

Basically the code (you guys probably can write it much cleaner than I) works perfectly on the first run through.
var doorSelection = ["a", "b", "c"];
var started = false;
var notPicked = true;
var notFinalChosen = true;
var wins = 0;
var losses = 0;
let roundComplete = false;
document.querySelector(".scoreCorrect").textContent = wins;
document.querySelector(".scoreWrong").textContent = losses;
document.querySelector(".heresText").classList.add("invisible");
document.querySelector(".startButton").addEventListener("click", function(){
document.querySelector(".startButton").classList.add("invisible");
mhGame();
started = true;
})
function mhGame(){
document.querySelector(".heresText").classList.remove("invisible");
var doorNumber = Math.floor(Math.random() * 3);
var doorPicker = doorSelection[doorNumber];
console.log(doorNumber + " " + doorPicker);
var doorContainer = document.querySelectorAll(".doorcontainer")[doorNumber];
var car = document.querySelector(".car");
car.classList.remove("invisible");
var doorContainerRect = doorContainer.getBoundingClientRect();
var carRect = car.getBoundingClientRect();
var carPosLeft = doorContainerRect.left - carRect.left + 50;
var carPosTop = doorContainerRect.top - carRect.top + 240;
car.style.left = carPosLeft + "px";
car.style.top = carPosTop + "px";
for(var i=0; i<3; i++){
document.querySelectorAll(".doorcontainer")[i].addEventListener("click", function(){
if (started && notPicked){
var firstPicked = this.textContent.trim();
console.log(firstPicked);
darkenDoor(firstPicked);
notPicked = false;
setTimeout(function(){
var doorsLeft = doorSelection.filter(function(door) {
return door !== firstPicked && door !== doorPicker;
});
var doorToReveal = doorsLeft[Math.floor(Math.random() * doorsLeft.length)];
console.log(doorToReveal);
hostReveal(doorToReveal);
document.querySelector(".heresText").classList.add("invisible");
document.querySelector(".switch").classList.remove("invisible");
document.querySelector(".stay").classList.remove("invisible");
for(var j=0; j<2; j++){
document.querySelectorAll(".buttonChoice div")[j].addEventListener("click", function(){
if(notFinalChosen){
var finalChoice = this.textContent;
if (finalChoice === "Switch"){
removeDarken(firstPicked);
var finalDoor = doorSelection.filter(function(newdoor){
return newdoor !== firstPicked && newdoor !== doorToReveal;
})
var openFinalChoice = "." + finalDoor + " .door";
document.querySelector(openFinalChoice).classList.add("invisible");
notFinalChosen = false;
console.log(finalDoor + ", " + doorPicker);
if(finalDoor == doorPicker){
document.querySelector(".heading").textContent = "You Win!";
wins++;
}
else{
document.querySelector(".heading").textContent = "Fail!";
losses++;
}
document.querySelector(".scoreCorrect").textContent = wins;
document.querySelector(".scoreWrong").textContent = losses;
}
else {
var openFinalChoice = "." + firstPicked + " .door";
removeDarken(firstPicked);
document.querySelector(openFinalChoice).classList.add("invisible");
notFinalChosen = false;
if(firstPicked === doorPicker){
document.querySelector(".heading").textContent = "You Win!";
wins++;
}
else{
document.querySelector(".heading").textContent = "Fail!";
losses++;
}
document.querySelector(".scoreCorrect").textContent = wins;
document.querySelector(".scoreWrong").textContent = losses;
}
}
resetGame();
})
}
}, 2000)
}
})
}
}
function darkenDoor(varsTemp){
var doorVars = document.querySelector("." + varsTemp);
doorVars.classList.add("darken");
}
function removeDarken(varsTemp2){
var doorVars2 = document.querySelector("." + varsTemp2);
doorVars2.classList.remove("darken");
}
function hostReveal(revealed){
var revealedDoor ="." + revealed + " .door";
document.querySelector(revealedDoor).classList.add("invisible");
}
function resetGame(){
setTimeout(function(){
console.log(doorSelection);
roundComplete = false;
started = false;
notPicked = true;
notFinalChosen = true;
document.querySelector(".switch").classList.add("invisible");
document.querySelector(".stay").classList.add("invisible");
document.querySelector(".car").classList.add("invisible");
document.querySelector(".car").style.left = 0 + "px";
document.querySelector(".car").style.top = 0 + "px";
document.querySelector(".startButton").classList.remove("invisible");
doorPicker = null;
doorNumber = null;
doorToReveal = null;
finalChoice = null;
finalDoor = null;
doorsLeft = null;
openFinalChoice = null;
for(var m=0; m<doorSelection.length; m++){
document.querySelectorAll(".door")[m].classList.remove("invisible");
}
document.querySelector(".heading").textContent = "Welcome to the Monty Hall Game!";
}, 3000)
}
But once I call resetGame(); and I've tried many different things including a true/false statement to trigger it, and placing it in different places (I have no idea what I'm doing with this part now), it opens the door with the car in it on the second round, then doesn't remove the "darken" by the third round, and by maybe the 4th or 5th round, the "start" button stops working as a whole.

I need to merge text of 2 lines depending on their x1,x2,y1 and y2 values

I am working on HOCR format of tesseract OCR, i am stuck when i have a text based on multiple lines. HOCR Format contains bounding box for every word and multi-line text issue can be solve if i merge all the texts of words if they have same x1.
I am using java script for this task.
This is sample image i am using, due to privacy issues i have masked the confidential data.
Here is my code, i know its not well written so i am open to any cretic.
//merging 2 lines(currentLine, previousLine)
function merge2lines(ocrLine, ocrPrevLine)
{
var stringOutCome="";
var stringOutComeOuterLine="";
//get all the words in this line
var lineItems = $(ocrLine).children();
var CoordinatesOfItemForFirstLineOfSecondLine='';
var textOfItemForFirstLineOfSecondLine='';
var prevLineItems = $(ocrPrevLine).children();
//loop over all words
var lineItemsCount = lineItems.length;
for (var i=0;i<lineItemsCount;i++)
{
var stringInfo = lineItems[i].textContent;
if (typeof stringInfo === 'string' && stringInfo.trim().length > 0)
{
var str = lineItems[i].title;
var title = (str).split(";");
var firstSpace = title[0].indexOf(" ");
var newStr = title[0].slice(firstSpace);
var coordinates = newStr.split(' ');
if(i==0){
CoordinatesOfItemForFirstWordOfSecondLine = coordinates;
textOfItemForFirstWordOfSecondLine = lineItems[i].textContent;
}
//check and remove text
if(! stringOutComeOuterLine.includes(lineItems[i].textContent))
{
stringOutComeOuterLine = stringOutComeOuterLine+" "+lineItems[i].textContent;
}
// stringOutComeOuterLine = stringOutComeOuterLine+" "+lineItems[i].textContent;
if(i<lineItemsCount-1)
{
var str2 = lineItems[i+1].title;
var title2 = (str2).split(";");
var firstSpace2 = title2[0].indexOf(" ");
var newStr2 = title2[0].slice(firstSpace2);
var coordinates2 = newStr2.split(' ');
var differenceOfCordinates = Math.abs(coordinates[3] - coordinates2[1]);
// console.log(lineItems[i].textContent,+" pakistan <- -> Block B",lineItems[i+1].textContent," DIfference: ",differenceOfCordinates);
if(parseInt(differenceOfCordinates) < 100)
{
stringOutComeOuterLine = stringOutComeOuterLine+" "+lineItems[i+1].textContent;
}
else{
var check = true;
// check previousLineitem x
for (var j=0;j<prevLineItems.length;j++)
{
var prevString = prevLineItems[j].textContent;
if (typeof prevString === 'string' && prevString.trim().length > 0)
{
var previousLineTitle = prevLineItems[j].title;
var splittedPreviousLineTitle = (previousLineTitle).split(";");
var previousLineItemFirstSpace = splittedPreviousLineTitle[0].indexOf(" ");
var previousLineItemCoordinates = splittedPreviousLineTitle[0].slice(previousLineItemFirstSpace);
var previousLineItemCoordinatesList = previousLineItemCoordinates.split(' ');
var stringDifference = Math.abs(previousLineItemCoordinatesList[1] - CoordinatesOfItemForFirstWordOfSecondLine[1]);
// console.log(prevLineItems[j].textContent,"->",textOfItemForFirstWordOfSecondLine,"Diff:", stringDifference);
if(stringDifference < 20 && check == true)
{
check = false;
// stringOutComeOuterLine = prevLineItems[j].textContent +" "+ stringOutComeOuterLine;
stringOutCome = stringOutCome+" "+prevLineItems[j].textContent;
}
else{
if(j<prevLineItems.length-1)
{
console.log(prevLineItems[j+1].textContent);
var previousLineTitleNext = prevLineItems[j+1].title;
var splittedPreviousLineTitleNext = (previousLineTitleNext).split(";");
var previousLineItemFirstSpaceNext = splittedPreviousLineTitleNext[0].indexOf(" ");
var previousLineItemCoordinatesNext = splittedPreviousLineTitleNext[0].slice(previousLineItemFirstSpaceNext);
var previousLineItemCoordinatesListNext = previousLineItemCoordinatesNext.split(' ');
var previousLineDiff = Math.abs(previousLineItemCoordinatesList[3] - previousLineItemCoordinatesListNext[1]);
// console.log("Previous Item",prevLineItems[j].textContent,"->Next Item:",prevLineItems[j+1].textContent,"previousLineDiff:", previousLineDiff);
// console.log("<br> left coordinat: ",previousLineItemCoordinatesList[3]," Right Item: ",previousLineItemCoordinatesListNext[1]);
if(previousLineDiff < 120){
stringOutCome = stringOutCome+" "+prevLineItems[j].textContent;//+" "+prevLineItems[j+1].textContent;
// console.log(stringOutCome,"previousLineDiff:", previousLineDiff);
}
else{
// stringOutComeOuterLine = prevLineItems[j].textContent +" "+ stringOutComeOuterLine;
stringOutCome = stringOutCome +" "+stringOutComeOuterLine;
}
}else{
// console.log("Else Part");
stringOutComeOuterLine = stringOutCome +" "+stringOutComeOuterLine;
}
}
// console.log(stringOutComeOuterLine);
}
}
}
}else{
// stringOutComeOuterLine = lineItems[i].textContent+" "+stringOutComeOuterLine;
// check previousLineitem x
for (var j=0;j<prevLineItems.length;j++)
{
var prevString = prevLineItems[j].textContent;
if (typeof prevString === 'string' && prevString.trim().length > 0)
{
var previousLineTitle = prevLineItems[j].title;
var splittedPreviousLineTitle = (previousLineTitle).split(";");
var previousLineItemFirstSpace = splittedPreviousLineTitle[0].indexOf(" ");
var previousLineItemCoordinates = splittedPreviousLineTitle[0].slice(previousLineItemFirstSpace);
var previousLineItemCoordinatesList = previousLineItemCoordinates.split(' ');
// console.log(prevLineItems[j].textContent,"->",textOfItemForFirstWordOfSecondLine,"Diff:", stringDifference);
if(j<prevLineItems.length-1)
{
console.log(prevLineItems[j+1].textContent);
var previousLineTitleNext = prevLineItems[j+1].title;
var splittedPreviousLineTitleNext = (previousLineTitleNext).split(";");
var previousLineItemFirstSpaceNext = splittedPreviousLineTitleNext[0].indexOf(" ");
var previousLineItemCoordinatesNext = splittedPreviousLineTitleNext[0].slice(previousLineItemFirstSpaceNext);
var previousLineItemCoordinatesListNext = previousLineItemCoordinatesNext.split(' ');
var previousLineDiff = Math.abs(previousLineItemCoordinatesList[3] - previousLineItemCoordinatesListNext[1]);
// console.log("Previous Item",prevLineItems[j].textContent,"->Next Item:",prevLineItems[j+1].textContent,"previousLineDiff:", previousLineDiff);
// console.log("<br> left coordinat: ",previousLineItemCoordinatesList[3]," Right Item: ",previousLineItemCoordinatesListNext[1]);
if(previousLineDiff < 120){
stringOutCome = stringOutCome+" "+prevLineItems[j].textContent;//+" "+prevLineItems[j+1].textContent;
// console.log(stringOutCome,"previousLineDiff:", previousLineDiff);
}
else{
// stringOutComeOuterLine = prevLineItems[j].textContent +" "+ stringOutComeOuterLine;
stringOutCome = stringOutCome +" "+stringOutComeOuterLine;
}
}else{
// console.log("Else Part");
stringOutComeOuterLine = stringOutCome +" "+stringOutComeOuterLine;
}
// console.log(stringOutComeOuterLine);
}
}
}
}
}
console.log(stringOutComeOuterLine);
return stringOutComeOuterLine;
}

angular fullcalendar loading time

I'm currently using "FullCalendar" for angular JS. Although it works fine, it takes around 15 seconds to load the calendar even though the data it coming from the php file instantly, does anyone have experience with fullcalendar and could help me optimize my script or see where I may be going wrong? Here is my calendar function :
$scope.refreshCal = function() {
$scope.colors = [];
var getAppointmentsurl = './dbscripts/getAppointments.php';
$http({ method: 'GET', url: getAppointmentsurl }).success(function(data) {
$scope.apnts = data;
angular.forEach(data, function(item, key) {
if ($scope.inArray(item.username)) {
$scope.colors.push(item.colorcode);
$scope.consultantsApps = data;
var appdate = new Date(moment(item.Appointment).format("YYYY-MM-DD"));
var appdatee = moment(item.Appointment, "YYYY-MM-DD");
var newtime = moment(item.txtTime).format("hh:mm a");
var time = newtime;
var hours = Number(time.match(/^(\d+)/)[1]);
var minutes = Number(time.match(/:(\d+)/)[1]);
var AMPM = time.match(/\s(.*)$/)[1];
if (AMPM == "pm" && hours < 12) hours = hours + 12;
if (AMPM == "am" && hours == 12) hours = hours - 12;
var sHours = hours.toString();
var sMinutes = minutes.toString();
if (hours < 10) sHours = "0" + sHours;
if (minutes < 10) sMinutes = "0" + sMinutes;
var y = appdatee.get("year");
var m = appdatee.get("month");
var d = appdatee.get("date");
var h = sHours;
var min = sMinutes;
var info = item.Company + ", " + item.Town + ", " + item.PostCode;
// var event= {title: item.Ref,color:item.colorcode,start: new Date(apnt.get("year"), apnt.get("month"), apnt.get("date"), t.get('hour'), t.get('minute')),end: new Date(apnt.get("year"), apnt.get("month"), apnt.get("date"), t.get('hour') + 1, t.get('minute')),allDay: false}
var event = {
ref: item.Ref,
cons: item.username,
title: (info),
color: item.colorcode,
start: new Date(y, m, d, h, min),
end: new Date(y, m, d, h, min),
allDay: false
};
$scope.events.push(event);
}
$scope.eventSources = [$scope.events];
})
});
};
Most of it is just formatting dates and times but other than that it's just looping through the list of appointments, adding them to $scope.events and pushing it to the calendar.
Thanks for your help!

Google maps api v3 calculate mileage by state

I'm searching for a way to calculate mileage by US State based on an origin, waypoints and destination of a route using Google Maps API v3.
I have tried using Googles Distance Matrix API but this it is calculating the distance between 2 points, which is good, but I need the break down for miles traveled for each State. For taxes purposes (IFTA reports for transportation).
I've done a lot of googling and looked through the documentation but I'm not seeing anything that calculate the mileage per State.
I know how to use Google maps and I know this is possible since I saw it on one video. There is no code I can show because I have no idea how to do it. Any thoughts?
Useful links I have found:
How to Draw Routes and Calculate Route Time and Distance on the Fly Using Google Map API V3 http://www.c-sharpcorner.com/UploadFile/8911c4/how-to-draw-routes-and-calculate-route-time-and-distance-on/
How to Build a Distance Finder with Google Maps API http://www.1stwebdesigner.com/distance-finder-google-maps-api/
Below is a fully functional implementation that uses the Google Maps Javascript API. All you need to add is your own Maps API Key. As noted in the posts referenced above, Google Maps throttles requests at an asymptotic rate, and thus, the longer the route, the longer it will take to calculate. To give a ballpark, a route from New Haven CT to the NJ/PA border takes approximately 5 minutes. A trip from New Haven CT to Los Angeles takes 45 minutes to index. One other note: There are a few state borders that run through bodies of water. Google considers these to be not located in any state, and so reports undefined as the state name. These sections are obviously only a few tenths of a mile in most cases, but I felt I should mention it just to clarify what is going on when that happens.
UPDATED:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=<YOUR-KEY-HERE>"></script>
<div id="map" style="height:400px"></div>
<div id="status"></div>
<div id="results" style="height:400px"><b>Results:</b></div>
<script>
var directionsRequest = {
origin: "New York, NY", //default
destination: "Los Angeles, LA", //default
optimizeWaypoints: true,
provideRouteAlternatives: false,
travelMode: google.maps.TravelMode.DRIVING,
drivingOptions: {
departureTime: new Date(),
trafficModel: google.maps.TrafficModel.PESSIMISTIC
}
};
directionsRequest.origin = prompt("Enter your starting address");
directionsRequest.destination = prompt("Enter your destination address");
var starttime = new Date();
var geocoder = new google.maps.Geocoder();
var startState;
var currentState;
var routeData;
var index = 0;
var stateChangeSteps = [];
var borderLatLngs = {};
var startLatLng;
var endLatLng;
directionsService = new google.maps.DirectionsService();
directionsService.route(directionsRequest, init);
function init(data){
routeData = data;
displayRoute();
startLatLng = data.routes[0].legs[0].start_location;
endLatLng = data.routes[0].legs[0].end_location;
geocoder.geocode({location:data.routes[0].legs[0].start_location}, assignInitialState)
}
function assignInitialState(data){
startState = getState(data);
currentState = startState;
compileStates(routeData);
}
function getState(data){
for (var i = 0; i < data.length; i++) {
if (data[i].types[0] === "administrative_area_level_1") {
var state = data[i].address_components[0].short_name;
}
}
return state;
}
function compileStates(data, this_index){
if(typeof(this_index) == "undefined"){
index = 1;
geocoder.geocode({location:data.routes[0].legs[0].steps[0].start_location}, compileStatesReceiver);
}else{
if(index >= data.routes[0].legs[0].steps.length){
console.log(stateChangeSteps);
index = 0;
startBinarySearch();
return;
}
setTimeout(function(){
geocoder.geocode({location:data.routes[0].legs[0].steps[index].start_location}, compileStatesReceiver);
$("#status").html("Indexing Step "+index+"... ("+data.routes[0].legs[0].steps.length+" Steps Total)");
}, 3000)
}
}
function compileStatesReceiver(response){
state = getState(response);
console.log(state);
if(state != currentState){
currentState = state;
stateChangeSteps.push(index-1);
}
index++;
compileStates(routeData, index);
}
var stepIndex = 0;
var stepStates = [];
var binaryCurrentState = "";
var stepNextState;
var stepEndState;
var step;
var myLatLng = {lat:39.8282, lng:-98.5795};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
function displayRoute() {
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
directionsDisplay.setDirections(routeData);
}
var orderedLatLngs = [];
function startBinarySearch(iterating){
if(stepIndex >= stateChangeSteps.length){
for(step in borderLatLngs){
for(state in borderLatLngs[step]){
for(statename in borderLatLngs[step][state]){
$("#results").append("<br>Cross into "+statename+" at "+JSON.stringify(borderLatLngs[step][state][statename], null, 4));
orderedLatLngs.push([borderLatLngs[step][state][statename], statename]);
}
}
}
compileMiles(true);
return;
}
step = routeData.routes[0].legs[0].steps[stateChangeSteps[stepIndex]];
console.log("Looking at step "+stateChangeSteps[stepIndex]);
borderLatLngs[stepIndex] = {};
if(!iterating){
binaryCurrentState = startState;
}
geocoder.geocode({location:step.end_location},
function(data){
if(data === null){
setTimeout(function(){startBinarySearch(true);}, 6000);
}else{
stepNextState = getState(data);
stepEndState = stepNextState;
binaryStage2(true);
}
});
}
var minIndex;
var maxIndex;
var currentIndex;
function binaryStage2(init){
if (typeof(init) != "undefined"){
minIndex = 0;
maxIndex = step.path.length - 1;
}
if((maxIndex-minIndex)<2){
borderLatLngs[stepIndex][maxIndex]={};
borderLatLngs[stepIndex][maxIndex][stepNextState]=step.path[maxIndex];
var marker = new google.maps.Marker({
position: borderLatLngs[stepIndex][maxIndex][stepNextState],
map: map,
});
if(stepNextState != stepEndState){
minIndex = maxIndex;
maxIndex = step.path.length - 1;
binaryCurrentState = stepNextState;
stepNextState = stepEndState;
}else{
stepIndex++;
binaryCurrentState = stepNextState;
startBinarySearch(true);
return;
}
}
console.log("Index starts: "+minIndex+" "+maxIndex);
console.log("current state is "+binaryCurrentState);
console.log("next state is "+ stepNextState);
console.log("end state is "+ stepEndState);
currentIndex = Math.floor((minIndex+maxIndex)/2);
setTimeout(function(){
geocoder.geocode({location:step.path[currentIndex]}, binaryStage2Reciever);
$("#status").html("Searching for division between "+binaryCurrentState+" and "+stepNextState+" between indexes "+minIndex+" and "+maxIndex+"...")
}, 3000);
}
function binaryStage2Reciever(response){
if(response === null){
setTimeout(binaryStage2, 6000);
}else{
state = getState(response)
if(state == binaryCurrentState){
minIndex = currentIndex +1;
}else{
maxIndex = currentIndex - 1
if(state != stepNextState){
stepNextState = state;
}
}
binaryStage2();
}
}
var currentStartPoint;
var compileMilesIndex = 0;
var stateMiles = {};
var trueState;
function compileMiles(init){
if(typeof(init)!= "undefined"){
currentStartPoint = startLatLng;
trueState = startState;
}
if(compileMilesIndex == orderedLatLngs.length){
directionsRequest.destination = endLatLng;
}else{
directionsRequest.destination = orderedLatLngs[compileMilesIndex][0];
}
directionsRequest.origin = currentStartPoint;
currentStartPoint = directionsRequest.destination;
directionsService.route(directionsRequest, compileMilesReciever)
}
function compileMilesReciever(data){
if(data===null){
setTimeout(compileMiles, 6000);
}else{
if(compileMilesIndex == orderedLatLngs.length){
stateMiles[stepEndState]=data.routes[0].legs[0].distance["text"];
$("#results").append("<br><br><b>Distances Traveled</b>");
for(state in stateMiles){
$("#results").append("<br>"+state+": "+stateMiles[state]);
}
var endtime = new Date();
totaltime = endtime - starttime;
$("#results").append("<br><br>Operation took "+Math.floor(totaltime/60000)+" minute(s) and "+(totaltime%60000)/1000+" second(s) to run.");
return;
}else{
stateMiles[trueState]=data.routes[0].legs[0].distance["text"];
}
trueState = orderedLatLngs[compileMilesIndex][1];
compileMilesIndex++;
setTimeout(compileMiles, 3000);
}
}
</script>
</script>

Google Apps Script: Server encountered an error. Try again later

I am stuck.. Error is thrown # Line 63 and sometimes at line 50. Both using the appendTableRow() method. I can't find anything wrong.
row3.appendTableCell(entryDesc)
Link to generated file: Link
Execution Transcript: Link
I am new so if you notice any "bad practices" feel free to aim a finger.
// Import data from the Calendar to the timesheet document
function importDataToTS (dateStart,dateFinish,doc) {
if (!dateStart) {
var dateStart = new Date('January 1, 2014');
}
var cal = CalendarApp.getCalendarById('0k2s9lfibn50scj41gcuurovck#group.calendar.google.com')
var events = cal.getEvents(dateStart, dateFinish);
var oldDate = new Date(dateStart.getFullYear(), dateStart.getMonth(), dateStart.getDate() - 1);
var paragraph = "";
var totalHoursWorked = 0
// START --- Text element styles
// Date
var entryDateStyle = {};
entryDateStyle[DocumentApp.Attribute.BOLD] = true;
entryDateStyle[DocumentApp.Attribute.FONT_SIZE] = 18;
// Title
var entryTitleStyle = {};
entryTitleStyle[DocumentApp.Attribute.FONT_SIZE] = 14;
// entryTimes
var entryTimesStyle = {};
entryTimesStyle[DocumentApp.Attribute.BOLD] = true;
entryTimesStyle[DocumentApp.Attribute.FONT_SIZE] = 12;
// entryDescription
var entryDescriptionStyle = {};
entryDescriptionStyle[DocumentApp.Attribute.ITALIC] = true;
entryDescriptionStyle[DocumentApp.Attribute.FONT_SIZE] = 10;
// END --- Text element styles
var entriesTable = doc.appendTable();
Logger.log(entriesTable.getType());
for (var i = 0; i in events; i++) {
var entryDate = events[i].getStartTime();
if (i > 0) {
oldDate = (events[i-1].getStartTime());
}
// If it's a new day add a full width cell
if (entryDate.getDate() > oldDate.getDate()) {
var row1 = entriesTable.appendTableRow();
row1.appendTableCell(shortDate(entryDate,4));
//.setAttributes(entryDateStyle);
}
// Add title, start/end times & hours worked
// Add title, start/end times & hours worked
var entryTitle = events[i].getTitle();
Logger.log(i + ": " + entryTitle);
var entryTimes = shortTime(events[i].getStartTime(),2) + " - " + shortTime(events[i].getEndTime(),2);
Logger.log(i + ": " + entryTimes);
var entryHoursWorked = ((events[i].getEndTime() - events[i].getStartTime())/(1000*60*60)%24) + "hr(s)";
Logger.log(i + ": " + entryHoursWorked);
var row2 = entriesTable.appendTableRow();
row2.appendTableCell(entryTitle);
//.setAttributes(entryTitleStyle);
row2.appendTableCell(entryTimes + "\t\t" + entryHoursWorked);
//.setAttributes(entryTimesStyle);
// Add entry description
var entryDesc = (events[i].getDescription().length > 1) ? events[i].getDescription().toString() : "";
if (entryDesc.length > 1) {
var row3 = entriesTable.appendTableRow();
row3.appendTableCell();
row3.appendTableCell(entryDesc);
//.setAttributes(entryDescriptionStyle);
}
totalHoursWorked += entryHoursWorked;
if (i === (events.length - 1)) {
var lastRow = entriesTable.appendTableRow();
lastRow.appendTableCell("Total Hours: " + totalHoursWorked);
}
}
for (var i = 0; i in entriesTable; i++) {
for (var j = 0; j in entriesTable[i]; j++) {
Logger.log(i + ":" + j + " " + entriesTable[i][j].toString());
}
}
doc.appendTable(entriesTable);
}
shortDate() && shorttTime()
function shortDate(date,n) {
// Returns a date object as "MMMDD";
if (date) {
switch (n) {
case 1:
//Jul6
return Utilities.formatDate(date, "EST", "MMMdd")
break;
case 2:
//Jul 6
return Utilities.formatDate(date, "EST", "MMM dd")
break;
case 3:
//July 6
return Utilities.formatDate(date, "EST", "MMMM dd")
break;
case 4:
return Utilities.formatDate(date, "EST", "EEE, MMM dd")
break;
default:
//Full Date unchanged
return date;
}
}
}
function shortTime(date) {
//Returns time string formatted as "hh:mm"am/pm
//Still needs to be updated with Utilities.formatDate
if (date) {
var hours = (date.getHours() > 12) ? (date.getHours() - 12) : date.getHours();
var ampm = (date.getHours() > 12) ? "pm" : "am";
var minutes = (date.getMinutes() == 0) ? "00" : date.getMinutes();
var time = hours + ":" + minutes + ampm
return time.toString();
}
}
I found a solution, it appears that: body.appendTableCell(); doesn't handle line breaks "\n". When the script was importing a multi-line event description from the calendar I would get a "server error" message. Adding split('\n') to the description row solved the problem. This worked: body.appendTableCell(data).split("\n");
Finished code:
var entryDesc = (events[i].getDescription().length > 1) ? events[i].getDescription() : "";
if (entryDesc) {
var row3 = entriesTable.appendTableRow();
row3.appendTableCell("");
row3.appendTableCell(entryDesc.split("\n"))
.setAttributes(entryDescriptionStyle);
}
I don't have a complete answer but I thought it might be interesting in the mean time to show a version that works without the event description.
I changed the calculation of total time that didn't work either.
Code can be tested on any default calendar using test function.
function test(){
//dateStart,dateFinish,doc
var doc = DocumentApp.getActiveDocument();
var dateStart = new Date('January 1, 2014');
var dateFinish = new Date('April 1, 2014')
importDataToTS (dateStart,dateFinish,doc);
}
function importDataToTS (dateStart,dateFinish,doc) {
if (!dateStart) {
var dateStart = new Date('January 1, 2014');
}
var cal = CalendarApp.getDefaultCalendar();
var events = cal.getEvents(dateStart, dateFinish);
var oldDate = new Date(dateStart.getFullYear(), dateStart.getMonth(), dateStart.getDate() - 1);
var paragraph = "";
var totalHoursWorked = 0
// START --- Text element styles
// Date
var entryDateStyle = {};
entryDateStyle[DocumentApp.Attribute.BOLD] = true;
entryDateStyle[DocumentApp.Attribute.FONT_SIZE] = 18;
// Title
var entryTitleStyle = {};
entryTitleStyle[DocumentApp.Attribute.FONT_SIZE] = 14;
// entryTimes
var entryTimesStyle = {};
entryTimesStyle[DocumentApp.Attribute.BOLD] = true;
entryTimesStyle[DocumentApp.Attribute.FONT_SIZE] = 12;
// entryDescription
var entryDescriptionStyle = {};
entryDescriptionStyle[DocumentApp.Attribute.ITALIC] = true;
entryDescriptionStyle[DocumentApp.Attribute.FONT_SIZE] = 10;
// END --- Text element styles
var entriesTable = doc.appendTable();
Logger.log('events.length = '+events.length);
for (var i = 0; i <events.length; i++) {
var entryDate = events[i].getStartTime();
if (i > 0) {
oldDate = (events[i-1].getStartTime());
}
Logger.log('i = '+i);
// If it's a new day add a full width cell
if (entryDate.getDate() > oldDate.getDate()) {
var row1 = entriesTable.appendTableRow();
row1.appendTableCell(shortDate(entryDate,4))
.setAttributes(entryDateStyle);
}
// Add title, start/end times & hours worked
var entryTitle = events[i].getTitle();
var entryTimes = shortTime(events[i].getStartTime(),2) + " - " + shortTime(events[i].getEndTime(),2);
var entryHoursWorked = (events[i].getEndTime().getTime() - events[i].getStartTime().getTime())/(1000*60*60) + "hr(s)";
var row2 = entriesTable.appendTableRow();
row2.appendTableCell(entryTitle)
.setAttributes(entryTitleStyle);
row2.appendTableCell(entryTimes + "\t\t" + entryHoursWorked)
.setAttributes(entryTimesStyle);
// Add entry description
var entryDesc = (events[i].getDescription().length > 2) ? events[i].getDescription() : "";
totalHoursWorked += Number(entryHoursWorked.replace(/\D/g,''));
if (i === (events.length - 1)) {
var lastRow = entriesTable.appendTableRow();
lastRow.appendTableCell("Total Hours: " + totalHoursWorked+' Hours');
}
}
for (var i = 0; i in entriesTable; i++) {
for (var j = 0; j in entriesTable[i]; j++) {
Logger.log(i + ":" + j + " " + entriesTable[i][j].toString());
}
}
doc.saveAndClose();
}