--- a/busui/common.inc.php +++ b/busui/common.inc.php @@ -1,8 +1,130 @@ <?php date_default_timezone_set('Australia/ACT'); +$APIurl = "http://localhost:8765"; +error_reporting(E_ALL ^ E_NOTICE); + +// 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"); + + // you have to open the session to be able to modify or remove it +session_start(); +function isDebug() +{ + return $_SERVER['SERVER_NAME'] == "10.0.1.154" || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || !$_SERVER['SERVER_NAME']; +} + +function debug($msg) { + if (isDebug()) echo "<!-- $msg -->"; +} +function isFastDevice() { + return true; +} + +function include_header($pageTitle, $opendiv = true, $geolocate = false) { + // this starts the session + session_start(); + + // if (isDebug()) // set php error level high + echo ' +<!DOCTYPE html> +<html> + <head> + <title>busness time - '.$pageTitle.'</title> + '; + if (isDebug()) 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 { + padding-bottom: 18px; + width: 100%; + } + + .ui-li-heading { + white-space: normal !important; + } +</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 setCookie(c_name,value,expiredays) +{ +var exdate=new Date(); +exdate.setDate(exdate.getDate()+expiredays); +document.cookie=c_name+ \"=\" +escape(value)+ +((expiredays==null) ? \"\" : \";expires=\"+exdate.toUTCString()); +} + +function getCookie(c_name) +{ +if (document.cookie.length>0) + { + c_start=document.cookie.indexOf(c_name + \"=\"); + if (c_start!=-1) + { + c_start=c_start + c_name.length+1; + c_end=document.cookie.indexOf(\";\",c_start); + if (c_end==-1) c_end=document.cookie.length; + return unescape(document.cookie.substring(c_start,c_end)); + } + } +return \"\"; +} + +function success(position) { +$('#geolocate').val(position.coords.latitude+','+position.coords.longitude); +setCookie('geolocate',position.coords.latitude+','+position.coords.longitude,1); +} + +function error(msg) { + console.log(msg); +} + +if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(success, error); +} + +</script> "; + } +echo '</head> +<body> + '; +if ($opendiv) echo '<div data-role="page"> + + <div data-role="header"> + <h1>'.$pageTitle.'</h1> + </div><!-- /header --> + <div data-role="content"> '; +} + +function include_footer() +{ + echo '</div>'; +} + +$service_periods = Array ('sunday','saturday','weekday'); function service_period() { +if (isset($_SESSION['service_period'])) return $_SESSION['service_period']; + switch (date('w')){ case 0: @@ -13,5 +135,294 @@ return 'weekday'; } } + +function remove_spaces($string) +{ + return str_replace(' ','',$string); +} + +function midnight_seconds() +{ +// from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html +if (isset($_SESSION['time'])) { + $time = mkdate($_SESSION['time']); + return (date("G",$time) * 3600) + (date("i",$time) * 60) + date("s",$time); + } + return (date("G") * 3600) + (date("i") * 60) + date("s"); +} + +function midnight_seconds_to_time($seconds) +{ +if ($seconds > 0) { + $midnight = mktime (0, 0, 0, date("n"), date("j"), date("Y")); + return date("h:ia",$midnight+$seconds); +} else { +return ""; +} +} +function getPage($url) +{ + debug($url); + $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>"; +curl_close($ch); +return $page; +} +function array_flatten($a,$f=array()){ + if(!$a||!is_array($a))return ''; + foreach($a as $k=>$v){ + if(is_array($v))$f=array_flatten($v,$f); + else $f[$k]=$v; + } + return $f; +} + +function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb") +{ +$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 = ""; + $output .= '<div data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>'; + $output .= '<center><img src="staticmaplite/staticmap.php?center='.$center.'&zoom='.$zoom.'&size='.$width.'x'.$height.'&maptype=mapnik&markers='.$markers.'" width='.$width.' height='.$height.'></center>'; + $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 object2array($object) { + if (is_object($object)) { + foreach ($object as $key => $value) { + $array[$key] = $value; + } + } + else { + $array = $object; + } + return $array; +} + +function geocode($query, $giveOptions) { + $url = "http://geocoding.cloudmade.com/daa03470bb8740298d4b10e3f03d63e6/geocoding/v2/find.js?query=".$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) { + $url = "http://geocoding.cloudmade.com/daa03470bb8740298d4b10e3f03d63e6/geocoding/v2/find.js?around=".$lat.",".$lng."&distance=closest&object_type=road"; + $contents = json_decode(getPage($url)); + return $contents->features[0]->properties->name; +} + +function startsWith($haystack,$needle,$case=true) { + if($case){return (strcmp(substr($haystack, 0, strlen($needle)),$needle)===0);} + return (strcasecmp(substr($haystack, 0, strlen($needle)),$needle)===0); +} + +function endsWith($haystack,$needle,$case=true) { + if($case){return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0);} + return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0); +} +function bracketsMeanNewLine($input) { + return str_replace(")","</small>",str_replace("(","<br><small>",$input)); +} + +function viaPoints($tripid,$stopid, $timingPointsOnly = false) { + global $APIurl; + $url = $APIurl."/json/tripstoptimes?trip=".$tripid; + +$json = json_decode(getPage($url)); +debug(print_r($json,true)); +$stops = $json[0]; +$times = $json[1]; +$foundStop = false; +$viaPoints = Array(); +foreach ($stops as $key => $row) +{ + if ($foundStop) { + if (!$timingPointsOnly || !startsWith($row[5],"Wj") ) { + $viaPoints[] = Array("id" => $row[0], "name" => $row[1], "time" => $times[$key]); + } + } else { + if ($row[0] == $stopid) $foundStop = true; + } +} + return $viaPoints; +} + +function viaPointNames($tripid,$stopid) { + $points = viaPoints($tripid,$stopid,true); + $pointNames = Array(); + foreach ($points as $point) { + $pointNames[] = $point['name']; + } + return implode(", ",$pointNames); +} + +function timePlaceSettings() { + global $service_periods; + echo '<div data-role="collapsible" data-collapsed="true"> + <h3>Change Time/Place...</h3> + <div class="ui-body"> + <div data-role="fieldcontain"> + <label for="geolocate"> Current Location: </label> + <input type="text" id="geolocate" name="geolocate" value="Enter co-ordinates or address here"/> <a href="#" style="display:none" name="here" id="here"/>Here?</a> + </div> + <div data-role="fieldcontain"> + <label for="time"> Time: </label> + <input type="time" value="'. date("H:m").'"/> <a href="#" style="display:none" name="currentTime" id="currentTime"/>Current Time?</a> + </div> + <div data-role="fieldcontain"> + <label for="service_period"> Service Period: </label> + <select name="service_period">'; + + foreach ($service_periods as $service_period) { + echo "<option value=\"$service_period\"".(service_period() === $service_period ? "SELECTED" : "").'>'.ucwords($service_period).'</option>'; + } + echo '</select> + <a href="#" style="display:none" name="currentPeriod" id="currentPeriod"/>Current Period?</a> + </div> + + <input type="submit" value="Update"/> + </div></div>'; +echo " <script> +$('#here').click(function(event) { $('#geolocate').val(getCookie('geolocate')); return false;}); +$('#here').show(); + </script>"; +} ?> -