-
Notifications
You must be signed in to change notification settings - Fork 0
/
exercise3.js
196 lines (181 loc) · 7.96 KB
/
exercise3.js
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
var markerList = []; //global variables
var routes;
var map;
var routePath;
var storedName;
var pathBounds;
var dataSet;
window.onload=function(){ //this function is executed after DOM has fully loaded
//buttons onclick
document.getElementById("busButton").onclick = showBuses; //show current location of all buses operating on the bus line selected
document.getElementById("refreshButton").onclick = refreshBuses; //when clicking the search button, we used the API and parse the data.
document.getElementById("routeButton").onclick = showRoutes; //when clicking the search button, we used the API and parse the data.
document.getElementById('lineList').onchange = function() { //if you change the route line, "Hide buses" button becomes "Show buses"
document.getElementById("busButton").value = "Show buses";
}
getRequest("https://data.foli.fi/gtfs/", getLatestDataSet); //get latest bus data
}
// A SIMPLE GET REQUEST FUNCTION
function getRequest(url, callback){
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function(){ //called when the server responds with data
if(this.readyState == 4 && this.status == 200){
var fetchData = JSON.parse(xmlHttp.responseText);
callback(fetchData); //pass the list to callback function, in this case the fetchRoutes function.
}
}
xmlHttp.open("GET", url, true); //true for asynchronous
xmlHttp.send();
}
function getLatestDataSet(data){
dataSet = data["datasets"][0];
getRequest("https://data.foli.fi/gtfs/v0/"+ dataSet + "/routes", fetchRouteList); //we need to fetch the route names to the drop-down list
}
//A SIMPLE COMPARATOR
function compare(item1,item2) {
if (String(item1[1]) < String(item2[1])){ //lexicographic compare
return -1;
}
else if (String(item1[1]) > String(item2[1])){
return 1;
}
return 0;
}
//GOOGLE MAPS FUNCTIONS
function initMap(){
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 60.45, lng: 22.35}, //initially around turku
zoom: 10
});
}
function addMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map
});
markerList.push(marker); //add to list of markers
var bounds = new google.maps.LatLngBounds();
for (i = 0; i < markerList.length; i++) {
bounds.extend(markerList[i].getPosition());
}
map.fitBounds(bounds); //fit bounds according to markers
if (pathBounds){
map.fitBounds(pathBounds);
}
}
function deleteMarkers(){
setMapOnAll(null);
markerList = [];
}
function hideMarkers(){
for (i=0;i<markerList.length;i++){ //loop through list of markers
markerList[i].setVisible(false); //hides markers
}
}
function setMapOnAll(map) {
for (var i = 0; i < markerList.length; i++) {
markerList[i].setMap(map);
}
}
//THREE BUTTONS FUNCTIONS
function showBuses(){ //event fired when user clicks on Show buses / Hide buses
var button = document.getElementById("busButton");
if (button.value == "Show buses"){
getRequest("https://data.foli.fi/siri/vm", showLocations); //fallback to showLocations
button.value = "Hide buses";
}
else if (button.value == "Hide buses"){
hideMarkers();
button.value = "Show buses";
}
}
function refreshBuses(){ //just run the showLocations
document.getElementById("busButton").value = "Hide buses";
getRequest("https://data.foli.fi/siri/vm", showLocations); //fallback to showLocations
}
function showRoutes(){
var routeList = document.getElementById("lineList");
if(routeList.options[routeList.selectedIndex].text == "Select line"){
alert("You have not selected any route.");
return;
}
if(routeList.options[routeList.selectedIndex].text != storedName){ //if the chosen route is not the same as the route for markers...
deleteMarkers(); //...we remove the markers
}
storedName = routeList.options[routeList.selectedIndex].text; //store new name so that we can now when to remove old route if we want new markers
var routeId = routeList.options[routeList.selectedIndex].value; //we use ID because that is what FÖLI uses
acquireTrips(routeId);
}
//CALLBACK FUNCTIONS
//FETCH ROUTE LIST TO DROPDOWN MENU
function fetchRouteList(routeList){
var routeChoices = [];
for(i=0; i<routeList.length; i++){
var routeIdAndName = [routeList[i].route_id, routeList[i].route_short_name]; //json ID of bus number and the actual bus number.
routeChoices.push(routeIdAndName);
}
routeChoices.sort(compare); //sort with compare function on the actual bus number
for(i=0; i<routeChoices.length; i++){ //add the routes to the dropdown menu
var routeId = routeChoices[i][0];
var routeName = routeChoices[i][1];
$("#lineList").append($("<option></option>").attr("value", routeId).text(routeName)); //add element to dropdown list
}
}
//SHOW BUSES BUTTON AND REFRESH BUTTON CALLBACK FUNCTION
function showLocations(data){ //fetch the locations by filtering the bus line from the JSON which we got from showBuses and then add markers on map
var routeList = document.getElementById("lineList");
deleteMarkers(); //delete old markers
if (routePath != undefined && routeList.options[routeList.selectedIndex].text != storedName){ //if there is an old path for another route line..
routePath.setMap(null); //..we delete the old path
pathBounds = ""; //and reset the bounds
}
var routeList = document.getElementById("lineList");
var routeName = routeList.options[routeList.selectedIndex].text; //get the name from the dropdown menu
var busPositions = [];
storedName = routeName;
busList = data.result.vehicles;
var empty = true; //variable to check if there are any buses on move
for (var bus in busList){ // loop through the elements in the JSON
if (routeName == busList[bus].publishedlinename){ //if the linenames match, we create a marker
var latitude = busList[bus].latitude;
var longitude = busList[bus].longitude;
var location = {lat: latitude, lng: longitude};
addMarker(location); //add marker
empty = false; //we have found buses on the map
}
}
if (empty){ //if we havent found buses, we alert with message
alert("No buses found");
var button = document.getElementById("busButton");
button.value = "Show buses";
}
}
//SHOW ROUTES BUTTON CALLBACK FUNCTIONS
function acquireTrips(routeId){ //acquire trips for this route id
getRequest("https://data.foli.fi/gtfs/v0/"+ dataSet + "/trips/route/" + routeId, acquireShape); //fallback to acquire shape
}
function acquireShape(trips){ //choose random shape_id and use it for acquiring coordinates from shapes.txt
getRequest("https://data.foli.fi/gtfs/v0/"+ dataSet + "/shapes/" + trips[1].shape_id, drawRoute);
}
function drawRoute(coordinates){ //draw route based on fetched coordinates
var locations = [];
var bounds = new google.maps.LatLngBounds();
if (routePath != undefined){ //if there is and old path
routePath.setMap(null); //delete old path
}
for (i=0; i<coordinates.length; i++){ //push coordinates to locations list
locations.push({lat: coordinates[i].lat,
lng: coordinates[i].lon});
var latlng = new google.maps.LatLng(coordinates[i].lat,coordinates[i].lon);
bounds.extend(latlng);
}
routePath = new google.maps.Polyline({ //create a polyline
path: locations,
strokeColor: '#FE7569',
strokeOpacity: 1.0,
strokeWeight: 3
});
routePath.setMap(map);
pathBounds = bounds;
map.fitBounds(bounds); //fit map according to the bounds
}