MyWay timeliness by stop/route
MyWay timeliness by stop/route

#!/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&amp;D", "index") include_header("Busness R&amp;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>";
//:get myway_route record //:get myway_route record
//no result, skip and display error //no result, skip and display error
//print out route //print out route
$potentialRoute = getRouteByFullName($obsv["route_full_name"]); $potentialRoute = getRouteByFullName($obsv["route_full_name"]);
if ($potentialRoute["route_short_name"] == "") { if ($potentialRoute["route_short_name"] == "") {
echo "error, route '{$obsv["route_full_name"]}' unknown"; echo "error, route '{$obsv["route_full_name"]}' unknown";
continue; continue;
} }
echo "Matched route: {$potentialRoute['route_short_name']}{$potentialRoute['route_long_name']} {$timing_period}<br>"; echo "Matched route: {$potentialRoute['route_short_name']}{$potentialRoute['route_long_name']} {$timing_period}<br>";
$timeDeltas = Array(); $timeDeltas = Array();
foreach ($potentialStops as $potentialStop) { foreach ($potentialStops as $potentialStop) {
$stopRoutes = getStopRoutes($potentialStop['stop_id'], $timing_period); $stopRoutes = getStopRoutes($potentialStop['stop_id'], $timing_period);
$foundRoute = Array(); $foundRoute = Array();
foreach ($stopRoutes as $stopRoute) { foreach ($stopRoutes as $stopRoute) {
//Check if this route stops at each stop //Check if this route stops at each stop
if ($stopRoute['route_short_name'] . $stopRoute['route_long_name'] == $obsv["route_full_name"]) { if ($stopRoute['route_short_name'] . $stopRoute['route_long_name'] == $obsv["route_full_name"]) {
echo "Matching route {$stopRoute['route_id']} found at {$potentialStop['stop_code']}<br>"; echo "Matching route {$stopRoute['route_id']} found at {$potentialStop['stop_code']}<br>";
$foundRoute = $stopRoute; $foundRoute = $stopRoute;
//if does get tripstoptimes for this route //if does get tripstoptimes for this route
$trips = getStopTrips($potentialStop['stop_id'], $timing_period, $search_time); $trips = getStopTrips($potentialStop['stop_id'], $timing_period, $search_time);
foreach ($trips as $trip) { foreach ($trips as $trip) {
//echo $trip['route_id']." ".$stopRoute['route_id'].";"; //echo $trip['route_id']." ".$stopRoute['route_id'].";";
if ($trip['route_id'] == $stopRoute['route_id']) { if ($trip['route_id'] == $stopRoute['route_id']) {
$timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']); $timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']);
$actual_time = strtotime($time); $actual_time = strtotime($time);
$trip_time = strtotime($timedTrip['arrival_time']); $trip_time = strtotime($timedTrip['arrival_time']);
$timeDiff = $actual_time - $trip_time; $timeDiff = $actual_time - $trip_time;
//work out time delta, put into array with index of delta //work out time delta, put into array with index of delta
$timeDeltas[] = Array( $timeDeltas[] = Array(
"timeDiff" => $timeDiff, "timeDiff" => $timeDiff,
"stop_code" => $potentialStop['stop_code'] "stop_code" => $potentialStop['stop_code'],
  "stop_sequence" => $timedTrip['stop_sequence']
); );
echo "Found trip {$trip['trip_id']} at stop {$potentialStop['stop_code']} (#{$potentialStop['stop_id']}, sequence #{$trip['stop_sequence']})<br>"; echo "Found trip {$trip['trip_id']} at stop {$potentialStop['stop_code']} (#{$potentialStop['stop_id']}, sequence #{$trip['stop_sequence']})<br>";
echo "Arriving at {$timedTrip['arrival_time']}, difference of " . round($timeDiff / 60, 2) . " minutes<br>"; echo "Arriving at {$timedTrip['arrival_time']}, difference of " . round($timeDiff / 60, 2) . " minutes<br>";
} }
} }
break; // because have found route break; // because have found route