-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbigTen.html
More file actions
214 lines (177 loc) · 6.73 KB
/
bigTen.html
File metadata and controls
214 lines (177 loc) · 6.73 KB
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
<!DOCTYPE html>
<html>
<!--from: https://cloud.google.com/blog/products/maps-platform/how-use-distance-matrix-api -->
<head>
<style> /* Set the size of the div element that contains the map */
#map {
height: 600px; /* The height is 400 pixels */
width: 800px; /* The width is 600 pixels */
}
#matrix {
color:green;
font-size: 20px;
font-weight: bold;
}
</style>
</head>
<body>
<div id="progress">
<p>gathering data...</p>
</div>
<!--The div element for the map -->
<div id="map">
</div>
<!--The div element for the distance matrix -->
<div id="table">
</div>
<!--The pre element for the Java literal for city objects -->
<pre id="citiesLatLongLiteral">
</pre>
<!--The pre element for the Java literal for the distance matrix -->
<pre id="distanceLiteral">
</pre>
<!--The pre element for the Java constants for the min/max lat/long -->
<pre id="latLongConstants">
</pre>
<script>
// specify your API key here as well as at the bottom of the file
// DO NOT commit your API key to GitHub as it could be exposed to others!
const GOOGLE_API_KEY = "!!! replace with your key !!!";
// initialize and add the map
let map;
async function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {lat: 41, lng: -86}
});
// display the new bounds of the map as it is updated
map.bounds_changed = () => {
let bounds = map.getBounds();
console.log(bounds.toString());
formatLatLongConstants(bounds, document.querySelector("#latLongConstants"));
};
// Feel free to replace the Big 10 cities with your own list of cities.
// NB: the Distance Matrix Services limits queries to a maximum of 25 cities
let cities = [
"Evanston, IL", // Northwestern
"Bloomington, IN", // Indiana
"College Park, MD", // Maryland
"Ann Arbor, MI", // Michigan
"East Lansing, MI", // Michigan State
"Columbus, OH", // Ohio State
"State College, PA", // Penn State
"New Brunswick, NJ", // Rutgers
"Champaign, IL", // Illinois
"Iowa City, IA", // Iowa
"Minneapolis, MN", // Minnesota
"Lincoln, NE", // Nebraska
"West Lafayette, IN", // Purdue
"Madison, WI" // Wisconsin
];
// encode the cities such that they can be included as parameters in the URL
let citiesEncoded = cities.map( city => {
return city.replace(", ", "+").replace(" ", "%20");
});
// preinitialize the array since it is critical that the elements in this array
// correspond to those in the cities array
let citiesLatLong = Array.from({length : cities.length});
// should use google.maps.Geocoder instead???
citiesEncoded.forEach((cityEncoded, index) => {
fetch("https://maps.googleapis.com/maps/api/geocode/json?address=" + cityEncoded +
"&key=" + GOOGLE_API_KEY).then(response => response.json()).then(data => {
// location of one city
let position = data.results[0].geometry.location;
citiesLatLong[index] = position;
// create marker for a city
let mk = new google.maps.Marker({position: position, map: map});
formatLatLongLiteral(citiesLatLong, cities, document.querySelector("#citiesLatLongLiteral"));
});
});
// NB: the Distance Matrix Service limits queries to a maximum of 100 elements; so,
// invoke it multiple times as necessary and combine the results
let maxOrigins = Math.floor(100 / cities.length);
let distanceMatrix = { "rows": [] };
const service = new google.maps.DistanceMatrixService();
for (let i = 0; i < cities.length; i += maxOrigins) {
const matrixOptions = {
origins: cities.slice(i, Math.min(cities.length, i + maxOrigins)),
destinations: cities,
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL
};
service.getDistanceMatrix(matrixOptions, (response, status) => {
if (status !== "OK") {
console.log("Error with distance matrix: " + status);
// by decrementing i, we are basically retrying the request...
i -= maxOrigins;
}
else {
distanceMatrix.rows = distanceMatrix.rows.concat(response.rows);
formatTable(cities, distanceMatrix, document.querySelector("#table"));
formatDistanceLiteral(distanceMatrix, document.querySelector("#distanceLiteral"));
}
});
// sleep for a second to avoid rate limit errors
await sleep(1000);
}
// display that all data has been gathered
document.querySelector("#progress").innerHTML = "<p>all data gathered</p>";
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function formatTable(cities, distanceMatrix, div) {
div.innerHTML = "";
div.style.display = "grid";
div.style.gridTemplateColumns = `repeat(${cities.length + 1}, 1fr)`;
div.appendChild(document.createElement("span"));
cities.forEach(city => {
let columnHeader = document.createElement("span");
columnHeader.innerHTML = city;
div.appendChild(columnHeader);
});
distanceMatrix.rows.forEach((row, index) => {
let rowHeader = document.createElement("span");
rowHeader.innerHTML = cities[index];
div.appendChild(rowHeader);
row.elements.forEach(element => {
let cell = document.createElement("span");
cell.innerHTML = element.distance.text;
div.appendChild(cell);
});
});
}
function formatLatLongLiteral(citiesLatLong, cities, pre) {
pre.innerHTML = " // replace literals in BigTenData.java with these\n";
pre.innerHTML += " // or create a new class and refactor references to BigTenData\n";
pre.innerHTML += " private static final City[] cities = new City[] {\n";
citiesLatLong.forEach((city, index) => {
if(city) {
pre.innerHTML += ` new City(${city.lat}, ${city.lng}, "${cities[index]}", "${cities[index]}"),\n`;
}
});
pre.innerHTML += " };";
}
function formatDistanceLiteral(distanceMatrix, pre) {
pre.innerHTML = " private static final double[][] distanceMatrix = new double[][]{\n";
distanceMatrix.rows.forEach(row => {
pre.innerHTML += " { ";
row.elements.forEach(element => {
pre.innerHTML += (element.distance.value * 0.000621371) + ", ";
});
pre.innerHTML += "},\n";
});
pre.innerHTML += " };";
}
function formatLatLongConstants(bounds, pre) {
pre.innerHTML = " // replace constants in Map.java with these\n";
pre.innerHTML += ` private static final double MIN_LAT = ${bounds.Za.j};\n`;
pre.innerHTML += ` private static final double MAX_LAT = ${bounds.Za.i};\n`;
pre.innerHTML += ` private static final double MIN_LNG = ${bounds.Ua.i};\n`;
pre.innerHTML += ` private static final double MAX_LNG = ${bounds.Ua.j};\n`;
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=!!! replace with your key !!!&callback=initMap">
</script>
</body>
</html>