<?php | <?php |
include('common.inc.php'); | 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 href="cbrfeed.zip">download</a>, last updated <?php echo date("F d Y.", @filemtime('cbrfeed.zip')); ?>)<br /> | Based on the maxious-canberra-transit-feed (<a href="cbrfeed.zip">download</a>, last updated <?php |
echo date("F d Y.", @filemtime('cbrfeed.zip')); ?>)<br /> | |
Source code for the transit feed and this site @ <a href="http://maxious.lambdacomplex.org/git">http://maxious.lambdacomplex.org/git</a><br /> | Source code for the transit feed and this site @ <a href="http://maxious.lambdacomplex.org/git">http://maxious.lambdacomplex.org/git</a><br /> |
Uses jQuery Mobile, PHP, Ruby, Python, Google Transit Feed Specification tools, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br /> | Uses jQuery Mobile, PHP, Ruby, Python, Google Transit Feed Specification tools, 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 /> |
<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> |
<? | <? |
include_footer(); | include_footer(); |
?> | ?> |
#!/bin/bash | #!/bin/bash |
#this script should be run from a fresh git checkout from http://maxious.lambdacomplex.org | #this script should be run from a fresh git checkout from http://maxious.lambdacomplex.org |
#ami base must have yum install lighttpd-fastcgi, git, tomcat6 | #ami base must have yum install lighttpd-fastcgi, git, tomcat6 |
#screen php-cli php-gd tomcat6-webapps tomcat6-admin-webapps | #screen php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2 |
#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 -rfv /tmp/busui/* /var/www | cp -rfv /tmp/busui/* /var/www |
cp /root/aws.php /tmp/ | cp /root/aws.php /tmp/ |
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/staticmaplite/cache | chcon -R -t httpd_sys_content_rw_t /var/www/staticmaplite/cache |
chmod -R 777 /var/www/staticmaplite/cache | chmod -R 777 /var/www/staticmaplite/cache |
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 |
easy_install transitfeed | easy_install transitfeed |
easy_install simplejson | easy_install simplejson |
screen -d -m /var/www/view.sh | screen -d -m /var/www/view.sh |
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 | |
// 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"); | |
function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb", $collapsible = true) | |
{ | |
$width = 300; | |
$height = 300; | |
$metersperpixel[9] = 305.492 * $width; | |
$metersperpixel[10] = 152.746 * $width; | |
$metersperpixel[11] = 76.373 * $width; | |
$metersperpixel[12] = 38.187 * $width; | |
$metersperpixel[13] = 19.093 * $width; | |
$metersperpixel[14] = 9.547 * $width; | |
$metersperpixel[15] = 4.773 * $width; | |
$metersperpixel[16] = 2.387 * $width; | |
// $metersperpixel[17]=1.193*$width; | |
$center = ""; | |
$markers = ""; | |
$minlat = 999; | |
$minlon = 999; | |
$maxlat = 0; | |
$maxlon = 0; | |
if (sizeof($mapPoints) < 1) return "map error"; | |
if (sizeof($mapPoints) === 1) { | |
if ($zoom == 0) $zoom = 14; | |
$markers.= "{$mapPoints[0][0]},{$mapPoints[0][1]},$markerimage"; | |
$center = "{$mapPoints[0][0]},{$mapPoints[0][1]}"; | |
} | |
else { | |
foreach ($mapPoints as $index => $mapPoint) { | |
$markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . $markerImage . ($index + 1); | |
if ($index + 1 != sizeof($mapPoints)) $markers.= "|"; | |
if ($mapPoint[0] < $minlat) $minlat = $mapPoint[0]; | |
if ($mapPoint[0] > $maxlat) $maxlat = $mapPoint[0]; | |
if ($mapPoint[1] < $minlon) $minlon = $mapPoint[1]; | |
if ($mapPoint[1] > $maxlon) $maxlon = $mapPoint[1]; | |
$totalLat+= $mapPoint[0]; | |
$totalLon+= $mapPoint[1]; | |
} | |
if ($zoom == 0) { | |
$mapwidthinmeters = distance($minlat, $minlon, $minlat, $maxlon); | |
foreach (array_reverse($metersperpixel, true) as $zoomLevel => $maxdistance) { | |
if ($zoom == 0 && $mapwidthinmeters < ($maxdistance + 50)) $zoom = $zoomLevel; | |
} | |
} | |
$center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints); | |
} | |
$output = ""; | |
if ($collapsible) $output.= '<div data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>'; | |
$output.= '<center><img src="' . curPageURL() . 'staticmaplite/staticmap.php?center=' . $center . '&zoom=' . $zoom . '&size=' . $width . 'x' . $height . '&maptype=mapnik&markers=' . $markers . '" width=' . $width . ' height=' . $height . '></center>'; | |
if ($collapsible) $output.= '</div>'; | |
return $output; | |
} | |
function distance($lat1, $lng1, $lat2, $lng2) | |
{ | |
$pi80 = M_PI / 180; | |
$lat1*= $pi80; | |
$lng1*= $pi80; | |
$lat2*= $pi80; | |
$lng2*= $pi80; | |
$r = 6372.797; // mean radius of Earth in km | |
$dlat = $lat2 - $lat1; | |
$dlng = $lng2 - $lng1; | |
$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)); | |
$km = $r * $c; | |
return $km * 1000; | |
} | |
function decodePolylineToArray($encoded) | |
{ | |
// source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 | |
$length = strlen($encoded); | |
$index = 0; | |
$points = array(); | |
$lat = 0; | |
$lng = 0; | |
while ($index < $length) { | |
// Temporary variable to hold each ASCII byte. | |
$b = 0; | |
// The encoded polyline consists of a latitude value followed by a | |
// longitude value. They should always come in pairs. Read the | |
// latitude value first. | |
$shift = 0; | |
$result = 0; | |
do { | |
// The `ord(substr($encoded, $index++))` statement returns the ASCII | |
// code for the character at $index. Subtract 63 to get the original | |
// value. (63 was added to ensure proper ASCII characters are displayed | |
// in the encoded polyline string, which is `human` readable) | |
$b = ord(substr($encoded, $index++)) - 63; | |
// AND the bits of the byte with 0x1f to get the original 5-bit `chunk. | |
// Then left shift the bits by the required amount, which increases | |
// by 5 bits each time. | |
// OR the value into $results, which sums up the individual 5-bit chunks | |
// into the original value. Since the 5-bit chunks were reversed in | |
// order during encoding, reading them in this way ensures proper | |
// summation. | |
$result|= ($b & 0x1f) << $shift; | |
$shift+= 5; | |
} | |
// Continue while the read byte is >= 0x20 since the last `chunk` | |
// was not OR'd with 0x20 during the conversion process. (Signals the end) | |
while ($b >= 0x20); | |
// Check if negative, and convert. (All negative values have the last bit | |
// set) | |
$dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1)); | |
// Compute actual latitude since value is offset from previous value. | |
$lat+= $dlat; | |
// The next values will correspond to the longitude for this point. | |
$shift = 0; | |
$result = 0; | |
do { | |
$b = ord(substr($encoded, $index++)) - 63; | |
$result|= ($b & 0x1f) << $shift; | |
$shift+= 5; | |
} while ($b >= 0x20); | |
$dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1)); | |
$lng+= $dlng; | |
// The actual latitude and longitude values were multiplied by | |
// 1e5 before encoding so that they could be converted to a 32-bit | |
// integer representation. (With a decimal accuracy of 5 places) | |
// Convert back to original values. | |
$points[] = array( | |
$lat * 1e-5, | |
$lng * 1e-5 | |
); | |
} | |
return $points; | |
} | |
function geocode($query, $giveOptions) | |
{ | |
global $cloudmadeAPIkey; | |
$url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=" . urlencode($query) . "&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true"; | |
$contents = json_decode(getPage($url)); | |
if ($giveOptions) return $contents->features; | |
elseif (isset($contents->features[0]->centroid)) return $contents->features[0]->centroid->coordinates[0] . "," . $contents->features[0]->centroid->coordinates[1]; | |
else return ""; | |
} | |
function reverseGeocode($lat, $lng) | |
{ | |
global $cloudmadeAPIkey; | |
$url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=" . $lat . "," . $lng . "&distance=closest&object_type=road"; | |
$contents = json_decode(getPage($url)); | |
return $contents->features[0]->properties->name; | |
} | |
?> |
<?php | |
function getPage($url) | |
{ | |
debug($url, "json"); | |
$ch = curl_init($url); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 30); | |
$page = curl_exec($ch); | |
if (curl_errno($ch)) echo "<font color=red> Database temporarily unavailable: " . curl_errno($ch) . " " . curl_error($ch) . "</font><br>"; | |
curl_close($ch); | |
debug(print_r($page,true),"json"); | |
return $page; | |
} | |
function curPageURL() | |
{ | |
$isHTTPS = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"); | |
$port = (isset($_SERVER["SERVER_PORT"]) && ((!$isHTTPS && $_SERVER["SERVER_PORT"] != "80") || ($isHTTPS && $_SERVER["SERVER_PORT"] != "443"))); | |
$port = ($port) ? ':' . $_SERVER["SERVER_PORT"] : ''; | |
$url = ($isHTTPS ? 'https://' : 'http://') . $_SERVER["SERVER_NAME"] . $port . htmlentities(dirname($_SERVER['PHP_SELF']) , ENT_QUOTES) . "/"; | |
return $url; | |
} | |
?> |
<?php | |
function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false) | |
{ | |
echo ' | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>' . $pageTitle . '</title>'; | |
if (isDebugServer()) echo '<link rel="stylesheet" href="css/jquery-mobile-1.0a3.css" /> | |
<script type="text/javascript" src="js/jquery-1.5.js"></script> | |
<script type="text/javascript" src="js/jquery-mobile-1.0a3.js"></script>'; | |
else echo '<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.css" /> | |
<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.js"></script> | |
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.js"></script>'; | |
echo ' | |
<link rel="stylesheet" href="css/jquery.ui.datepicker.mobile.css" /> | |
<script> | |
//reset type=date inputs to text | |
$( document ).bind( "mobileinit", function(){ | |
$.mobile.page.prototype.options.degradeInputs.date = true; | |
}); | |
</script> | |
<script src="js/jQuery.ui.datepicker.js"></script> | |
<script src="js/jquery.ui.datepicker.mobile.js"></script> | |
<style type="text/css"> | |
.ui-navbar { | |
width: 100%; | |
} | |
.ui-btn-inner { | |
white-space: normal !important; | |
} | |
.ui-li-heading { | |
white-space: normal !important; | |
} | |
.ui-listview-filter { | |
margin: 0 !important; | |
} | |
.ui-icon-navigation { | |
background-image: url(css/images/113-navigation.png); | |
background-position: 1px 0; | |
} | |
#footer { | |
text-size: 0.75em; | |
text-align: center; | |
} | |
body { | |
background-color: #F0F0F0; | |
} | |
</style> | |
<meta name="apple-mobile-web-app-capable" content="yes" /> | |
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> | |
<link rel="apple-touch-startup-image" href="startup.png" /> | |
<link rel="apple-touch-icon" href="apple-touch-icon.png" />'; | |
if ($geolocate) { | |
echo "<script> | |
function success(position) { | |
$('#geolocate').val(position.coords.latitude+','+position.coords.longitude); | |
$.ajax({ url: \"common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude }); | |
$('#here').click(function(event) { $('#geolocate').val(doAJAXrequestForGeolocSessionHere()); return false;}); | |
$('#here').show(); | |
} | |
function error(msg) { | |
console.log(msg); | |
} | |
if (navigator.geolocation) { | |
var options = { | |
enableHighAccuracy: false, | |
timeout: 60000, | |
maximumAge: 10000 | |
} | |
navigator.geolocation.getCurrentPosition(success, error, options); | |
} | |
</script> "; | |
} | |
echo '</head> | |
<body> | |
'; | |
if (isMetricsOn()) { | |
require_once ('owa/owa_env.php'); | |
require_once (OWA_DIR . 'owa_php.php'); | |
$owa = new owa_php(); | |
global $owaSiteID; | |
$owa->setSiteId($owaSiteID); | |
$owa->setPageTitle($pageTitle); | |
$owa->setPageType($pageType); | |
$owa->trackPageView(); | |
$owa->placeHelperPageTags(); | |
} | |
if ($opendiv) { | |
echo '<div data-role="page"> | |
<script> | |
$(document).ready(function () | |
{ | |
document.title = "' . $pageTitle . '"; | |
}); | |
</script> | |
<div data-role="header"> | |
<h1>' . $pageTitle . '</h1> | |
</div><!-- /header --> | |
<div data-role="content"> '; | |
} | |
} | |
function include_footer() | |
{ | |
if ($geolocate && isset($_SESSION['lat'])) { | |
echo "<script> | |
$('#here').click(function(event) { $('#geolocate').val(doAJAXrequestForGeolocSessionHere()); return false;}); | |
$('#here').show(); | |
</script>"; | |
} | |
echo '<div id="footer"><a href="about.php">About/Contact Us</a> <a href="feedback.php">Feedback/Bug Report</a></a>'; | |
echo '</div>'; | |
} | |
function timePlaceSettings($geolocate = false) | |
{ | |
global $service_periods; |