<?php | <?php |
include ('include/common.inc.php'); | include ('include/common.inc.php'); |
include_header("About", "about") | include_header("About", "about") |
?> | ?> |
<p> | <p> |
Busness Time - An ACT bus timetable webapp<br /> | Busness Time - An ACT bus timetable webapp<br /> |
Based on the maxious-canberra-transit-feed (<a | Based on the maxious-canberra-transit-feed (<a |
href="http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip">download</a>, | href="http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip">download</a>, |
last updated <?php | last updated <?php |
echo date("F d Y.", @filemtime('cbrfeed.zip')); ?>)<br /> | echo date("F d Y.", @filemtime('cbrfeed.zip')); ?>)<br /> |
Source code for the <a | Source code for the <a |
href="https://github.com/maxious/ACTBus-data">transit | href="https://github.com/maxious/ACTBus-data">transit |
feed</a> and <a href="https://github.com/maxious/ACTBus-ui">this | feed</a> and <a href="https://github.com/maxious/ACTBus-ui">this |
site</a> available from github.<br /> | site</a> available from github.<br /> |
Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br /> | Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br /> |
<br /> | <br /> |
Feedback encouraged; contact maxious@lambdacomplex.org<br /> | Feedback encouraged; contact maxious@lambdacomplex.org<br /> |
<br /> | <br /> |
Some icons by Joseph Wain / glyphish.com<br /> | Some icons by Joseph Wain / glyphish.com<br /> |
Native clients also available for iPhone(<a href="http://itunes.apple.com/au/app/cbrtimetable/id444287349?mt=8">cbrTimetable by Sandor Kolotenko</a> | |
, <a href="http://itunes.apple.com/au/app/act-buses/id376634797?mt=8">ACT Buses by David Sullivan</a>) | |
and Android (<a href="https://market.android.com/details?id=com.action">MyBus 2.0 by Imagine Team</a>) | |
<br /> | |
<br /> | <br /> |
<small>Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip. | <small>Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip. |
Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, | Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, |
express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided | express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided |
"as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. | "as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. |
All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, | All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, |
change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site | change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site |
without prior notice. </small> | without prior notice. </small> |
<?php | <?php |
include_footer(); | include_footer(); |
?> | ?> |
#!/bin/bash | #!/bin/bash |
#this script should be run from a fresh git checkout from github | #this script should be run from a fresh git checkout from github |
#ami base must have yum install lighttpd-fastcgi, git, tomcat6 | #ami base must have yum install lighttpd-fastcgi, git, tomcat6 |
#php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2 | #php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2 |
#postgres postgres-server php-pg | #postgres postgres-server php-pg |
#http://www.how2forge.org/installing-lighttpd-with-php5-and-mysql-support-on-fedora-12 | #http://www.how2forge.org/installing-lighttpd-with-php5-and-mysql-support-on-fedora-12 |
cp /root/aws.php /tmp/ | cp /root/aws.php /tmp/ |
mkdir /var/www/lib/staticmaplite/cache | mkdir /var/www/lib/staticmaplite/cache |
chcon -h system_u:object_r:httpd_sys_content_t /var/www | chcon -h system_u:object_r:httpd_sys_content_t /var/www |
chcon -R -h root:object_r:httpd_sys_content_t /var/www/* | chcon -R -h root:object_r:httpd_sys_content_t /var/www/* |
chcon -R -t httpd_sys_content_rw_t /var/www/lib/staticmaplite/cache | chcon -R -t httpd_sys_content_rw_t /var/www/lib/staticmaplite/cache |
chmod -R 777 /var/www/lib/staticmaplite/cache | chmod -R 777 /var/www/lib/staticmaplite/cache |
chcon -R -t httpd_sys_content_rw_t /var/www/labs/tiles | chcon -R -t httpd_sys_content_rw_t /var/www/labs/tiles |
chmod -R 777 /var/www/labs/tiles | chmod -R 777 /var/www/labs/tiles |
wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \ | wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \ |
-O /var/www/cbrfeed.zip | -O /var/www/cbrfeed.zip |
createdb transitdata | createdb transitdata |
createlang -d transitdata plpgsql | createlang -d transitdata plpgsql |
psql -d transitdata -f /var/www/lib/postgis.sql | psql -d transitdata -f /var/www/lib/postgis.sql |
# curl https://github.com/maxious/ACTBus-ui/raw/master/transitdata.cbrfeed.sql.gz -o transitdata.cbrfeed.sql.gz | # curl https://github.com/maxious/ACTBus-ui/raw/master/transitdata.cbrfeed.sql.gz -o transitdata.cbrfeed.sql.gz |
#made with pg_dump transitdata | gzip -c > transitdata.cbrfeed.sql.gz | #made with pg_dump transitdata | gzip -c > transitdata.cbrfeed.sql.gz |
gunzip /var/www/transitdata.cbrfeed.sql.gz | gunzip /var/www/transitdata.cbrfeed.sql.gz |
psql -d transitdata -f /var/www/transitdata.cbrfeed.sql | psql -d transitdata -f /var/www/transitdata.cbrfeed.sql |
#createuser transitdata -SDRP | #createuser transitdata -SDRP |
#password transitdata | #password transitdata |
#psql -d transitdata -c \"GRANT SELECT ON TABLE agency,calendar,calendar_dates,routes,stop_times,stops,trips TO transitdata;\" | #psql -d transitdata -c \"GRANT SELECT ON TABLE agency,calendar,calendar_dates,routes,stop_times,stops,trips TO transitdata;\" |
#psql -d transitdata -c "GRANT SELECT,INSERT ON TABLE myway_observations,myway_routes,myway_stops,myway_timingdeltas TO transitdata;" | |
#psql -d transitdata -c "GRANT SELECT,INSERT,UPDATE ON TABLE myway_routes,myway_stops TO transitdata;" | |
##psql -d transitdata -c "GRANT SELECT ON ALL TABLES IN SCHEMA public TO transitdata;" | |
php /var/www/updatedb.php | php /var/www/updatedb.php |
wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \ | wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \ |
-O /tmp/Graph.obj | -O /tmp/Graph.obj |
rm -rfv /usr/share/tomcat6/webapps/opentripplanner* | rm -rfv /usr/share/tomcat6/webapps/opentripplanner* |
wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-webapp.war \ | wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-webapp.war \ |
-O /usr/share/tomcat6/webapps/opentripplanner-webapp.war | -O /usr/share/tomcat6/webapps/opentripplanner-webapp.war |
wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-api-webapp.war \ | wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-api-webapp.war \ |
-O /usr/share/tomcat6/webapps/opentripplanner-api-webapp.war | -O /usr/share/tomcat6/webapps/opentripplanner-api-webapp.war |
/etc/init.d/tomcat6 restart | /etc/init.d/tomcat6 restart |
<?php | <?php |
include ('../include/common.inc.php'); | include ('../include/common.inc.php'); |
include_header("Busness R&D", "index") | include_header("Busness R&D", "index") |
?> | ?> |
<ul data-role="listview" data-theme="e" data-groupingtheme="e"> | <ul data-role="listview" data-theme="e" data-groupingtheme="e"> |
<li data-role="list-divider" > Experimental Features </li> | <li data-role="list-divider" > Experimental Features </li> |
<li><a href="mywaybalance.php"><h3>MyWay Balance for mobile</h3> | <li><a href="mywaybalance.php"><h3>MyWay Balance for mobile</h3> |
<p>Mobile viewer for MyWay balance. Warning! No HTTPS security.</p></a></li> | <p>Mobile viewer for MyWay balance. Warning! No HTTPS security.</p></a></li> |
<li><a href="networkstats.php"><h3>Route Statistics</h3> | |
<p>Analysis of route timing points</p></a></li> | |
<li><a href="busstopdensity.php"><h3>Bus Stop Density Map</h3> | <li><a href="busstopdensity.php"><h3>Bus Stop Density Map</h3> |
<p>Analysis of bus stop coverage</p></a></li> | <p>Analysis of bus stop coverage</p></a></li> |
<li><a href="stopBrowser.php"><h3>Bus Stop Browser Map</h3> | <li><a href="stopBrowser.php"><h3>Bus Stop Browser Map</h3> |
<p>Bus stop location/route browser</p></a></li> | <p>Bus stop location/route browser</p></a></li> |
<li>More coming soon!</li> | </ul> |
<ul data-role="listview" data-theme="e" data-groupingtheme="e"> | |
<li data-role="list-divider" > MyWay Timeliness Graphs </li> | |
<li><a href="myway_timeliness.php"><h3>Timeliness over Day</h3> | |
<p>Displays the deviation from the timetable over the day</p></a></li> | |
<li><a href="myway_timeliness_freqdist.php"><h3>Frequency Distribution of Time Deviation</h3> | |
<p>Displays spread of time deviations</p></a></li> | |
<li><a href="myway_timeliness_route.php"><h3>Timeliness over Route</h3> | |
<p>Displays the deviation from timetable as a specific route progresses</p></a></li> | |
<li><a href="myway_timeliness_stop.php"><h3>Timeliness at Stop</h3> | |
<p>Displays the deviation from the timetable at a specific stop</p></a></li> | |
</ul> | </ul> |
</div> | </div> |
<?php | <?php |
include_footer() | include_footer() |
?> | ?> |
<?php | <?php |
include ('../include/common.inc.php'); | include ('../include/common.inc.php'); |
include_header("MyWay Deltas", "mywayDelta"); | include_header("MyWay Deltas", "mywayDelta"); |
?> | ?> |
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../js/flot/excanvas.min.js"></script><![endif]--> | <!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../js/flot/excanvas.min.js"></script><![endif]--> |
<script language="javascript" type="text/javascript" src="../js/flot/jquery.flot.js"></script> | <script language="javascript" type="text/javascript" src="../js/flot/jquery.flot.js"></script> |
<div id="placeholder" style="width:1000px;height:600px"></div> | <center><div id="placeholder" style="width:900px;height:550px"></div></center> |
<script type="text/javascript"> | <script type="text/javascript"> |
$(function () { | $(function () { |
var d = new Date(); | var d = new Date(); |
d.setUTCMinutes(0); | d.setUTCMinutes(0); |
d.setUTCHours(0); | d.setUTCHours(0); |
var midnight = d.getTime(); | var midnight = d.getTime(); |
<?php | <?php |
$query = "select * from myway_timingdeltas where abs(timing_delta) < 2*(select stddev(timing_delta) from myway_timingdeltas) order by route_full_name;"; | $query = "select * from myway_timingdeltas where abs(timing_delta) < 2*(select stddev(timing_delta) from myway_timingdeltas) order by route_full_name;"; |
$query = $conn->prepare($query); | $query = $conn->prepare($query); |
$query->execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn->errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
$i = 0; | $i = 0; |
$labels = Array(); | $labels = Array(); |
$lastRoute = ""; | $lastRoute = ""; |
foreach ($query->fetchAll() as $delta) { | foreach ($query->fetchAll() as $delta) { |
$routeName = $delta['route_full_name']; | $routeName = $delta['route_full_name']; |
if (strstr($routeName," 3")) $routeName = "312-319"; | if (strstr($routeName, " 3")) $routeName = "312-319"; |
else $routeName = preg_replace('/\D/', '', $routeName); | else $routeName = preg_replace('/\D/', '', $routeName); |
if ($routeName != $lastRoute) { | if ($routeName != $lastRoute) { |
$i++; | $i++; |
echo " var d$i = [];"; | echo " var d$i = [];"; |
$lastRoute = $routeName; | $lastRoute = $routeName; |
$labels[$i] = $routeName; | $labels[$i] = $routeName; |
} | } |
echo "d$i.push([ midnight+ (1000*" . midnight_seconds(strtotime($delta['time'])) . "), {$delta['timing_delta']}]); \n"; | echo "d$i.push([ midnight+ (1000*" . midnight_seconds(strtotime($delta['time'])) . "), ".intval($delta['timing_delta'])."]); \n"; |
}; | }; |
?> | ?> |
var placeholder = $("#placeholder"); | var placeholder = $("#placeholder"); |
var plot = $.plot(placeholder, [ | var plot = $.plot(placeholder, [ |
<?php | <?php |
foreach ($labels as $key => $label) { | foreach ($labels as $key => $label) { |
echo " { | echo " { |
data: d$key, | data: d$key, |
points: { show: true }, | points: { show: true }, |
label: '$label' | label: '$label' |
},"; | },"; |
} | } |
?> | ?> |
], | ], |
{ | { |
xaxis: { | xaxis: { |
mode: "time", | mode: "time", |
min: midnight + (1000*60*60*8), | min: midnight + (1000*60*60*8), |
max: midnight + (1000*60*60*23.5) | max: midnight + (1000*60*60*23.5) |
}, | }, |
yaxis: { | yaxis: { |
tickFormatter: yformatter | tickFormatter: yformatter |
}, | }, |
grid: { hoverable: true, clickable: true }, | grid: { hoverable: true, clickable: true, labelMargin: 32 }, |
}); | }); |
var o; | var o; |
o = plot.pointOffset({ x: midnight+ (9*60*60*1000), y: -1.2}); | o = plot.pointOffset({ x: midnight+ (9*60*60*1000), y: -1.2}); |
placeholder.append('<div style="position:absolute;left:' + (o.left + 4) + 'px;top:' + o.top + 'px;color:#666;font-size:smaller">9am</div>'); | placeholder.append('<div style="position:absolute;left:' + (o.left + 4) + 'px;top:' + o.top + 'px;color:#666;font-size:smaller">9am</div>'); |
o = plot.pointOffset({ x: midnight+ (16*60*60*1000), y: -1.2}); | o = plot.pointOffset({ x: midnight+ (16*60*60*1000), y: -1.2}); |
placeholder.append('<div style="position:absolute;left:' + (o.left + 4) + 'px;top:' + o.top + 'px;color:#666;font-size:smaller">4pm</div>'); | placeholder.append('<div style="position:absolute;left:' + (o.left + 4) + 'px;top:' + o.top + 'px;color:#666;font-size:smaller">4pm</div>'); |
}); | }); |
function yformatter(v) { | function yformatter(v) { |
return Math.floor(v/60) + " minutes " + (v == 0 ? "" : (v >0 ? "early":"late")) | if (Math.floor(v/60) < -9) return ""; |
return Math.abs(Math.floor(v/60)) + " min " + (v == 0 ? "" : (v >0 ? "early":"late")) | |
} | } |
function showTooltip(x, y, contents) { | function showTooltip(x, y, contents) { |
$('<div id="tooltip">' + contents + '</div>').css( { | $('<div id="tooltip">' + contents + '</div>').css( { |
position: 'absolute', | position: 'absolute', |
display: 'none', | display: 'none', |
top: y + 5, | top: y + 5, |
left: x + 5, | left: x + 5, |
border: '1px solid #fdd', | border: '1px solid #fdd', |
padding: '2px', | padding: '2px', |
'background-color': '#fee', | 'background-color': '#fee', |
opacity: 0.80 | opacity: 0.80 |
}).appendTo("body").fadeIn(200); | }).appendTo("body").fadeIn(200); |
} | } |
var previousPoint = null; | var previousPoint = null; |
$("#placeholder").bind("plothover", function (event, pos, item) { | $("#placeholder").bind("plothover", function (event, pos, item) { |
$("#x").text(pos.x.toFixed(2)); | $("#x").text(pos.x.toFixed(2)); |
$("#y").text(pos.y.toFixed(2)); | $("#y").text(pos.y.toFixed(2)); |
if (item) { | if (item) { |
if (previousPoint != item.dataIndex) { | if (previousPoint != item.dataIndex) { |
previousPoint = item.dataIndex; | previousPoint = item.dataIndex; |
$("#tooltip").remove(); | $("#tooltip").remove(); |
var x = item.datapoint[0].toFixed(2), | var x = item.datapoint[0].toFixed(2), |
y = item.datapoint[1].toFixed(2); | y = item.datapoint[1].toFixed(2); |
var d = new Date(); | var d = new Date(); |
d.setTime(x); | d.setTime(x); |
var time = d.getUTCHours() +':'+ (d.getUTCMinutes().toString().length == 1 ? '0'+ d.getMinutes(): d.getUTCMinutes()) | var time = d.getUTCHours() +':'+ (d.getUTCMinutes().toString().length == 1 ? '0'+ d.getMinutes(): d.getUTCMinutes()) |
showTooltip(item.pageX, item.pageY, | showTooltip(item.pageX, item.pageY, |
item.series.label + " at "+ time +" = " + y +" ( "+ y/60+" minutes )"); | item.series.label + " at "+ time +" = " + Math.abs(new Number(y/60).toFixed(2))+" minutes "+(y >0 ? "early":"late")); |
} | } |
} | } |
else { | else { |
$("#tooltip").remove(); | $("#tooltip").remove(); |
previousPoint = null; | previousPoint = null; |
} | } |
}); | }); |
</script> | </script> |
<?php | <?php |
include ('../include/common.inc.php'); | include ('../include/common.inc.php'); |
include_header("MyWay Delta Calculate", "mywayDeltaCalc"); | include_header("MyWay Delta Calculate", "mywayDeltaCalc"); |
function abssort($a, $b) | function abssort($a, $b) |
{ | { |
if ($a['timeDiff'] == $b['timeDiff']) { | if ($a['timeDiff'] == $b['timeDiff']) { |
return 0; | return 0; |
} | } |
return (abs($a['timeDiff']) < abs($b['timeDiff'])) ? -1 : 1; | return (abs($a['timeDiff']) < abs($b['timeDiff'])) ? -1 : 1; |
} | } |
//collect all observation not in delta | //collect all observation not in delta |
$query = "select * from myway_observations INNER JOIN myway_stops | $query = "select * from myway_observations INNER JOIN myway_stops |
ON myway_observations.myway_stop=myway_stops.myway_stop INNER JOIN myway_routes | ON myway_observations.myway_stop=myway_stops.myway_stop INNER JOIN myway_routes |
ON myway_observations.myway_route=myway_routes.myway_route | ON myway_observations.myway_route=myway_routes.myway_route |
WHERE observation_id NOT IN | WHERE observation_id NOT IN |
( | ( |
SELECT observation_id | SELECT observation_id |
FROM myway_timingdeltas | FROM myway_timingdeltas |
)"; | )"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn->prepare($query); | $query = $conn->prepare($query); |
$query->execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn->errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
$uncalcdObservations = $query->fetchAll(); | $uncalcdObservations = $query->fetchAll(); |
//Display count | //Display count |
echo "<h3>" . sizeof($uncalcdObservations) . " observations not yet processed</h2>"; | echo "<h3>" . sizeof($uncalcdObservations) . " observations not yet processed</h2>"; |
//foreach observation not in delta | //foreach observation not in delta |
foreach ($uncalcdObservations as $obsv) { | foreach ($uncalcdObservations as $obsv) { |
//var_dump($obsv); | //var_dump($obsv); |
echo "<h3>Observation {$obsv['observation_id']}:</h1> | echo "<h3>Observation {$obsv['observation_id']}:</h1> |
<small>{$obsv['myway_stop']} @ {$obsv['time']} on {$obsv['myway_route']}</small><br>"; | <small>{$obsv['myway_stop']} @ {$obsv['time']} on {$obsv['myway_route']}</small><br>"; |
if ($obsv["stop_code"] == "") { | if ($obsv["stop_code"] == "") { |
echo "error, stop '{$obsv['myway_stop']}' unknown"; | echo "error, stop '{$obsv['myway_stop']}' unknown"; |
continue; | continue; |
} | } |
if ($obsv["route_full_name"] == "") { | if ($obsv["route_full_name"] == "") { |
echo "error, route '{$obsv['myway_route']}' unknown"; | echo "error, route '{$obsv['myway_route']}' unknown"; |
continue; | continue; |
} | } |
// :convert timestamp into time of day and date | // :convert timestamp into time of day and date |
$time = date("H:i:s", strtotime($obsv['time'])); | $time = date("H:i:s", strtotime($obsv['time'])); |
$search_time = date("H:i:s", strtotime($obsv['time'])-(30*60)); // 30 minutes margin | $search_time = date("H:i:s", strtotime($obsv['time'])-(30*60)); // 30 minutes margin |
$date = date("c", strtotime($obsv['time'])); | $date = date("c", strtotime($obsv['time'])); |
$timing_period = service_period(strtotime($date)); | $timing_period = service_period(strtotime($date)); |
$potentialStops = getStopsByStopCode($obsv["stop_code"], $obsv["stop_street"]); | $potentialStops = getStopsByStopCode($obsv["stop_code"], $obsv["stop_street"]); |
//:get myway_stops records | //:get myway_stops records |
//:search by starts with stopcode and starts with street if street is not null | //:search by starts with stopcode and starts with street if street is not null |
//no result, skip and display error | //no result, skip and display error |
if (sizeof($potentialStops) < 1) { | if (sizeof($potentialStops) < 1) { |
echo "error, potential stops for stopcode {$obsv["stop_code"]} street {$obsv["stop_street"]} unknown"; | echo "error, potential stops for stopcode {$obsv["stop_code"]} street {$obsv["stop_street"]} unknown"; |
continue; | continue; |
} | } |
//print out stops | //print out stops |
echo "Matched stops: "; | echo "Matched stops: "; |
foreach ($potentialStops as $potentialStop) echo $potentialStop['stop_code'] . " "; | foreach ($potentialStops as $potentialStop) echo $potentialStop['stop_code'] . " "; |
echo "<br>"; | echo "<br>"; |