Labs Tidy up, depreciate old trip planner tester, promote myway balance/service alerts to main site
Labs Tidy up, depreciate old trip planner tester, promote myway balance/service alerts to main site

file:a/about.php -> file:b/about.php
<?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> 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>) , <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>) and Android (<a href="https://market.android.com/details?id=com.action">MyBus 2.0 by Imagine Team</a>)
<br /> <br />
  GTFS-realtime API;
  Alerts and Trip Updates (but only Cancelled or Stop Skipped)
  Default format binary but can get JSON by adding ?ascii=yes
  <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();
?> ?>
   
<?php <?php
function getScheme()  
{ function getScheme() {
$scheme = 'http'; $scheme = 'http';
if (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') { if (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') {
$scheme .= 's'; $scheme .= 's';
} }
return $scheme; return $scheme;
} }
   
function getTrustRoot() function getTrustRoot() {
{ return sprintf("%s://%s:%s%s/", getScheme(), $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], dirname($_SERVER['PHP_SELF']));
return sprintf("%s://%s:%s%s/", }
getScheme(), $_SERVER['SERVER_NAME'],  
$_SERVER['SERVER_PORT'],  
dirname($_SERVER['PHP_SELF']));  
}  
   
   
// Includes required files // Includes required files
set_include_path(get_include_path() . PATH_SEPARATOR . $labsPath."lib/openid-php/"); set_include_path(get_include_path() . PATH_SEPARATOR . $basePath . "lib/openid-php/");
require_once "Auth/OpenID/Consumer.php"; require_once "Auth/OpenID/Consumer.php";
require_once "Auth/OpenID/FileStore.php"; require_once "Auth/OpenID/FileStore.php";
require_once "Auth/OpenID/AX.php"; require_once "Auth/OpenID/AX.php";
   
  function login() {
  // Just tested this with/for Google, needs trying with others ...
function login() $oid_identifier = 'https://www.google.com/accounts/o8/id';
{  
// Just tested this with/for Google, needs trying with others ...  
$oid_identifier = 'https://www.google.com/accounts/o8/id';  
// Create file storage area for OpenID data // Create file storage area for OpenID data
$store = new Auth_OpenID_FileStore('lib/openid-php/oid_store'); $store = new Auth_OpenID_FileStore('lib/openid-php/oid_store');
// Create OpenID consumer // Create OpenID consumer
$consumer = new Auth_OpenID_Consumer($store); $consumer = new Auth_OpenID_Consumer($store);
// Create an authentication request to the OpenID provider // Create an authentication request to the OpenID provider
$auth = $consumer -> begin($oid_identifier); $auth = $consumer->begin($oid_identifier);
   
// Create attribute request object // Create attribute request object
// See http://code.google.com/apis/accounts/docs/OpenID.html#Parameters for parameters // See http://code.google.com/apis/accounts/docs/OpenID.html#Parameters for parameters
// Usage: make($type_uri, $count=1, $required=false, $alias=null) // Usage: make($type_uri, $count=1, $required=false, $alias=null)
$attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/contact/email', 2, 1, 'email'); $attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/contact/email', 2, 1, 'email');
$attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/namePerson/first', 1, 1, 'firstname'); $attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/namePerson/first', 1, 1, 'firstname');
$attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/namePerson/last', 1, 1, 'lastname'); $attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/namePerson/last', 1, 1, 'lastname');
   
// Create AX fetch request // Create AX fetch request
$ax = new Auth_OpenID_AX_FetchRequest; $ax = new Auth_OpenID_AX_FetchRequest;
   
// Add attributes to AX fetch request // Add attributes to AX fetch request
foreach($attribute as $attr) { foreach ($attribute as $attr) {
$ax -> add($attr); $ax->add($attr);
} }
   
// Add AX fetch request to authentication request // Add AX fetch request to authentication request
$auth -> addExtension($ax); $auth->addExtension($ax);
$_SESSION['returnURL'] = curPageURL(); $_SESSION['returnURL'] = curPageURL();
// Redirect to OpenID provider for authentication // Redirect to OpenID provider for authentication
$url = $auth -> redirectURL(getTrustRoot(), $_SESSION['returnURL']); $url = $auth->redirectURL(getTrustRoot(), $_SESSION['returnURL']);
header('Location: ' . $url); header('Location: ' . $url);
} }
   
  function auth() {
  if ($_SESSION['authed'] == true)
  return true;
   
function auth() // Create file storage area for OpenID data
  $store = new Auth_OpenID_FileStore('lib/openid-php/oid_store');
  // Create OpenID consumer
  $consumer = new Auth_OpenID_Consumer($store);
  // Create an authentication request to the OpenID provider
  $response = $consumer->complete($_SESSION['returnURL']);
   
{ if ($response->status == Auth_OpenID_SUCCESS) {
if ($_SESSION['authed'] == true) return true;  
   
// Create file storage area for OpenID data  
$store = new Auth_OpenID_FileStore('lib/openid-php/oid_store');  
// Create OpenID consumer  
$consumer = new Auth_OpenID_Consumer($store);  
// Create an authentication request to the OpenID provider  
$response = $consumer -> complete($_SESSION['returnURL']);  
   
if ($response -> status == Auth_OpenID_SUCCESS) {  
// Get registration informations // Get registration informations
$ax = new Auth_OpenID_AX_FetchResponse(); $ax = new Auth_OpenID_AX_FetchResponse();
$obj = $ax -> fromSuccessResponse($response); $obj = $ax->fromSuccessResponse($response);
$email = $obj -> data['http://axschema.org/contact/email'][0]; $email = $obj->data['http://axschema.org/contact/email'][0];
var_dump($email); var_dump($email);
if ($email != "maxious@gmail.com") { if ($email != "maxious@gmail.com") {
die("Access Denied"); die("Access Denied");
} else {  
$_SESSION['authed'] = true;  
}  
} else { } else {
  $_SESSION['authed'] = true;
  }
  } else {
login(); login();
} }
} }
if ($_REQUEST['janrain_nonce']) auth();  
  if ($_REQUEST['janrain_nonce'])
  auth();
?> ?>
<?php <?php
   
// SELECT array_to_string(array(SELECT REPLACE(name_2006, ',', '\,') as name FROM suburbs order by name), ',') // SELECT array_to_string(array(SELECT REPLACE(name_2006, ',', '\,') as name FROM suburbs order by name), ',')
$suburbs = explode(",", "Acton,Ainslie,Amaroo,Aranda,Banks,Barton,Belconnen,Bonner,Bonython,Braddon,Bruce,Calwell,Campbell,Chapman,Charnwood,Chifley,Chisholm,City,Conder,Cook,Curtin,Deakin,Dickson,Downer,Duffy,Dunlop,Evatt,Fadden,Farrer,Fisher,Florey,Flynn,Forrest,Franklin,Fraser,Fyshwick,Garran,Gilmore,Giralang,Gordon,Gowrie,Greenway,Griffith,Gungahlin,Hackett,Hall,Harrison,Hawker,Higgins,Holder,Holt,Hughes,Hume,Isaacs,Isabella Plains,Kaleen,Kambah,Kingston,Latham,Lawson,Lyneham,Lyons,Macarthur,Macgregor,Macquarie,Mawson,McKellar,Melba,Mitchell,Monash,Narrabundah,Ngunnawal,Nicholls,Oaks Estate,O'Connor,O'Malley,Oxley,Page,Palmerston,Parkes,Pearce,Phillip,Pialligo,Red Hill,Reid,Richardson,Rivett,Russell,Scullin,Spence,Stirling,Symonston,Tharwa,Theodore,Torrens,Turner,Wanniassa,Waramanga,Watson,Weetangera,Weston,Yarralumla"); $suburbs = explode(",", "Acton,Ainslie,Amaroo,Aranda,Banks,Barton,Belconnen,Bonner,Bonython,Braddon,Bruce,Calwell,Campbell,Chapman,Charnwood,Chifley,Chisholm,City,Conder,Cook,Curtin,Deakin,Dickson,Downer,Duffy,Dunlop,Evatt,Fadden,Farrer,Fisher,Florey,Flynn,Forrest,Franklin,Fraser,Fyshwick,Garran,Gilmore,Giralang,Gordon,Gowrie,Greenway,Griffith,Gungahlin,Hackett,Hall,Harrison,Hawker,Higgins,Holder,Holt,Hughes,Hume,Isaacs,Isabella Plains,Kaleen,Kambah,Kingston,Latham,Lawson,Lyneham,Lyons,Macarthur,Macgregor,Macquarie,Mawson,McKellar,Melba,Mitchell,Monash,Narrabundah,Ngunnawal,Nicholls,Oaks Estate,O'Connor,O'Malley,Oxley,Page,Palmerston,Parkes,Pearce,Phillip,Pialligo,Red Hill,Reid,Richardson,Rivett,Russell,Scullin,Spence,Stirling,Symonston,Tharwa,Theodore,Torrens,Turner,Wanniassa,Waramanga,Watson,Weetangera,Weston,Yarralumla");
function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb", $collapsible = true, $twotone = false)  
{ function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb", $collapsible = true, $twotone = false) {
global $labsPath; global $basePath;
$width = 300; $width = 300;
$height = 300; $height = 300;
$metersperpixel[9] = 305.492 * $width; $metersperpixel[9] = 305.492 * $width;
$metersperpixel[10] = 152.746 * $width; $metersperpixel[10] = 152.746 * $width;
$metersperpixel[11] = 76.373 * $width; $metersperpixel[11] = 76.373 * $width;
$metersperpixel[12] = 38.187 * $width; $metersperpixel[12] = 38.187 * $width;
$metersperpixel[13] = 19.093 * $width; $metersperpixel[13] = 19.093 * $width;
$metersperpixel[14] = 9.547 * $width; $metersperpixel[14] = 9.547 * $width;
$metersperpixel[15] = 4.773 * $width; $metersperpixel[15] = 4.773 * $width;
//$metersperpixel[16] = 2.387 * $width; //$metersperpixel[16] = 2.387 * $width;
// $metersperpixel[17]=1.193*$width; // $metersperpixel[17]=1.193*$width;
$center = ""; $center = "";
$markers = ""; $markers = "";
$mapwidthinmeters = 50; $mapwidthinmeters = 50;
if (sizeof($mapPoints) < 1) return "map error"; if (sizeof($mapPoints) < 1)
if (sizeof($mapPoints) === 1) { return "map error";
if ($zoom == 0) $zoom = 14; if (sizeof($mapPoints) === 1) {
$markers.= "{$mapPoints[0][0]},{$mapPoints[0][1]},$markerimage"; if ($zoom == 0)
$center = "{$mapPoints[0][0]},{$mapPoints[0][1]}"; $zoom = 14;
} $markers.= "{$mapPoints[0][0]},{$mapPoints[0][1]},$markerimage";
else { $center = "{$mapPoints[0][0]},{$mapPoints[0][1]}";
foreach ($mapPoints as $index => $mapPoint) { }
if ($twotone && $index == 0) { else {
$markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . "iconr" . ($index + 1); foreach ($mapPoints as $index => $mapPoint) {
$center = "{$mapPoints[0][0]},{$mapPoints[0][1]}"; if ($twotone && $index == 0) {
} $markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . "iconr" . ($index + 1);
else { $center = "{$mapPoints[0][0]},{$mapPoints[0][1]}";
$markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . $markerImage . ($index + 1); } else {
} $markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . $markerImage . ($index + 1);
if ($index + 1 != sizeof($mapPoints)) $markers.= "|"; }
$dist = distance($mapPoints[0][0], $mapPoint[0][1], $mapPoint[0], $mapPoint[1]); if ($index + 1 != sizeof($mapPoints))
$mapwidthinmeters = ($dist > $mapwidthinmeters ? $dist : $mapwidthinmeters); $markers.= "|";
$totalLat+= $mapPoint[0]; $dist = distance($mapPoints[0][0], $mapPoint[0][1], $mapPoint[0], $mapPoint[1]);
$totalLon+= $mapPoint[1]; $mapwidthinmeters = ($dist > $mapwidthinmeters ? $dist : $mapwidthinmeters);
} $totalLat+= $mapPoint[0];
if ($zoom == 0) { $totalLon+= $mapPoint[1];
$mapwidthinmeters = distance($minlat, $minlon, $minlat, $maxlon); }
foreach (array_reverse($metersperpixel, true) as $zoomLevel => $maxdistance) { if ($zoom == 0) {
if ($zoom == 0 && $mapwidthinmeters * 1.5 < ($maxdistance)) $zoom = $zoomLevel; $mapwidthinmeters = distance($minlat, $minlon, $minlat, $maxlon);
} foreach (array_reverse($metersperpixel, true) as $zoomLevel => $maxdistance) {
} if ($zoom == 0 && $mapwidthinmeters * 1.5 < ($maxdistance))
$center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints); $zoom = $zoomLevel;
} }
$output = ""; }
if ($collapsible) $output.= '<div class="map" data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>'; $center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints);
$output.= '<img class="map" src="' . curPageURL() . '/' . $labsPath . '/lib/staticmaplite/staticmap.php?center=' . $center . '&amp;zoom=' . $zoom . '&amp;size=' . $width . 'x' . $height . '&amp;markers=' . $markers . '" width=' . $width . ' height=' . $height . '>'; }
if ($collapsible) $output.= '</div>'; $output = "";
return $output; if ($collapsible)
  $output.= '<div class="map" data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>';
  $output.= '<img class="map" src="' . curPageURL() . '/' . $basePath . '/lib/staticmaplite/staticmap.php?center=' . $center . '&amp;zoom=' . $zoom . '&amp;size=' . $width . 'x' . $height . '&amp;markers=' . $markers . '" width=' . $width . ' height=' . $height . '>';
  if ($collapsible)
  $output.= '</div>';
  return $output;
} }
function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false)  
{ function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false) {
$pi80 = M_PI / 180; $pi80 = M_PI / 180;
$lat1*= $pi80; $lat1*= $pi80;
$lng1*= $pi80; $lng1*= $pi80;
$lat2*= $pi80; $lat2*= $pi80;
$lng2*= $pi80; $lng2*= $pi80;
$r = 6372.797; // mean radius of Earth in km $r = 6372.797; // mean radius of Earth in km
$dlat = $lat2 - $lat1; $dlat = $lat2 - $lat1;
$dlng = $lng2 - $lng1; $dlng = $lng2 - $lng1;
$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
$c = 2 * atan2(sqrt($a) , sqrt(1 - $a)); $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
$km = $r * $c; $km = $r * $c;
if ($roundLargeValues) { if ($roundLargeValues) {
if ($km < 1) return floor($km * 1000); if ($km < 1)
else return round($km, 2) . "k"; return floor($km * 1000);
} else
else return floor($km * 1000); return round($km, 2) . "k";
  }
  else
  return floor($km * 1000);
} }
function decodePolylineToArray($encoded)  
{ function decodePolylineToArray($encoded) {
// source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 // source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5
$length = strlen($encoded); $length = strlen($encoded);
$index = 0; $index = 0;
$points = array(); $points = array();
$lat = 0; $lat = 0;
$lng = 0; $lng = 0;
while ($index < $length) { while ($index < $length) {
// Temporary variable to hold each ASCII byte. // Temporary variable to hold each ASCII byte.
$b = 0; $b = 0;
// The encoded polyline consists of a latitude value followed by a // The encoded polyline consists of a latitude value followed by a
// longitude value. They should always come in pairs. Read the // longitude value. They should always come in pairs. Read the
// latitude value first. // latitude value first.
$shift = 0; $shift = 0;
$result = 0; $result = 0;
do {