-
Notifications
You must be signed in to change notification settings - Fork 0
/
extras_gas
181 lines (169 loc) · 5.98 KB
/
extras_gas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
function onOpen(e) {
var spreadsheet = SpreadsheetApp.getActive();
var ui =
SpreadsheetApp.getUi()
.createMenu('Extras')
.addItem('Generate step-by-step...', 'generateaStepByStep_')
.addItem('Prepare sheet...', 'prepareSheet_')
.addToUi();
}
/** A custom function that converts meters to miles.
*
* @param {Number} meters The distance in meters.
* @return {Number} The distance in miles.
*/
function metersToMiles(meters) {
if (typeof meters != 'number') {
return null;
}
return meters / 1000 * 0.621371;
}
/**
* A custom function that gets the driving distance between two addresses.
*
* @param {String} origin The starting address.
* @param {String} destination The ending address.
* @return {Number} The distance in meters.
*/
function drivingDistance(origin, destination) {
var directions = getDirections_(origin, destination);
return directions.routes[0].legs[0].distance.value;
}
/**
* A function that adds headers and some initial data to the spreadsheet.
*/
function prepareSheet_() {
var sheet = SpreadsheetApp.getActiveSheet().showSheet('Travel');
var headers = [
'Start Address',
'End Address',
'Driving Distance (meters)',
'Driving Distance (miles)'];
var initialData = [
'1413 East Naomi Street Indianapolis, IN 46203'];
sheet.getRange('A1:D1').setValues([headers]).setFontWeight('bold');
sheet.getRange('A2:B2').setValues([initialData]);
sheet.setFrozenRows(1);
sheet.autoResizeColumns(1, 4);
}
/**
* Creates a new sheet containing step-by-step directions between the two
* addresses on the "Directions" sheet that the user selected.
*/
function generateStepByStep_() {
var spreadsheet = SpreadsheetApp.getActive();
var travelSheet = spreadsheet.getSheetByName('Travel');
travelSheet.activate();
// Prompt the user for a row number.
var selectedRow = Browser.inputBox('Generate step-by-step',
'Please enter the row number of the addresses to use' +
' (for example, "2"):',
Browser.Buttons.OK_CANCEL);
if (selectedRow == 'cancel') {
return;
}
var rowNumber = Number(selectedRow);
if (isNaN(rowNumber) || rowNumber < 2 ||
rowNumber > travelSheet.getLastRow()) {
Browser.msgBox('Error',
Utilities.formatString('Row "%s" is not valid.', selectedRow),
Browser.Buttons.OK);
return;
}
// Retrieve the addresses in that row.
var row = travelSheet.getRange(rowNumber, 1, 1, 2);
var rowValues = row.getValues();
var origin = rowValues[0][0];
var destination = rowValues[0][1];
if (!origin || !destination) {
Browser.msgBox('Error', 'Row does not contain two addresses.',
Browser.Buttons.OK);
return;
}
// Get the raw directions information.
var directions = getDirections_(origin, destination);
// Create a new sheet and append the steps in the directions.
var sheetName = 'Driving Directions';
var directionsSheet = spreadsheet.getSheetByName(sheetName);
if (directionsSheet) {
directionsSheet.clear();
directionsSheet.activate();
} else {
directionsSheet =
spreadsheet.insertSheet(sheetName, spreadsheet.getNumSheets());
}
var sheetTitle = Utilities.formatString('Driving Directions from %s to %s',
origin, destination);
var headers = [
[sheetTitle, '', ''],
['Step', 'Distance (Meters)', 'Distance (Miles)']
];
var newRows = [];
for (var i = 0; i < directions.routes[0].legs[0].steps.length; i++) {
var step = directions.routes[0].legs[0].steps[i];
// Remove HTML tags from the instructions.
var instructions = step.html_instructions.replace(/<br>|<div.*?>/g, '\n')
.replace(/<.*?>/g, '');
newRows.push([
instructions,
step.distance.value
]);
}
directionsSheet.getRange(1, 1, headers.length, 3).setValues(headers);
directionsSheet.getRange(headers.length + 1, 1, newRows.length, 2)
.setValues(newRows);
directionsSheet.getRange(headers.length + 1, 3, newRows.length, 1)
.setFormulaR1C1('=METERSTOMILES(R[0]C[-1])');
// Format the new sheet.
directionsSheet.getRange('A1:C1').merge().setBackground('#ddddee');
directionsSheet.getRange('A1:2').setFontWeight('bold');
directionsSheet.setColumnWidth(1, 500);
directionsSheet.getRange('B2:C').setVerticalAlignment('top');
directionsSheet.getRange('C2:C').setNumberFormat('0.00');
var stepsRange = directionsSheet.getDataRange()
.offset(2, 0, directionsSheet.getLastRow() - 2);
setAlternatingRowBackgroundColors_(stepsRange, '#ffffff', '#eeeeee');
directionsSheet.setFrozenRows(2);
SpreadsheetApp.flush();
}
/**
* Sets the background colors for alternating rows within the range.
* @param {Range} range The range to change the background colors of.
* @param {string} oddColor The color to apply to odd rows (relative to the
* start of the range).
* @param {string} evenColor The color to apply to even rows (relative to the
* start of the range).
*/
function setAlternatingRowBackgroundColors_(range, oddColor, evenColor) {
var backgrounds = [];
for (var row = 1; row <= range.getNumRows(); row++) {
var rowBackgrounds = [];
for (var column = 1; column <= range.getNumColumns(); column++) {
if (row % 2 == 0) {
rowBackgrounds.push(evenColor);
} else {
rowBackgrounds.push(oddColor);
}
}
backgrounds.push(rowBackgrounds);
}
range.setBackgrounds(backgrounds);
}
/**
* A shared helper function used to obtain the full set of directions
* information between two addresses. Uses the Apps Script Maps Service.
*
* @param {String} origin The starting address.
* @param {String} destination The ending address.
* @return {Object} The directions response object.
*/
function getDirections_(origin, destination) {
var directionFinder = Maps.newDirectionFinder();
directionFinder.setOrigin(origin);
directionFinder.setDestination(destination);
var directions = directionFinder.getDirections();
if (directions.status !== 'OK') {
throw directions.error_message;
}
return directions;
}