Skip to content

Commit 0cf46e7

Browse files
committed
bt4u: only show routes on stop, popup style tweaks
1 parent 2d47954 commit 0cf46e7

File tree

7 files changed

+2186
-1969
lines changed

7 files changed

+2186
-1969
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*~
2+
*.pyc
3+
*.swp
4+
/openlayers

css/global.css

+17-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@ body
2323
#header h1
2424
{
2525
padding: 0;
26-
font-family: "Delicious", "Trebuchet MS", "DejaVu Sans", "Bitstream Vera Sans", sans-serif;
2726
font-size: 2.7em;
28-
font-weight: normal;
27+
}
28+
29+
h1, h4
30+
{
31+
font-family: "Delicious", "Trebuchet MS", "DejaVu Sans", "Bitstream Vera Sans", sans-serif;
32+
font-weight: bold;
2933
}
3034

3135
/* center header and content, give it a standard width */
@@ -72,18 +76,28 @@ body
7276
.olControlLayerSwitcher .layersDiv
7377
{
7478
background: #333 !important;
79+
border-top-left-radius: 6px;
80+
border-bottom-left-radius: 6px;
7581
}
7682

7783
.olControlOverviewMapElement
7884
{
7985
background: #666;
8086
}
8187

88+
.olPopup
89+
{
90+
background: #fff !important;
91+
border: 1px solid #dbd8bc !important;
92+
border-radius: 6px;
93+
box-shadow: 0 0 2px 2px rgba(255, 255, 255, 153);
94+
}
95+
8296
.olPopup h4
8397
{
8498
margin: 0 0 6px 0;
8599
padding: 0;
86-
font-size: 1.1em;
100+
font-size: 1.4em;
87101
font-weight: bold;
88102
}
89103

js/bt4u.js

+22-261
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
BT4U_API_URL = "/bt4u";
2+
ROUTES_OSM_URL = "/routes.osm";
23
STOPS_OSM_URL = "/stops.osm";
34

45
routeId = "";
@@ -7,36 +8,12 @@ updateTimer = null;
78

89
/**
910
* Initialize bus data.
10-
* Adds map layers and load routes.
11+
* Loads routes and stops.
1112
*/
1213
function initBusData()
1314
{
14-
// Bus route layer
15-
/*busRoutes = new OpenLayers.Layer.Vector('Bus Routes', {
16-
displayInLayerSwitcher: false, visibility: false });
17-
map.addLayer(busRoutes);
18-
19-
// Bus stops layer
20-
busStops = new OpenLayers.Layer.Markers('Bus Stops', {
21-
displayInLayerSwitcher: false, visibility: false });
22-
map.addLayer(busStops);
23-
24-
// Buses layer
25-
busMarkers = new OpenLayers.Layer.Markers('Buses', {
26-
attribution: "Bus data from <a href='http://bt4u.org' rel='external'>" +
27-
"BT4u</a>",
28-
displayInLayerSwitcher: false,
29-
visibility: false });
30-
map.addLayer(busMarkers);*/
31-
15+
loadRoutes();
3216
loadBusStops();
33-
34-
$.get(BT4U_API_URL + '/routes', function(data){
35-
routes = $.parseJSON(data);
36-
});
37-
38-
/*loadRoutes();
39-
initRouteUpdates();*/
4017
}
4118

4219
/**
@@ -103,18 +80,19 @@ function showStopInfo(feature)
10380
popupHtml += "<select id='popup_route_selector'>";
10481
popupHtml += "<option value=''>Select a route</option>";
10582

106-
for(i = 0; i < routes.length; i++)
83+
for(i in routes[feature.data.id])
10784
{
108-
popupHtml += "<option value='" + routes[i]['route_short_name'] +
109-
"'>" + routes[i]['route_long_name'] + "</option>";
85+
route = routes[feature.data.id][i];
86+
popupHtml += "<option value='" + route['ref'] +
87+
"'>" + route['name'] + "</option>";
11088
}
11189

11290
popupHtml += "</select>";
11391
popupHtml += "<div id='arrival_times'></div>";
11492

11593
popup = new OpenLayers.Popup.Anchored('stop_info',
11694
feature.geometry.getBounds().getCenterLonLat(),
117-
new OpenLayers.Size(300, 200),
95+
new OpenLayers.Size(300, 160),
11896
popupHtml,
11997
null,
12098
false,
@@ -139,246 +117,29 @@ function hideStopInfo(feature)
139117
feature.popup.destroy();
140118
}
141119

142-
var routes = [];
120+
var routes = {};
143121

144122
/**
145123
* Loads the routes that are currently running
146124
*/
147125
function loadRoutes()
148126
{
149-
loadBusData('allRunningRoutes', '', parseRoutes);
150-
}
127+
$.get(ROUTES_OSM_URL, function(data){
128+
$(data).find('relation').each(function(){
129+
routeObj = $(this);
130+
route = {};
151131

152-
/**
153-
* Callback for loadRoutes()
154-
*/
155-
function parseRoutes(data)
156-
{
157-
jsonData = $.parseJSON(data);
158-
routeList = jsonData['response']['allRunningRoutes'];
132+
routeObj.find('tag').each(function(){
133+
route[$(this).attr('k')] = $(this).attr('v');
134+
});
159135

160-
// create route array
161-
for(id in routeList)
162-
{
163-
routes.push({
164-
routeId : id,
165-
text : routeList[id]
166-
});
167-
}
136+
routeObj.find("member[type='node']").each(function(){
137+
nodeId = $(this).attr('ref');
138+
if(typeof routes[nodeId] != 'object')
139+
routes[nodeId] = [];
168140

169-
// make sure buses are running
170-
if(routes.length == 0)
171-
{
172-
$('#route_selector option').text('No routes running');
173-
$('#route_selector').attr('disabled', 'disabled');
174-
return;
175-
}
176-
else {
177-
$('#route_selector option').text('Select a route');
178-
$('#route_selector').removeAttr('disabled');
179-
}
180-
181-
// add each route to the route selector
182-
$.each(routeList, function(val, text)
183-
{
184-
$('#route_selector').append(new Option(text, val));
185-
});
186-
187-
$('#route_selector').change(function(e)
188-
{
189-
$('#route_selector option:selected').each(function()
190-
{
191-
setActiveRoute($(this).val());
141+
routes[nodeId].push(route);
142+
});
192143
});
193144
});
194145
}
195-
196-
/**
197-
* Sets the active bus route and calls loadRoute()
198-
*/
199-
function setActiveRoute(val)
200-
{
201-
if(val.length == 0)
202-
{
203-
hideBusLayers();
204-
return;
205-
}
206-
207-
showBusLayers();
208-
209-
routeId = val;
210-
loadRoute();
211-
}
212-
213-
/**
214-
* Loads the current bus route
215-
*/
216-
function loadRoute()
217-
{
218-
if(routeId.length == 0)
219-
{
220-
return;
221-
}
222-
223-
loadBusData('route', routeId, parseRoute);
224-
}
225-
226-
/**
227-
* Callback for loadRoute()
228-
*/
229-
function parseRoute(data)
230-
{
231-
jsonData = $.parseJSON(data);
232-
routeData = jsonData['response']['route'];
233-
234-
addShape(routeData['shape']['shapePoints'][0]);
235-
addStops(routeData['stops']);
236-
addBuses(routeData['busses']);
237-
}
238-
239-
/**
240-
* Adds the shape of a bus route given an array of maps containing lon and lat values
241-
*/
242-
function addShape(pts)
243-
{
244-
points = [];
245-
246-
for(i in pts)
247-
{
248-
pt = new OpenLayers.Geometry.Point(pts[i]['lon'], pts[i]['lat']);
249-
250-
points.push(pt.transform(EPSG_4326, map.getProjectionObject()));;
251-
}
252-
253-
// remove existing route
254-
busRoutes.removeFeatures(busRoutes.features);
255-
256-
geom = new OpenLayers.Geometry.LineString(points);
257-
feature = new OpenLayers.Feature.Vector(geom, null, {
258-
strokeColor : '#ff0000',
259-
strokeOpacity : 0.7,
260-
strokeWidth : 5
261-
});
262-
busRoutes.addFeatures(feature);
263-
}
264-
265-
/**
266-
* Updates the stops currently displayed on the map from an array of stops
267-
*/
268-
function addStops(stops)
269-
{
270-
// remove existing stops
271-
busStops.clearMarkers();
272-
273-
for(i in stops)
274-
{
275-
stopLoc = stops[i]['location'];
276-
277-
if(stopLoc.length == 0)
278-
{
279-
continue;
280-
}
281-
282-
loc = new OpenLayers.LonLat(stopLoc['lon'], stopLoc['lat']);
283-
284-
eta = parseFloat(stops[i]['eta']);
285-
eta = Math.round(eta * 100) / 100;
286-
287-
popupData = "<strong>" + stops[i]['name'] + "</strong><br />\n";
288-
289-
if(eta >= 0)
290-
{
291-
popupData += "ETA: " + eta + " minutes";//<br />\n";
292-
}
293-
294-
//popupData = "Scheduled Arrival: ";
295-
296-
// create marker and add to "bus stops" layer
297-
addMarker(busStops, loc.transform(EPSG_4326, map.getProjectionObject()), AutoSizeAnchored, popupData, { 'closeBox' : true });
298-
299-
// add popup to marker
300-
//marker.events.register('mousedown', marker, showStopPopup);
301-
}
302-
}
303-
304-
/**
305-
* Loads the bus data and calls parseBuses()
306-
*/
307-
function updateBuses()
308-
{
309-
loadBusData('busses', routeId, parseBuses);
310-
}
311-
312-
/**
313-
* Callback for updateBuses()
314-
*/
315-
function parseBuses(data)
316-
{
317-
jsonData = $.parseJSON(data);
318-
addBuses(jsonData['response']['busses']);
319-
}
320-
321-
/**
322-
* Updates the position of buses on the map given an array of buses
323-
*/
324-
function addBuses(buses)
325-
{
326-
// remove existing buses
327-
busMarkers.clearMarkers();
328-
329-
size = new OpenLayers.Size(60, 60);
330-
331-
for(i in buses)
332-
{
333-
busLoc = buses[i]['location'];
334-
335-
if(busLoc.length == 0)
336-
{
337-
continue;
338-
}
339-
340-
loc = new OpenLayers.LonLat(busLoc['lon'], busLoc['lat']);
341-
342-
dir = new String(buses[i]['velocity']['direction']);
343-
while(dir.length < 4)
344-
{
345-
dir = '0'.concat(dir);
346-
}
347-
348-
icon = new OpenLayers.Icon(BUS_ICON.replace('####', dir), size);
349-
popupData = "Passengers: " + buses[i]['passenger_count'] + "<br />\n";
350-
popupData += "Speed: " + buses[i]['velocity']['speed'] + "mph<br />\n";
351-
popupData += "Last Updated: " + buses[i]['latestUpdate'];
352-
353-
// create marker and add to "bus markers" layer
354-
addMarker(busMarkers, loc.transform(EPSG_4326, map.getProjectionObject()), AutoSizeAnchored, popupData, { 'closeBox' : true, 'icon' : icon});
355-
}
356-
}
357-
358-
/**
359-
* Initializes automatic updates of bus position at the time specified by BUS_UPDATE_INTERVAL
360-
*/
361-
function initRouteUpdates()
362-
{
363-
updateTimer = setInterval(updateBuses, BUS_UPDATE_INTERVAL);
364-
}
365-
366-
/**
367-
* Make all bus layers visible (they are hidden by default)
368-
*/
369-
function showBusLayers()
370-
{
371-
busRoutes.setVisibility(true);
372-
busStops.setVisibility(true);
373-
busMarkers.setVisibility(true);
374-
}
375-
376-
/**
377-
* Hide all bus layers
378-
*/
379-
function hideBusLayers()
380-
{
381-
busRoutes.setVisibility(false);
382-
busStops.setVisibility(false);
383-
busMarkers.setVisibility(false);
384-
}

0 commit comments

Comments
 (0)