From: Alexander Sadleir Date: Sat, 04 Feb 2012 08:56:43 +0000 Subject: Upgrade graphs to Flotr2 X-Git-Url: http://maxious.lambdacomplex.org/git/?p=busui.git&a=commitdiff&h=7cfc800a9181a84676e5e33ff428664dc47b4c2b --- Upgrade graphs to Flotr2 --- --- /dev/null +++ b/.gitmodules @@ -1,1 +1,7 @@ +[submodule "js/flotr2"] + path = js/flotr2 + url = https://github.com/HumbleSoftware/Flotr2.git +[submodule "js/FlashCanvas"] + path = js/FlashCanvas + url = https://github.com/timcameronryan/FlashCanvas --- a/about.php +++ b/about.php @@ -34,8 +34,9 @@
Some icons by Joseph Wain / glyphish.com
Native clients also available for iPhone(cbrTimetable by Sandor Kolotenko - , ACT Buses by David Sullivan) - , Android (MyBus 2.0 by Imagine Team) + , ACT Buses by David Sullivan, Bus Trips ACT by Molson Chengalath) + , Android (MyBus 2.0 by Imagine Team, GetMe2 Canberra by +Colin Thompson ) and Windows Phone 7 (TransHub Canberra by Soul Solutions) Other web clients include iTranzit.
GTFS-realtime API: --- a/aws/busuidb.sh +++ b/aws/busuidb.sh @@ -7,7 +7,8 @@ psql -d transitdata -f /var/www/transitdata.cbrfeed.sql #createuser transitdata -SDRP #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\ +#,servicealerts_alerts,servicealerts_informed 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;" @@ -15,3 +16,4 @@ ##SELECT '', 'public', 'shapes', 'shape_pt', ST_CoordDim(shape_pt), ST_SRID(shape_pt), GeometryType(shape_pt) ##FROM shapes LIMIT 1; php /var/www/updatedb.php + --- a/geo/route.kml.php +++ b/geo/route.kml.php @@ -1,30 +1,105 @@ '; echo ' - + + + '; + + + '; $route = getRoute($routeid); - echo "\n\n"; - $link = curPageURL()."/../trip.php?routeid=".htmlspecialchars ($route["route_id"]); - echo "".$route['route_short_name'].""; - echo ''; - echo ''.$route['route_short_name']." ".$route['route_long_name']."]]> "; -echo "#yellowLineGreenPoly"; +echo "\n\n"; +$_REQUEST['time'] = "12:00"; +$trip = getRouteNextTrip($routeid, 0); +$link = curPageURL() . "/../trip.php?routeid=" . htmlspecialchars($route["route_id"]. "&directionid=0&tripid=".$trip['trip_id']) ; +echo "" . $route['route_short_name'] . " Direction 0 "; +echo ''; +echo '' . $route['route_short_name'] . " Direction 0]]> "; +echo "#yellowLineYellowPoly"; - $trips = getRouteTrips($routeid); - echo getTripShape($trips[0]['trip_id']); +echo getTripShape($trip['trip_id']); + echo "\n"; +$stops = Array(); +foreach (getTripStops($trip['trip_id']) as $stop) { + $stop['style'] = "#ylw-pushpin"; + $stops[$stop['stop_id']] = $stop; +} -echo "\n\n"; + +echo "\n\n"; +$trip = getRouteNextTrip($routeid, 1); +$link = curPageURL() . "/../trip.php?routeid=" . htmlspecialchars($route["route_id"]. "&directionid=1&tripid=".$trip['trip_id']) ; +echo "" . $route['route_short_name'] . " Direction 1 "; +echo ''; +echo '' . $route['route_short_name'] . " Direction 1]]> "; +echo "#blueLineBluePoly"; + +echo getTripShape($trip['trip_id']); + echo "\n"; +foreach (getTripStops($trip['trip_id']) as $stop) { + if (isset($stops[$stop['stop_id']])) { + $stop['style'] = "#grn-pushpin"; + } else { + $stop['style'] = "#blue-pushpin"; + } + $stops[$stop['stop_id']] = $stop; +} +foreach ($stops as $stop) { + echo "\n\n"; + $link = curPageURL() . '/../stop.php?stopid=' . htmlspecialchars($stop['stop_id']); + echo "" . htmlspecialchars($stop['stop_name']) . ""; + echo ''; + echo '' . htmlspecialchars($stop['stop_name']) . "]]> "; + echo "" . $stop['style'] . ""; + echo $stop['positionkml']; + echo "\n"; +} + +echo "\n"; ?> --- a/geo/stops.kml.php +++ b/geo/stops.kml.php @@ -1,11 +1,13 @@ createElementNS('http://earth.google.com/kml/2.1', 'kml'); +$node = $dom->createElementNS('http://www.opengis.net/kml/2.2', 'kml'); $parNode = $dom->appendChild($node); // Creates a KML Document element and append it to the KML element. $dnode = $dom->createElement('Document'); @@ -13,7 +15,7 @@ if ($suburb != "") $result_stops = getStopsBySuburb($suburb); else $result_stops = getStops(); foreach ($result_stops as $stop) { - $description = 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] . "
"; + $description = 'View stop page
'; // Creates a Placemark and append it to the Document. $node = $dom->createElement('Placemark'); $placeNode = $docNode->appendChild($node); --- /dev/null +++ b/geo/trip.kml.php @@ -1,1 +1,70 @@ + +'; +echo ' + + + + '; +$trip = getTrip($tripid); +echo "\n\n"; +$link = curPageURL() . "/../trip.php?tripid=" . htmlspecialchars($$tripid); +echo "" . $tripid . ""; +echo ''; +echo '' . $tripid . "]]> "; +echo "#yellowLineGreenPoly"; + +echo getTripShape($tripid); + +echo "\n"; +foreach (getTripStopTimes($tripid) as $stop) { + echo "\n\n"; + $link = curPageURL() . '/../trip.php?tripid=' . htmlspecialchars($tripid); + echo "" . $stop['arrival_time'] . " @ " . htmlspecialchars($stop['stop_name']) . ""; + echo ''; + echo '' . htmlspecialchars($stop['stop_name']) . "]]> "; + echo "#blue-pushpin"; + echo "" . $stop['stop_lon'] . "," . $stop['stop_lat'] . ""; + + echo "\n"; +} +echo "\n"; +?> + + --- a/include/common-auth.inc.php +++ b/include/common-auth.inc.php @@ -30,4 +30,4 @@ login(); } } -?> + --- a/include/common-db.inc.php +++ b/include/common-db.inc.php @@ -27,12 +27,13 @@ } function databaseError($errMsg) { - die($errMsg); + if ($errMsg[1] != "") { + die(print_r($errMsg,true)); + } } include ('db/route-dao.inc.php'); include ('db/trip-dao.inc.php'); include ('db/stop-dao.inc.php'); include ('db/servicealert-dao.inc.php'); -?> --- a/include/common-geo.inc.php +++ b/include/common-geo.inc.php @@ -168,5 +168,3 @@ return $contents->features[0]->properties->name; } -?> - --- a/include/common-net.inc.php +++ b/include/common-net.inc.php @@ -35,7 +35,6 @@ 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"))); @@ -44,5 +43,4 @@ return $url; } -?> --- a/include/common-request.inc.php +++ b/include/common-request.inc.php @@ -60,13 +60,16 @@ if (isset($_REQUEST['tripid'])) { $tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_STRING); } +if (isset($_REQUEST['routeid'])) { + $routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_STRING); +} +if (isset($_REQUEST['directionid'])) { + $directionid = filter_var($_REQUEST['directionid'], FILTER_SANITIZE_STRING); +} if (isset($_REQUEST['stopid'])) { $stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); -} -if (isset($_REQUEST['routeid'])) { - $routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT); } if (isset($_REQUEST['geolocate'])) { $geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL); } -?> + --- a/include/common-session.inc.php +++ b/include/common-session.inc.php @@ -17,14 +17,6 @@ */ // you have to open the session to be able to modify or remove it session_start(); -if (isset($_REQUEST['service_period'])) { - $_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING); - sessionUpdated(); -} -if (isset($_REQUEST['time'])) { - $_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); - sessionUpdated(); -} if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") { $geocoded = false; if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { @@ -69,9 +61,10 @@ } //debug(print_r($_SESSION, true) , "session"); -function current_time() { - return ($_SESSION['time'] ? $_SESSION['time'] : date("H:i:s")); +function current_time($time = "") { + if (isset($_REQUEST['time'])) return $_REQUEST['time']; + else if ($time != "") date("H:i:s",$time); + else return date("H:i:s"); } -?> --- a/include/common-template.inc.php +++ b/include/common-template.inc.php @@ -54,7 +54,7 @@ '; - $jqmVersion = "1.0"; + $jqmVersion = "1.0.1"; if (isDebugServer()) { $jqmcss = $basePath . "css/jquery.mobile-$jqmVersion.css"; $jqjs = $basePath . "js/jquery-1.6.4.min.js"; @@ -175,7 +175,7 @@
'; if ($GTFSREnabled) { $overrides = getServiceOverride(); - if ($overrides['service_id']) { + if (isset($overrides['service_id'])) { if ($overrides['service_id'] == "noservice") { echo '
Buses are not running today due to industrial action/public holiday. See http://www.action.act.gov.au for details.
'; @@ -212,9 +212,37 @@ } echo "\n
"; } - +function timeSettings() { + global $service_periods; +echo '
+

Change Time (' . (isset($_REQUEST['time']) ? $_REQUEST['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...

+
+ + + + +
+
+ + + Current Time? +
+
+ + + +
+ + +
+
'; +} function placeSettings() { - global $service_periods; + $geoerror = false; $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; @@ -276,5 +304,4 @@ return ""; } } -?> - + --- a/include/common-transit.inc.php +++ b/include/common-transit.inc.php @@ -23,15 +23,18 @@ function service_period($date = "") { - if (isset($_SESSION['service_period'])) - return $_SESSION['service_period']; + if (isset($_REQUEST['service_period'])) { + return $_REQUEST['service_period']; + } + $override = getServiceOverride($date); - if ($override['service_id']) { - $idParts = explode("-",$override['service_id']); - return strtolower($idParts[2]); - } - - switch (date('w', ($date != "" ? $date : time()))) { + if (isset($override['service_id'])) { + return strtolower($override['service_id']); + } + $date = ($date != "" ? $date : time()); + $dow = date('w', $date); + + switch ($dow) { case 0: return 'sunday'; case 6: @@ -40,16 +43,28 @@ return 'weekday'; } } -function service_ids($service_period) { + +function service_ids($service_period, $date = "") { switch ($service_period) { case 'sunday': - return Array("2010-TUGGSUN-Sunday-20","2010-BELCSUN-Sunday-19"); + return Array("Sunday", "Sunday"); case 'saturday': - return Array("2010-BELCSAT-Saturday-19","2010-TUGGSAT-Saturday-19"); + return Array("Saturday", "Saturday"); default: - //return 'weekday'; - return Array("2010-BELCMAST-Weekday-15","2010-TUGGMAST-Weekday-14"); - } + $date = ($date != "" ? $date : time()); +// school holidays + $ymd = date('Ymd', $date); + $dow = date('w', $date); + if (intval($ymd) < "20120203" && $dow != 0 && $dow != 6) { + return Array("Weekday-SchoolVacation", "Weekday-SchoolVacation"); + } else { + return Array("Weekday", "Weekday"); + } + } +} + +function valid_service_ids() { + return array_merge(service_ids(""), service_ids('saturday'), service_ids('sunday')); } function midnight_seconds($time = "") { @@ -286,5 +301,4 @@ } } -?> - + --- a/include/common.inc.php +++ b/include/common.inc.php @@ -57,7 +57,7 @@ function isDebugServer() { return php_sapi_name() == "cli" || strstr(php_uname('n'),"actbus") || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == "azusa" || $_SERVER['SERVER_NAME'] == "vanille" - || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || $_SERVER['SERVER_NAME'] == "192.168.1.8"); + || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || $_SERVER['SERVER_NAME'] == "192.168.1.8" || $_SERVER['SERVER_NAME'] == "192.168.178.24"); } include_once ("common-geo.inc.php"); @@ -201,6 +201,3 @@ return implode($glue, $retVal); } - -?> - --- a/include/db/route-dao.inc.php +++ b/include/db/route-dao.inc.php @@ -29,6 +29,7 @@ } return $query->fetch(PDO :: FETCH_ASSOC); } + function getRoutesByShortName($routeShortName) { global $conn; $query = "Select distinct route_id, route_short_name from routes where route_short_name = :routeShortName"; @@ -45,8 +46,11 @@ function getRouteHeadsigns($routeID) { global $conn; - $query = "select distinct stops.stop_name, trip_headsign,direction_id from routes join trips on trips.route_id = routes.route_id -join stop_times on stop_times.trip_id = trips.trip_id join stops on stop_times.stop_id = stops.stop_id where trips.route_id = :routeID and stop_times.stop_sequence = 1"; + $query = "select stops.stop_name, trip_headsign, direction_id,max(service_id) as service_id, count(*) + from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id join stops on +stop_times.stop_id = stops.stop_id where trips.route_id = :routeID +and stop_times.stop_sequence = 1 group by stops.stop_name, trip_headsign, direction_id having count(*) > 2"; debug($query, "database"); $query = $conn->prepare($query); $query->bindParam(":routeID", $routeID); @@ -55,9 +59,14 @@ databaseError($conn->errorInfo()); return Array(); } -return $query->fetchAll(); -} - + return $query->fetchAll(); +} +function getRouteDescription($routeID, $directionID) { + $trip = getRouteNextTrip($routeID, $directionID); + $start = getTripStartingPoint($trip['trip_id']); + $end = getTripDestination($trip['trip_id']); + return "From ".$start['stop_name']." to ".$end['stop_name']; +} function getRouteByFullName($routeFullName) { global $conn; $query = "Select * from routes where route_short_name||route_long_name = :routeFullName LIMIT 1"; @@ -77,30 +86,6 @@ $query = "Select * from routes order by route_short_name;"; debug($query, "database"); $query = $conn->prepare($query); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} - -function getRoutesByNumber($routeNumber = "") { - global $conn; - if ($routeNumber != "") { - $query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id = -routes.route_id join stop_times on stop_times.trip_id = trips.trip_id -where route_short_name = :routeNumber OR route_short_name LIKE :routeNumber2 order by route_short_name;"; - } else { - $query = "SELECT DISTINCT route_short_name from routes order by route_short_name"; - } - debug($query, "database"); - $query = $conn->prepare($query); - if ($routeNumber != "") { - $query->bindParam(":routeNumber", $routeNumber); - $routeNumber2 = "% " . $routeNumber; - $query->bindParam(":routeNumber2", $routeNumber2); - } $query->execute(); if (!$query) { databaseError($conn->errorInfo()); @@ -132,31 +117,43 @@ return $query->fetchAll(); } -function getRouteNextTrip($routeID) { - global $conn; - $query = "select * from routes join trips on trips.route_id = routes.route_id -join stop_times on stop_times.trip_id = trips.trip_id where -arrival_time > :currentTime and routes.route_id = :routeID order by +function getRouteNextTrip($routeID, $directionID) { + global $conn; + + $query = "select routes.route_id,direction_id,trips.trip_id,trip_headsign,departure_time from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id where arrival_time between :currentTime and :futureTime +and routes.route_id = :routeID and trips.direction_id = :directionID order by arrival_time limit 1"; debug($query, "database"); $query = $conn->prepare($query); $query->bindParam(":currentTime", current_time()); + $futureTime = current_time(strtotime(current_time() ." +2h")); + if (date("h",strtotime(current_time()) > 22)) $futureTime = "23:59:59"; + $query->bindParam(":futureTime", $futureTime); $query->bindParam(":routeID", $routeID); - $query->execute(); + $query->bindParam(":directionID", $directionID); + $query->execute(); + databaseError($conn->errorInfo()); if (!$query) { databaseError($conn->errorInfo()); return Array(); } $r = $query->fetch(PDO :: FETCH_ASSOC); - - // past last trip of the day special case - if (sizeof($r) < 16) { - $query = "select * from routes join trips on trips.route_id = routes.route_id -join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID order by + return $r; +} + +function getRouteFirstTrip($routeID,$directionID) { + global $conn; + + $query = "select * from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID +and trips.direction_id = :directionID order by arrival_time DESC limit 1"; debug($query, "database"); $query = $conn->prepare($query); $query->bindParam(":routeID", $routeID); + + $query->bindParam(":directionID", $directionID); $query->execute(); if (!$query) { databaseError($conn->errorInfo()); @@ -164,12 +161,11 @@ } $r = $query->fetch(PDO :: FETCH_ASSOC); - } - return $r; -} - -function getRouteAtStop($routeID, $stop_id) { - $nextTrip = getRouteNextTrip($routeID); + return $r; +} + +function getRouteAtStop($routeID, $directionID, $stop_id) { + $nextTrip = getRouteNextTrip($routeID, $directionID); if ($nextTrip['trip_id']) { foreach (getTripStopTimes($nextTrip['trip_id']) as $tripStop) { if ($tripStop['stop_id'] == $stop_id) @@ -179,40 +175,59 @@ return Array(); } -function getRouteTrips($routeID) { - global $conn; - $query = "select routes.route_id,trips.trip_id,service_id,arrival_time, stop_id, stop_sequence from routes join trips on trips.route_id = routes.route_id -join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID and stop_sequence = '1' order by -arrival_time "; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":routeID", $routeID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} - -function getRoutesByDestination($destination = "", $service_period = "") { +function getRouteTrips($routeID, $directionID = "", $service_period = "") { global $conn; if ($service_period == "") $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + $directionSQL = ""; + if ($directionID != "") + $directionSQL = " and direction_id = :directionID "; + $query = "select routes.route_id,trips.trip_id,service_id,arrival_time, stop_id, stop_sequence from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id where (service_id=:service_periodA OR service_id=:service_periodB) +AND (routes.route_id = :routeID) " . $directionSQL . " and stop_sequence = '1' order by +arrival_time "; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":routeID", $routeID); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); + if ($directionSQL != "") + $query->bindParam(":directionID", $directionID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRoutesByDestination($destination = "", $service_period = "") { + global $conn; + if ($service_period == "") + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; if ($destination != "") { - $query = "SELECT DISTINCT trips.route_id,route_short_name,route_long_name, service_id + /* $query = "SELECT DISTINCT trips.route_id,route_short_name,route_long_name, service_id FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id -WHERE route_long_name = :destination AND service_id=:service_period order by route_short_name"; +WHERE route_long_name = :destination AND (service_id=:service_periodA OR service_id=:service_periodB) + order by route_short_name";*/ + $query = "select route_id, direction_id, stop_name, b.trip_id, b.stop_sequence from (select route_id, direction_id, max(stop_sequence) as stop_sequence, max(a.trip_id) as trip_id from stop_times inner join (SELECT route_id, direction_id, max(trip_id) as trip_id + from trips group by route_id,direction_id) as a on stop_times.trip_id = a.trip_id group by route_id, direction_id) as b inner join stop_times on b.trip_id = stop_times.trip_id inner join stops on stop_times.stop_id = stops.stop_id where stop_times.stop_sequence = b.stop_sequence and stop_name = :destination order by route_id;"; } else { - $query = "SELECT DISTINCT route_long_name -FROM stop_times join trips on trips.trip_id = -stop_times.trip_id join routes on trips.route_id = routes.route_id -WHERE service_id= :service_period order by route_long_name"; - } - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); + $query = "select stop_name from (select route_id, direction_id, max(stop_sequence) as stop_sequence, max(a.trip_id) as trip_id from stop_times inner join (SELECT route_id, direction_id, max(trip_id) as trip_id + from trips group by route_id,direction_id) as a on stop_times.trip_id = a.trip_id group by route_id, direction_id) as b inner join stop_times on b.trip_id = stop_times.trip_id inner join stops on stop_times.stop_id = stops.stop_id where stop_times.stop_sequence = b.stop_sequence group by stop_name order by stop_name;"; + } + debug($query, "database"); + $query = $conn->prepare($query); + + //$query->bindParam(":service_periodA", $sidA); + //$query->bindParam(":service_periodB", $sidB); if ($destination != "") $query->bindParam(":destination", $destination); $query->execute(); @@ -226,35 +241,41 @@ function getRoutesBySuburb($suburb, $service_period = "") { if ($service_period == "") $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + global $conn; $query = "SELECT DISTINCT service_id,trips.route_id,route_short_name,route_long_name FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id join stops on stops.stop_id = stop_times.stop_id -WHERE zone_id LIKE ':suburb AND service_id=:service_period ORDER BY route_short_name"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); - $suburb = "%" . $suburb . ";%"; +WHERE stop_desc LIKE :suburb AND (service_id=:service_periodA OR service_id=:service_periodB) + ORDER BY route_short_name"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); + $suburb = "%Suburb: %" . $suburb . "%"; $query->bindParam(":suburb", $suburb); $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } + + databaseError($conn->errorInfo()); + return $query->fetchAll(); } function getRoutesNearby($lat, $lng, $limit = "", $distance = 500) { - if ($service_period == "") + // if ($service_period == "") $service_period = service_period(); - $service_ids = service_ids($service_period); + $service_ids = service_ids($service_period); $sidA = $service_ids[0]; $sidB = $service_ids[1]; - if ($limit != "") + $limitSQL = ""; + if ($limit != "") $limitSQL = " LIMIT :limit "; global $conn; - $query = "SELECT service_id,trips.route_id,route_short_name,route_long_name,min(stops.stop_id) as stop_id, + $query = "SELECT service_id,trips.route_id,trips.direction_id,route_short_name,route_long_name,min(stops.stop_id) as stop_id, min(ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE)) as distance FROM stop_times join trips on trips.trip_id = stop_times.trip_id @@ -262,7 +283,7 @@ join stops on stops.stop_id = stop_times.stop_id WHERE (service_id=:service_periodA OR service_id=:service_periodB) AND ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), :distance, FALSE) - group by service_id,trips.route_id,route_short_name,route_long_name + group by service_id,trips.route_id,trips.direction_id,route_short_name,route_long_name order by distance $limitSQL"; debug($query, "database"); $query = $conn->prepare($query); @@ -279,4 +300,3 @@ return $query->fetchAll(); } -?> --- a/include/db/servicealert-dao.inc.php +++ b/include/db/servicealert-dao.inc.php @@ -174,4 +174,3 @@ return null; } -?> --- a/include/db/stop-dao.inc.php +++ b/include/db/stop-dao.inc.php @@ -46,7 +46,7 @@ } } $query .= " order by stop_name;"; - debug($query,"database"); + debug($query, "database"); $query = $conn->prepare($query); if ($firstLetter != "") $query->bindParam(":firstLetter", $firstLetter); @@ -167,16 +167,16 @@ if ($service_period == "") { $service_period = service_period(); } - $service_ids = service_ids($service_period); + $service_ids = service_ids($service_period); $sidA = $service_ids[0]; $sidB = $service_ids[1]; $limitSQL = ""; if ($limit != "") $limitSQL .= " LIMIT :limit "; - + global $conn; if ($afterTime != "") { - $query = " SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name,end_times.arrival_time as end_time + $query = " SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,trips.direction_id,trips.trip_headsign,route_short_name,route_long_name,end_times.arrival_time as end_time FROM stop_times join trips on trips.trip_id = stop_times.trip_id @@ -184,7 +184,7 @@ WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times WHERE stop_times.stop_id = :stopID AND stop_times.trip_id = end_times.trip_id -AND (service_id=:service_periodA OR service_id=:service_periodB) ".($route_short_name != "" ? " AND route_short_name = :route_short_name ":"")." +AND (service_id=:service_periodA OR service_id=:service_periodB) " . ($route_short_name != "" ? " AND route_short_name = :route_short_name " : "") . " AND end_times.arrival_time > :afterTime ORDER BY end_time $limitSQL"; } else { @@ -194,7 +194,7 @@ stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_times.stop_id = :stopID -AND (service_id=:service_periodA OR service_id=:service_periodB) ".($route_short_name != "" ? " AND route_short_name = :route_short_name ":"")." +AND (service_id=:service_periodA OR service_id=:service_periodB) " . ($route_short_name != "" ? " AND route_short_name = :route_short_name " : "") . " ORDER BY arrival_time $limitSQL"; } debug($query, "database"); @@ -247,4 +247,3 @@ return $timedTrips; } -?> --- a/include/db/trip-dao.inc.php +++ b/include/db/trip-dao.inc.php @@ -35,7 +35,7 @@ } function getTripStops($tripID) { global $conn; - $query = "SELECT stop_id, stop_name, ST_AsKML(position) as positionkml, + $query = "SELECT stops.stop_id, stop_name, ST_AsKML(position) as positionkml, stop_sequence, trips.trip_id FROM stop_times join trips on trips.trip_id = stop_times.trip_id @@ -49,7 +49,7 @@ databaseError($conn->errorInfo()); return Array(); } - return $query->fetchColumn(0); + return $query->fetchAll(); } function getTripShape($tripID) { // todo, use shapes table if shape_id specified @@ -78,7 +78,7 @@ join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id join stops on stops.stop_id = stop_times.stop_id -WHERE trips.trip_id = :tripID $range ORDER BY stop_sequence"; +WHERE trips.trip_id = :tripID ORDER BY stop_sequence"; debug($query, "database"); $query = $conn->prepare($query); $query->bindParam(":tripID", $tripID); @@ -132,6 +132,22 @@ } $r = $query->fetch(PDO :: FETCH_ASSOC); return $r['arrival_time']; +} +function getTripStartingPoint($tripID) { + global $conn; + $query = "SELECT stops.stop_id, stops.stop_name, stops.stop_desc + from stop_times inner join stops on stop_times.stop_id = stops.stop_id + WHERE trip_id = :tripID and stop_sequence = '1' limit 1"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; } function getTripDestination($tripID) { @@ -187,6 +203,3 @@ } return $query->fetchAll(); } - - -?> --- a/index.php +++ b/index.php @@ -20,7 +20,7 @@
-

busness time


Canberra Bus Timetables and Trip Planner +

busness time


Canberra Bus Timetables and Trip Planner
Launch Trip Planner... @@ -37,9 +37,9 @@
  • Routes By Suburb
  • Nearby Routes
  • + Busness R&D + MyWay Balance and Timeliness Survey Results Busness R&D'; - echo ' MyWay Balance and Timeliness Survey Results'; include_footer(true) ?> --- /dev/null +++ b/js/FlashCanvas --- a/js/flot/excanvas.js +++ /dev/null @@ -1,1428 +1,1 @@ -// Copyright 2006 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Known Issues: -// -// * Patterns only support repeat. -// * Radial gradient are not implemented. The VML version of these look very -// different from the canvas one. -// * Clipping paths are not implemented. -// * Coordsize. The width and height attribute have higher priority than the -// width and height style values which isn't correct. -// * Painting mode isn't implemented. -// * Canvas width/height should is using content-box by default. IE in -// Quirks mode will draw the canvas using border-box. Either change your -// doctype to HTML5 -// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) -// or use Box Sizing Behavior from WebFX -// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) -// * Non uniform scaling does not correctly scale strokes. -// * Filling very large shapes (above 5000 points) is buggy. -// * Optimize. There is always room for speed improvements. - -// Only add this code if we do not already have a canvas implementation -if (!document.createElement('canvas').getContext) { - -(function() { - - // alias some functions to make (compiled) code shorter - var m = Math; - var mr = m.round; - var ms = m.sin; - var mc = m.cos; - var abs = m.abs; - var sqrt = m.sqrt; - - // this is used for sub pixel precision - var Z = 10; - var Z2 = Z / 2; - - /** - * This funtion is assigned to the elements as element.getContext(). - * @this {HTMLElement} - * @return {CanvasRenderingContext2D_} - */ - function getContext() { - return this.context_ || - (this.context_ = new CanvasRenderingContext2D_(this)); - } - - var slice = Array.prototype.slice; - - /** - * Binds a function to an object. The returned function will always use the - * passed in {@code obj} as {@code this}. - * - * Example: - * - * g = bind(f, obj, a, b) - * g(c, d) // will do f.call(obj, a, b, c, d) - * - * @param {Function} f The function to bind the object to - * @param {Object} obj The object that should act as this when the function - * is called - * @param {*} var_args Rest arguments that will be used as the initial - * arguments when the function is called - * @return {Function} A new function that has bound this - */ - function bind(f, obj, var_args) { - var a = slice.call(arguments, 2); - return function() { - return f.apply(obj, a.concat(slice.call(arguments))); - }; - } - - function encodeHtmlAttribute(s) { - return String(s).replace(/&/g, '&').replace(/"/g, '"'); - } - - function addNamespacesAndStylesheet(doc) { - // create xmlns - if (!doc.namespaces['g_vml_']) { - doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', - '#default#VML'); - - } - if (!doc.namespaces['g_o_']) { - doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', - '#default#VML'); - } - - // Setup default CSS. Only add one style sheet per document - if (!doc.styleSheets['ex_canvas_']) { - var ss = doc.createStyleSheet(); - ss.owningElement.id = 'ex_canvas_'; - ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + - // default size is 300x150 in Gecko and Opera - 'text-align:left;width:300px;height:150px}'; - } - } - - // Add namespaces and stylesheet at startup. - addNamespacesAndStylesheet(document); - - var G_vmlCanvasManager_ = { - init: function(opt_doc) { - if (/MSIE/.test(navigator.userAgent) && !window.opera) { - var doc = opt_doc || document; - // Create a dummy element so that IE will allow canvas elements to be - // recognized. - doc.createElement('canvas'); - doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); - } - }, - - init_: function(doc) { - // find all canvas elements - var els = doc.getElementsByTagName('canvas'); - for (var i = 0; i < els.length; i++) { - this.initElement(els[i]); - } - }, - - /** - * Public initializes a canvas element so that it can be used as canvas - * element from now on. This is called automatically before the page is - * loaded but if you are creating elements using createElement you need to - * make sure this is called on the element. - * @param {HTMLElement} el The canvas element to initialize. - * @return {HTMLElement} the element that was created. - */ - initElement: function(el) { - if (!el.getContext) { - el.getContext = getContext; - - // Add namespaces and stylesheet to document of the element. - addNamespacesAndStylesheet(el.ownerDocument); - - // Remove fallback content. There is no way to hide text nodes so we - // just remove all childNodes. We could hide all elements and remove - // text nodes but who really cares about the fallback content. - el.innerHTML = ''; - - // do not use inline function because that will leak memory - el.attachEvent('onpropertychange', onPropertyChange); - el.attachEvent('onresize', onResize); - - var attrs = el.attributes; - if (attrs.width && attrs.width.specified) { - // TODO: use runtimeStyle and coordsize - // el.getContext().setWidth_(attrs.width.nodeValue); - el.style.width = attrs.width.nodeValue + 'px'; - } else { - el.width = el.clientWidth; - } - if (attrs.height && attrs.height.specified) { - // TODO: use runtimeStyle and coordsize - // el.getContext().setHeight_(attrs.height.nodeValue); - el.style.height = attrs.height.nodeValue + 'px'; - } else { - el.height = el.clientHeight; - } - //el.getContext().setCoordsize_() - } - return el; - } - }; - - function onPropertyChange(e) { - var el = e.srcElement; - - switch (e.propertyName) { - case 'width': - el.getContext().clearRect(); - el.style.width = el.attributes.width.nodeValue + 'px'; - // In IE8 this does not trigger onresize. - el.firstChild.style.width = el.clientWidth + 'px'; - break; - case 'height': - el.getContext().clearRect(); - el.style.height = el.attributes.height.nodeValue + 'px'; - el.firstChild.style.height = el.clientHeight + 'px'; - break; - } - } - - function onResize(e) { - var el = e.srcElement; - if (el.firstChild) { - el.firstChild.style.width = el.clientWidth + 'px'; - el.firstChild.style.height = el.clientHeight + 'px'; - } - } - - G_vmlCanvasManager_.init(); - - // precompute "00" to "FF" - var decToHex = []; - for (var i = 0; i < 16; i++) { - for (var j = 0; j < 16; j++) { - decToHex[i * 16 + j] = i.toString(16) + j.toString(16); - } - } - - function createMatrixIdentity() { - return [ - [1, 0, 0], - [0, 1, 0], - [0, 0, 1] - ]; - } - - function matrixMultiply(m1, m2) { - var result = createMatrixIdentity(); - - for (var x = 0; x < 3; x++) { - for (var y = 0; y < 3; y++) { - var sum = 0; - - for (var z = 0; z < 3; z++) { - sum += m1[x][z] * m2[z][y]; - } - - result[x][y] = sum; - } - } - return result; - } - - function copyState(o1, o2) { - o2.fillStyle = o1.fillStyle; - o2.lineCap = o1.lineCap; - o2.lineJoin = o1.lineJoin; - o2.lineWidth = o1.lineWidth; - o2.miterLimit = o1.miterLimit; - o2.shadowBlur = o1.shadowBlur; - o2.shadowColor = o1.shadowColor; - o2.shadowOffsetX = o1.shadowOffsetX; - o2.shadowOffsetY = o1.shadowOffsetY; - o2.strokeStyle = o1.strokeStyle; - o2.globalAlpha = o1.globalAlpha; - o2.font = o1.font; - o2.textAlign = o1.textAlign; - o2.textBaseline = o1.textBaseline; - o2.arcScaleX_ = o1.arcScaleX_; - o2.arcScaleY_ = o1.arcScaleY_; - o2.lineScale_ = o1.lineScale_; - } - - var colorData = { - aliceblue: '#F0F8FF', - antiquewhite: '#FAEBD7', - aquamarine: '#7FFFD4', - azure: '#F0FFFF', - beige: '#F5F5DC', - bisque: '#FFE4C4', - black: '#000000', - blanchedalmond: '#FFEBCD', - blueviolet: '#8A2BE2', - brown: '#A52A2A', - burlywood: '#DEB887', - cadetblue: '#5F9EA0', - chartreuse: '#7FFF00', - chocolate: '#D2691E', - coral: '#FF7F50', - cornflowerblue: '#6495ED', - cornsilk: '#FFF8DC', - crimson: '#DC143C', - cyan: '#00FFFF', - darkblue: '#00008B', - darkcyan: '#008B8B', - darkgoldenrod: '#B8860B', - darkgray: '#A9A9A9', - darkgreen: '#006400', - darkgrey: '#A9A9A9', - darkkhaki: '#BDB76B', - darkmagenta: '#8B008B', - darkolivegreen: '#556B2F', - darkorange: '#FF8C00', - darkorchid: '#9932CC', - darkred: '#8B0000', - darksalmon: '#E9967A', - darkseagreen: '#8FBC8F', - darkslateblue: '#483D8B', - darkslategray: '#2F4F4F', - darkslategrey: '#2F4F4F', - darkturquoise: '#00CED1', - darkviolet: '#9400D3', - deeppink: '#FF1493', - deepskyblue: '#00BFFF', - dimgray: '#696969', - dimgrey: '#696969', - dodgerblue: '#1E90FF', - firebrick: '#B22222', - floralwhite: '#FFFAF0', - forestgreen: '#228B22', - gainsboro: '#DCDCDC', - ghostwhite: '#F8F8FF', - gold: '#FFD700', - goldenrod: '#DAA520', - grey: '#808080', - greenyellow: '#ADFF2F', - honeydew: '#F0FFF0', - hotpink: '#FF69B4', - indianred: '#CD5C5C', - indigo: '#4B0082', - ivory: '#FFFFF0', - khaki: '#F0E68C', - lavender: '#E6E6FA', - lavenderblush: '#FFF0F5', - lawngreen: '#7CFC00', - lemonchiffon: '#FFFACD', - lightblue: '#ADD8E6', - lightcoral: '#F08080', - lightcyan: '#E0FFFF', - lightgoldenrodyellow: '#FAFAD2', - lightgreen: '#90EE90', - lightgrey: '#D3D3D3', - lightpink: '#FFB6C1', - lightsalmon: '#FFA07A', - lightseagreen: '#20B2AA', - lightskyblue: '#87CEFA', - lightslategray: '#778899', - lightslategrey: '#778899', - lightsteelblue: '#B0C4DE', - lightyellow: '#FFFFE0', - limegreen: '#32CD32', - linen: '#FAF0E6', - magenta: '#FF00FF', - mediumaquamarine: '#66CDAA', - mediumblue: '#0000CD', - mediumorchid: '#BA55D3', - mediumpurple: '#9370DB', - mediumseagreen: '#3CB371', - mediumslateblue: '#7B68EE', - mediumspringgreen: '#00FA9A', - mediumturquoise: '#48D1CC', - mediumvioletred: '#C71585', - midnightblue: '#191970', - mintcream: '#F5FFFA', - mistyrose: '#FFE4E1', - moccasin: '#FFE4B5', - navajowhite: '#FFDEAD', - oldlace: '#FDF5E6', - olivedrab: '#6B8E23', - orange: '#FFA500', - orangered: '#FF4500', - orchid: '#DA70D6', - palegoldenrod: '#EEE8AA', - palegreen: '#98FB98', - paleturquoise: '#AFEEEE', - palevioletred: '#DB7093', - papayawhip: '#FFEFD5', - peachpuff: '#FFDAB9', - peru: '#CD853F', - pink: '#FFC0CB', - plum: '#DDA0DD', - powderblue: '#B0E0E6', - rosybrown: '#BC8F8F', - royalblue: '#4169E1', - saddlebrown: '#8B4513', - salmon: '#FA8072', - sandybrown: '#F4A460', - seagreen: '#2E8B57', - seashell: '#FFF5EE', - sienna: '#A0522D', - skyblue: '#87CEEB', - slateblue: '#6A5ACD', - slategray: '#708090', - slategrey: '#708090', - snow: '#FFFAFA', - springgreen: '#00FF7F', - steelblue: '#4682B4', - tan: '#D2B48C', - thistle: '#D8BFD8', - tomato: '#FF6347', - turquoise: '#40E0D0', - violet: '#EE82EE', - wheat: '#F5DEB3', - whitesmoke: '#F5F5F5', - yellowgreen: '#9ACD32' - }; - - - function getRgbHslContent(styleString) { - var start = styleString.indexOf('(', 3); - var end = styleString.indexOf(')', start + 1); - var parts = styleString.substring(start + 1, end).split(','); - // add alpha if needed - if (parts.length == 4 && styleString.substr(3, 1) == 'a') { - alpha = Number(parts[3]); - } else { - parts[3] = 1; - } - return parts; - } - - function percent(s) { - return parseFloat(s) / 100; - } - - function clamp(v, min, max) { - return Math.min(max, Math.max(min, v)); - } - - function hslToRgb(parts){ - var r, g, b; - h = parseFloat(parts[0]) / 360 % 360; - if (h < 0) - h++; - s = clamp(percent(parts[1]), 0, 1); - l = clamp(percent(parts[2]), 0, 1); - if (s == 0) { - r = g = b = l; // achromatic - } else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hueToRgb(p, q, h + 1 / 3); - g = hueToRgb(p, q, h); - b = hueToRgb(p, q, h - 1 / 3); - } - - return '#' + decToHex[Math.floor(r * 255)] + - decToHex[Math.floor(g * 255)] + - decToHex[Math.floor(b * 255)]; - } - - function hueToRgb(m1, m2, h) { - if (h < 0) - h++; - if (h > 1) - h--; - - if (6 * h < 1) - return m1 + (m2 - m1) * 6 * h; - else if (2 * h < 1) - return m2; - else if (3 * h < 2) - return m1 + (m2 - m1) * (2 / 3 - h) * 6; - else - return m1; - } - - function processStyle(styleString) { - var str, alpha = 1; - - styleString = String(styleString); - if (styleString.charAt(0) == '#') { - str = styleString; - } else if (/^rgb/.test(styleString)) { - var parts = getRgbHslContent(styleString); - var str = '#', n; - for (var i = 0; i < 3; i++) { - if (parts[i].indexOf('%') != -1) { - n = Math.floor(percent(parts[i]) * 255); - } else { - n = Number(parts[i]); - } - str += decToHex[clamp(n, 0, 255)]; - } - alpha = parts[3]; - } else if (/^hsl/.test(styleString)) { - var parts = getRgbHslContent(styleString); - str = hslToRgb(parts); - alpha = parts[3]; - } else { - str = colorData[styleString] || styleString; - } - return {color: str, alpha: alpha}; - } - - var DEFAULT_STYLE = { - style: 'normal', - variant: 'normal', - weight: 'normal', - size: 10, - family: 'sans-serif' - }; - - // Internal text style cache - var fontStyleCache = {}; - - function processFontStyle(styleString) { - if (fontStyleCache[styleString]) { - return fontStyleCache[styleString]; - } - - var el = document.createElement('div'); - var style = el.style; - try { - style.font = styleString; - } catch (ex) { - // Ignore failures to set to invalid font. - } - - return fontStyleCache[styleString] = { - style: style.fontStyle || DEFAULT_STYLE.style, - variant: style.fontVariant || DEFAULT_STYLE.variant, - weight: style.fontWeight || DEFAULT_STYLE.weight, - size: style.fontSize || DEFAULT_STYLE.size, - family: style.fontFamily || DEFAULT_STYLE.family - }; - } - - function getComputedStyle(style, element) { - var computedStyle = {}; - - for (var p in style) { - computedStyle[p] = style[p]; - } - - // Compute the size - var canvasFontSize = parseFloat(element.currentStyle.fontSize), - fontSize = parseFloat(style.size); - - if (typeof style.size == 'number') { - computedStyle.size = style.size; - } else if (style.size.indexOf('px') != -1) { - computedStyle.size = fontSize; - } else if (style.size.indexOf('em') != -1) { - computedStyle.size = canvasFontSize * fontSize; - } else if(style.size.indexOf('%') != -1) { - computedStyle.size = (canvasFontSize / 100) * fontSize; - } else if (style.size.indexOf('pt') != -1) { - computedStyle.size = fontSize / .75; - } else { - computedStyle.size = canvasFontSize; - } - - // Different scaling between normal text and VML text. This was found using - // trial and error to get the same size as non VML text. - computedStyle.size *= 0.981; - - return computedStyle; - } - - function buildStyle(style) { - return style.style + ' ' + style.variant + ' ' + style.weight + ' ' + - style.size + 'px ' + style.family; - } - - function processLineCap(lineCap) { - switch (lineCap) { - case 'butt': - return 'flat'; - case 'round': - return 'round'; - case 'square': - default: - return 'square'; - } - } - - /** - * This class implements CanvasRenderingContext2D interface as described by - * the WHATWG. - * @param {HTMLElement} surfaceElement The element that the 2D context should - * be associated with - */ - function CanvasRenderingContext2D_(surfaceElement) { - this.m_ = createMatrixIdentity(); - - this.mStack_ = []; - this.aStack_ = []; - this.currentPath_ = []; - - // Canvas context properties - this.strokeStyle = '#000'; - this.fillStyle = '#000'; - - this.lineWidth = 1; - this.lineJoin = 'miter'; - this.lineCap = 'butt'; - this.miterLimit = Z * 1; - this.globalAlpha = 1; - this.font = '10px sans-serif'; - this.textAlign = 'left'; - this.textBaseline = 'alphabetic'; - this.canvas = surfaceElement; - - var el = surfaceElement.ownerDocument.createElement('div'); - el.style.width = surfaceElement.clientWidth + 'px'; - el.style.height = surfaceElement.clientHeight + 'px'; - el.style.overflow = 'hidden'; - el.style.position = 'absolute'; - surfaceElement.appendChild(el); - - this.element_ = el; - this.arcScaleX_ = 1; - this.arcScaleY_ = 1; - this.lineScale_ = 1; - } - - var contextPrototype = CanvasRenderingContext2D_.prototype; - contextPrototype.clearRect = function() { - if (this.textMeasureEl_) { - this.textMeasureEl_.removeNode(true); - this.textMeasureEl_ = null; - } - this.element_.innerHTML = ''; - }; - - contextPrototype.beginPath = function() { - // TODO: Branch current matrix so that save/restore has no effect - // as per safari docs. - this.currentPath_ = []; - }; - - contextPrototype.moveTo = function(aX, aY) { - var p = this.getCoords_(aX, aY); - this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); - this.currentX_ = p.x; - this.currentY_ = p.y; - }; - - contextPrototype.lineTo = function(aX, aY) { - var p = this.getCoords_(aX, aY); - this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); - - this.currentX_ = p.x; - this.currentY_ = p.y; - }; - - contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, - aCP2x, aCP2y, - aX, aY) { - var p = this.getCoords_(aX, aY); - var cp1 = this.getCoords_(aCP1x, aCP1y); - var cp2 = this.getCoords_(aCP2x, aCP2y); - bezierCurveTo(this, cp1, cp2, p); - }; - - // Helper function that takes the already fixed cordinates. - function bezierCurveTo(self, cp1, cp2, p) { - self.currentPath_.push({ - type: 'bezierCurveTo', - cp1x: cp1.x, - cp1y: cp1.y, - cp2x: cp2.x, - cp2y: cp2.y, - x: p.x, - y: p.y - }); - self.currentX_ = p.x; - self.currentY_ = p.y; - } - - contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { - // the following is lifted almost directly from - // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes - - var cp = this.getCoords_(aCPx, aCPy); - var p = this.getCoords_(aX, aY); - - var cp1 = { - x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), - y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) - }; - var cp2 = { - x: cp1.x + (p.x - this.currentX_) / 3.0, - y: cp1.y + (p.y - this.currentY_) / 3.0 - }; - - bezierCurveTo(this, cp1, cp2, p); - }; - - contextPrototype.arc = function(aX, aY, aRadius, - aStartAngle, aEndAngle, aClockwise) { - aRadius *= Z; - var arcType = aClockwise ? 'at' : 'wa'; - - var xStart = aX + mc(aStartAngle) * aRadius - Z2; - var yStart = aY + ms(aStartAngle) * aRadius - Z2; - - var xEnd = aX + mc(aEndAngle) * aRadius - Z2; - var yEnd = aY + ms(aEndAngle) * aRadius - Z2; - - // IE won't render arches drawn counter clockwise if xStart == xEnd. - if (xStart == xEnd && !aClockwise) { - xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something - // that can be represented in binary - } - - var p = this.getCoords_(aX, aY); - var pStart = this.getCoords_(xStart, yStart); - var pEnd = this.getCoords_(xEnd, yEnd); - - this.currentPath_.push({type: arcType, - x: p.x, - y: p.y, - radius: aRadius, - xStart: pStart.x, - yStart: pStart.y, - xEnd: pEnd.x, - yEnd: pEnd.y}); - - }; - - contextPrototype.rect = function(aX, aY, aWidth, aHeight) { - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - }; - - contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { - var oldPath = this.currentPath_; - this.beginPath(); - - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - this.stroke(); - - this.currentPath_ = oldPath; - }; - - contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { - var oldPath = this.currentPath_; - this.beginPath(); - - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - this.fill(); - - this.currentPath_ = oldPath; - }; - - contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { - var gradient = new CanvasGradient_('gradient'); - gradient.x0_ = aX0; - gradient.y0_ = aY0; - gradient.x1_ = aX1; - gradient.y1_ = aY1; - return gradient; - }; - - contextPrototype.createRadialGradient = function(aX0, aY0, aR0, - aX1, aY1, aR1) { - var gradient = new CanvasGradient_('gradientradial'); - gradient.x0_ = aX0; - gradient.y0_ = aY0; - gradient.r0_ = aR0; - gradient.x1_ = aX1; - gradient.y1_ = aY1; - gradient.r1_ = aR1; - return gradient; - }; - - contextPrototype.drawImage = function(image, var_args) { - var dx, dy, dw, dh, sx, sy, sw, sh; - - // to find the original width we overide the width and height - var oldRuntimeWidth = image.runtimeStyle.width; - var oldRuntimeHeight = image.runtimeStyle.height; - image.runtimeStyle.width = 'auto'; - image.runtimeStyle.height = 'auto'; - - // get the original size - var w = image.width; - var h = image.height; - - // and remove overides - image.runtimeStyle.width = oldRuntimeWidth; - image.runtimeStyle.height = oldRuntimeHeight; - - if (arguments.length == 3) { - dx = arguments[1]; - dy = arguments[2]; - sx = sy = 0; - sw = dw = w; - sh = dh = h; - } else if (arguments.length == 5) { - dx = arguments[1]; - dy = arguments[2]; - dw = arguments[3]; - dh = arguments[4]; - sx = sy = 0; - sw = w; - sh = h; - } else if (arguments.length == 9) { - sx = arguments[1]; - sy = arguments[2]; - sw = arguments[3]; - sh = arguments[4]; - dx = arguments[5]; - dy = arguments[6]; - dw = arguments[7]; - dh = arguments[8]; - } else { - throw Error('Invalid number of arguments'); - } - - var d = this.getCoords_(dx, dy); - - var w2 = sw / 2; - var h2 = sh / 2; - - var vmlStr = []; - - var W = 10; - var H = 10; - - // For some reason that I've now forgotten, using divs didn't work - vmlStr.push(' ' , - '', - ''); - - this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); - }; - - contextPrototype.stroke = function(aFill) { -