Add geositemaps starting with route map
Add geositemaps starting with route map

file:b/geo/route.kml.php (new)
--- /dev/null
+++ b/geo/route.kml.php
@@ -1,1 +1,30 @@
+<?php
+header('Content-Type: application/vnd.google-earth.kml+xml');
+include ('../include/common.inc.php');
+echo '<?xml version="1.0" encoding="UTF-8"?>
+<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"><Document>';
+echo '
+    <Style id="yellowLineGreenPoly">
+      <LineStyle>
+        <color>7f00ff00</color>
+        <width>4</width>
+      </LineStyle>
+      <PolyStyle>
+        <color>7f00ffff</color>
+      </PolyStyle>
+	</Style>';
+$route = getRoute($routeid);
+ echo "\n<Placemark>\n";
+ $link = curPageURL()."/../trip.php?routeid=".htmlspecialchars ($route["route_id"]);
+ echo "<name>".$route['route_short_name']."</name>";
+  echo '<atom:link href="'.$link.'"/>';
+ echo '<description><![CDATA[ <a href="'.$link.'">'.$route['route_short_name']." ".$route['route_long_name']."</a>]]> </description>";
+echo "<styleUrl>#yellowLineGreenPoly</styleUrl>";
 
+	$trips = getRouteTrips($routeid);
+	echo getTripShape($trips[0]['trip_id']);
+
+echo "</Placemark>\n</Document></kml>\n";
+?>
+
+

--- a/include/common-template.inc.php
+++ b/include/common-template.inc.php
@@ -5,6 +5,7 @@
 function googleAnalyticsGetImageUrl()
 {
 	global $GA_ACCOUNT, $GA_PIXEL;
+	//if (stristr($_SERVER['HTTP_USER_AGENT'], 'Googlebot') return "";
 	$url = "";
 	$url.= $GA_PIXEL . "?";
 	$url.= "utmac=" . $GA_ACCOUNT;
@@ -125,7 +126,25 @@
 border-radius: 15px;
     }
  
-
+/*#leftcolumn { 
+	float: none;
+}			
+.min-width-768px #leftcolumn {
+	float: left;
+	width: 30%;
+}
+#rightcolumn { 
+	float: none;
+}			
+.min-width-768px #rightcolumn {
+	float: right;
+	width: 68%;
+}*/	
+
+#footer {
+clear:both;
+text-align:center;
+}
     // source http://webaim.org/techniques/skipnav/
     #skip a, #skip a:hover, #skip a:visited 
 { 
@@ -144,7 +163,7 @@
 height:auto; 
 }
 </style>';
-	if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod')) {
+	if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) {
 		echo '<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" />
@@ -175,7 +194,11 @@
 }
 $(document).ready(function() {
         $('#here').click(function(event) { $('#geolocate').val(geolocate()); return false;});
-$('#here').show();
+        $('#here').show();
+	/*if ($.mobile.media('screen and (min-width: 768px)')) {
+	  $('map a:first').click();
+	  $('#settings a:first').click();
+	}*/
 });
 ";
 		if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") echo "geolocate();";
@@ -187,6 +210,7 @@
   var _gaq = _gaq || [];
   _gaq.push(['_setAccount', 'UA-22173039-1']);
   _gaq.push(['_trackPageview']);
+   _gaq.push(['_trackPageLoadTime']);
 </script>";
 	echo '</head>
 <body>
@@ -249,7 +273,7 @@
         or enter an address/co-ordinates in the box below.';
 	}
 	echo '</div>';
-	echo '<div data-role="collapsible" data-collapsed="' . !$geoerror . '">
+	echo '<div id="settings" data-role="collapsible" data-collapsed="' . !$geoerror . '">
         <h3>Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...</h3>
         <form action="' . basename($_SERVER['PHP_SELF']) . "?" . $_SERVER['QUERY_STRING'] . '" method="post">
         <div class="ui-body"> 

--- a/include/common.inc.php
+++ b/include/common.inc.php
@@ -163,7 +163,7 @@
 			$key => $val
 		));
 	}
-	if ($sort_ascending) $array = array_reverse($temp_array);
+	if ($sort_ascending && isset($temp_array)) $array = array_reverse($temp_array);
 	else $array = $temp_array;
 }
 function r_implode( $glue, $pieces ) 

--- a/include/db/route-dao.inc.php
+++ b/include/db/route-dao.inc.php
@@ -13,6 +13,7 @@
 	}
 	return $query->fetch(PDO::FETCH_ASSOC);
 }
+
 function getRoutes()
 {
 	global $conn;
@@ -200,7 +201,7 @@
 	$query = $conn->prepare($query);
 	$query->bindParam(":service_period", $service_period);
 	$query->bindParam(":distance", $distance);
-	$query->bindParam(":limit", $limit);
+	if ($limit != "") $query->bindParam(":limit", $limit);
 	$query->execute();
 	if (!$query) {
 		databaseError($conn->errorInfo());

--- a/include/db/trip-dao.inc.php
+++ b/include/db/trip-dao.inc.php
@@ -16,40 +16,25 @@
 	}
 	return $query->fetch(PDO::FETCH_ASSOC);
 }
-function getTripShape()
-{
-	/* def handle_json_GET_tripstopTimes(self, params):
-	   schedule = self.server.schedule
-	   try:
-	     trip = schedule.GetTrip(params.get('trip'))
-	   except KeyError:
-	      # if a non-existent trip is searched for, the return nothing
-	     return
-	   time_stops = trip.GetTimeInterpolatedStops()
-	   stops = []
-	   times = []
-	   for arr,ts,is_timingpoint in time_stops:
-	     stops.append(StopToTuple(ts.stop))
-	     times.append(arr)
-	   return [stops, times]
-	
-	 def handle_json_GET_tripshape(self, params):
-	   schedule = self.server.schedule
-	   try:
-	     trip = schedule.GetTrip(params.get('trip'))
-	   except KeyError:
-	      # if a non-existent trip is searched for, the return nothing
-	     return
-	   points = []
-	   if trip.shape_id:
-	     shape = schedule.GetShape(trip.shape_id)
-	     for (lat, lon, dist) in shape.points:
-	       points.append((lat, lon))
-	   else:
-	     time_stops = trip.GetTimeStops()
-	     for arr,dep,stop in time_stops:
-	       points.append((stop.stop_lat, stop.stop_lon))
-	   return points*/
+function getTripShape($tripID)
+{
+	global $conn;
+	$query = "SELECT ST_AsKML(ST_MakeLine(geometry(a.position))) as the_route
+FROM (SELECT position,
+	stop_sequence, trips.trip_id
+FROM stop_times
+join trips on trips.trip_id = stop_times.trip_id
+join stops on stops.stop_id = stop_times.stop_id
+WHERE trips.trip_id = :tripID ORDER BY stop_sequence) as a group by a.trip_id";
+	debug($query, "database");
+	$query = $conn->prepare($query);
+	$query->bindParam(":tripID", $tripID);
+	$query->execute();
+	if (!$query) {
+		databaseError($conn->errorInfo());
+		return Array();
+	}
+	return $query->fetchColumn(0);
 }
 function getTimeInterpolatedTrip($tripID, $range = "")
 {

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -28,5 +28,4 @@
 echo ' <a href="labs/index.php" data-role="button" data-icon="beaker">Busness R&amp;D</a>';
 include_footer(true)
 ?>
-        
 

--- a/labs/index.php
+++ b/labs/index.php
@@ -10,6 +10,8 @@
 		<p>Analysis of route timing points</p></a></li>
 		<li><a href="busstopdensity.php"><h3>Bus Stop Density Map</h3>
 		<p>Analysis of bus stop coverage</p></a></li>
+		<li><a href="stopBrowser.php"><h3>Bus Stop Browser Map</h3>
+		<p>Bus stop location/route browser</p></a></li>
 		<li>More coming soon!</li>
             </ul>
 	    </div>

--- a/labs/myway_api.json.php
+++ b/labs/myway_api.json.php
@@ -23,7 +23,7 @@
 	"DOBday" => "day",
 	"DOByear" => "year",
 	"secret_answer" => "pwrd",
-	"button" => "button"
+	"button" => "Submit"
 );
 foreach (Array(
 	"card_number",
@@ -64,6 +64,7 @@
 	curl_setopt($ch, CURLOPT_POST, count($fields));
 	curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
 	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+	curl_setopt($ch, CURLOPT_REFERER, "https://www.action.act.gov.au/ARTS/getbalance.asp");
 	curl_setopt($ch, CURLOPT_HEADER, 0);
 	curl_setopt($ch, CURLOPT_TIMEOUT, 30);
 	//execute post
@@ -75,6 +76,7 @@
 
 if (!isset($return['error'])) {
 	include_once ('lib/simple_html_dom.php');
+	//print_r($pageHTML);
 	$page = str_get_html($pageHTML);
 	$pageAlerts = $page->find(".smartCardAlert");
 	if (sizeof($pageAlerts) > 0) {
@@ -94,12 +96,14 @@
 				$tableColumns[$tableColumnNum] = cleanString($th->plaintext);
 				$tableColumnNum++;
 			}
+			//print_r($tableColumns);
 			$tableRowNum = 0;
 			foreach ($table->find("tr") as $tr) {
 				$tableColumnNum = 0;
 				foreach ($tr->find("td") as $td) {
 					if ($tableNum == 1) $return[$tableName[$tableNum]][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext);
 					else $return[$tableName[$tableNum]][$tableRowNum][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext);
+					//print_r($return);
 					$tableColumnNum++;
 				}
 				$tableRowNum++;

--- a/labs/mywaybalance.php
+++ b/labs/mywaybalance.php
@@ -29,8 +29,10 @@
 		echo '<ul data-role="listview" data-inset="true"><li data-role="list-divider"> Recent Transactions </li>';
 		$txCount=0;
 		foreach ($return['myway_transactions'] as $transaction) {
-			echo "<li><b>" . $transaction["Date / Time"] . "</b>";
-			echo "<br><small>" . $transaction["TX Reference No / Type"] . "</small>";
+			echo "<li>";
+			if ($transaction["Deduction Type"] == "DEFAULT") echo '<img src="css/images/warning.png" alt="Failed to tap off: " class="ui-li-icon">';
+			echo"<b>" . $transaction["Date / Time"] . "</b>";
+			echo "<br><small>" .$transaction["Route"] ." at " . $transaction["Stop Name"]. "<br>". $transaction["TX Reference No / Type"] . "</small>";
 			echo '<p class="ui-li-aside">' . $transaction["TX Amount"] . '</p>';
 			echo "</li>";
 			$txCount++;

--- /dev/null
+++ b/labs/stopBrowser.kml.php
@@ -1,1 +1,62 @@
+<?php
+	header('Content-type: application/vnd.google-earth.kml+xml');
+//http://wiki.openstreetmap.org/wiki/OpenLayers_Dynamic_KML
 
+// Creates the KML/XML Document.
+	$dom = new DOMDocument('1.0', 'UTF-8');
+ 
+	// Creates the root KML element and appends it to the root document.
+	$node = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml');
+	$parNode = $dom->appendChild($node);
+ 
+	// Creates a KML Document element and append it to the KML element.
+	$dnode = $dom->createElement('Document');
+	$docNode = $parNode->appendChild($dnode);
+ 
+ 
+$bbox = $_GET['bbox']; // get the bbox param from google earth
+list($bbox_south, $bbox_west, $bbox_north,$bbox_east) = explode(",", $bbox); // west, south, east, north
+
+include ('../include/common.inc.php');
+$debugOkay = Array();
+$contents = getNearbyStops( (($bbox_west+ $bbox_east) /2), ($bbox_south + $bbox_north)/2 ,50, 3000);
+foreach ($contents as $stop) {
+                $description = 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] ." <br>";
+                $trips = getStopTripsWithTimes($stop['stop_id'], "", "", "", 3);
+                if ($trips) {
+			foreach ($trips as $key => $row) {
+                        	if ($key < 3) {
+                                	$description .= $row['route_short_name'] . ' ' . $row['route_long_name'] . ' @ ' . $row['arrival_time'] . "<br>";
+                        	}
+                	}
+		} else {
+			$description .= "No more trips today";
+		}
+					 // Creates a Placemark and append it to the Document.
+					  $node = $dom->createElement('Placemark');
+					  $placeNode = $docNode->appendChild($node);
+ 
+					  // Creates an id attribute and assign it the value of id column.
+					  $placeNode->setAttribute('id', 'placemark' . $stop['stop_id']);
+ 
+					  // Create name, and description elements and assigns them the values of the name and address columns from the results.
+					  $nameNode = $dom->createElement('name',htmlentities($stop['stop_name']));
+					  $descriptionNode = $dom->createElement('description',$description);
+					  $placeNode->appendChild($nameNode);
+					  $placeNode->appendChild($descriptionNode);
+ 
+					  // Creates a Point element.
+					  $pointNode = $dom->createElement('Point');
+					  $placeNode->appendChild($pointNode);
+ 
+					  // Creates a coordinates element and gives it the value of the lng and lat columns from the results.
+					  $coorStr = $stop['stop_lon'] . ','  . $stop['stop_lat'];
+					  $coorNode = $dom->createElement('coordinates', $coorStr);
+					  $pointNode->appendChild($coorNode);
+				}
+ 
+ 
+	$kmlOutput = $dom->saveXML();
+	echo $kmlOutput;
+?>
+

--- /dev/null
+++ b/labs/stopBrowser.php
@@ -1,1 +1,102 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <script src="openlayers/OpenLayers.js"></script>
+ <SCRIPT TYPE="text/javascript" SRC="OpenStreetMap.js"></SCRIPT> 
+    <script type="text/javascript">
+        var map,select;
+       
+	
+function init()
+{
+    var extent = new OpenLayers.Bounds(148.98, -35.48, 149.25, -35.15);
+ 
+		// set up the map options
+		var options = 
+		{
+			   maxExtent: extent,
+			   numZoomLevels: 20, 
+		}; 
+ 
+		// create the ol map object
+		map = new OpenLayers.Map('map', options);
+    
+var osmtiles = new OpenLayers.Layer.OSM("OSM");
 
+var nearmap = new OpenLayers.Layer.OSM.NearMap("NearMap");
+
+	    var stopbrowser = new OpenLayers.Layer.Vector("POI", {
+		projection: new OpenLayers.Projection("EPSG:4326"),
+		strategies: [
+			new OpenLayers.Strategy.BBOX(),
+		],
+		protocol: new OpenLayers.Protocol.HTTP({
+                        url: "stopBrowser.kml.php",  //Note that it is probably worth adding a Math.random() on the end of the URL to stop caching.
+			format: new OpenLayers.Format.KML({
+                                extractStyles: true, 
+                                extractAttributes: true
+                        }),
+		})
+	    });
+
+	map.addLayers([osmtiles,stopbrowser,nearmap]);
+
+    var lonLat = new OpenLayers.LonLat(149.11, -35.28).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
+    map.setCenter(lonLat, 15);
+    map.addControl( new OpenLayers.Control.LayerSwitcher({'ascending':false}));
+    map.addControl(new OpenLayers.Control.MousePosition(
+    {
+        displayProjection: new OpenLayers.Projection("EPSG:4326"),
+        suffix: "__________________________________"
+    }));
+    map.addControl(new OpenLayers.Control.MousePosition(
+    {
+        displayProjection: new OpenLayers.Projection("EPSG:900913")
+    }));
+    
+  select = new OpenLayers.Control.SelectFeature(stopbrowser);
+            
+            stopbrowser.events.on({
+                "featureselected": onFeatureSelect,
+                "featureunselected": onFeatureUnselect
+            });
+ 
+            map.addControl(select);
+            select.activate();   
+
+}
+ function onPopupClose(evt) {
+            select.unselectAll();
+        }
+        function onFeatureSelect(event) {
+            var feature = event.feature;
+            // Since KML is user-generated, do naive protection against
+            // Javascript.
+            var content = "<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description;
+            if (content.search("<script") != -1) {
+                content = "Content contained Javascript! Escaped content below.<br />" + content.replace(/</g, "&lt;");
+            }
+            popup = new OpenLayers.Popup.FramedCloud("chicken", 
+                                     feature.geometry.getBounds().getCenterLonLat(),
+                                     new OpenLayers.Size(100,100),
+                                     content,
+                                     null, true, onPopupClose);
+            feature.popup = popup;
+            map.addPopup(popup);
+        }
+        function onFeatureUnselect(event) {
+            var feature = event.feature;
+            if(feature.popup) {
+                map.removePopup(feature.popup);
+                feature.popup.destroy();
+                delete feature.popup;
+            }
+        }
+    </script>
+
+  </head>
+  <body onload="init()">
+    <div id="map" width="100%" height="100%" class="smallmap"></div>
+  </body>
+</html>
+
+

file:a/robots.txt -> file:b/robots.txt
--- a/robots.txt
+++ b/robots.txt
@@ -1,4 +1,6 @@
 User-agent: *
 Allow: /
+User-agent: *
+Disallow: /lib/ga.php
 sitemap: http://bus.lambdacomplex.org/sitemap.xml.php
 

--- a/sitemap.xml.php
+++ b/sitemap.xml.php
@@ -22,6 +22,17 @@
 	echo "<priority>0.9</priority>";
 	echo "</url>\n";
  }
+ 
+ // geosite map
+ foreach (getRoutes() as $route) {
+      echo " <url><loc>".curPageURL()."geo/route.kml.php?routeid=".htmlspecialchars ($route["route_id"])."</loc>";
+	echo "<lastmod>" . $last_updated . "</lastmod>";
+	echo "<geo:geo>
+       <geo:format>kml</geo:format>
+   </geo:geo>";
+	echo "</url>\n";
+ }
+ 
   echo '</urlset>';
 
 ?>

file:a/stop.php -> file:b/stop.php
--- a/stop.php
+++ b/stop.php
@@ -60,6 +60,7 @@
 	}
 }
 include_header($stop['stop_name'], "stop");
+echo '<span id="leftcolumn">';
 timePlaceSettings();
 echo $stopLinks;
 if (sizeof($stops) > 0) {
@@ -75,6 +76,7 @@
 		)
 	)) ;
 }
+echo '</span><span id="rightcolumn">';
 echo '  <ul data-role="listview"  data-inset="true">';
 if (sizeof($allStopsTrips) > 0) {
     sktimesort($allStopsTrips,"arrival_time", true);
@@ -107,6 +109,7 @@
 	}
 }
 echo '</ul>';
+echo '</span>';
 include_footer();
 ?>
 

file:a/trip.php -> file:b/trip.php
--- a/trip.php
+++ b/trip.php
@@ -16,7 +16,7 @@
 include_header("Stops on " . $trip['route_short_name'] . ' ' . $trip['route_long_name'], "trip");
 trackEvent("Route/Trip View","View Route",  $trip['route_short_name'] . ' ' . $trip['route_long_name'], $routeid);
 
-
+echo '<span id="leftcolumn">';
 echo '<h2>Via:</h2> <small>' . viaPointNames($tripid) . '</small>';
 echo '<h2>Other Trips:</h2> ';
 foreach (getRouteTrips($routeid) as $othertrip) {
@@ -27,6 +27,7 @@
 foreach (getRoutesByNumber($trip['route_short_name']) as $row) {
 	if ($row['route_id'] != $routeid) echo '<a href="trip.php?routeid=' . $row['route_id'] . '">' . $row['route_long_name'] . ' (' . ucwords($row['service_id']) . ')</a> ';
 }
+echo '</span><span id="rightcolumn">';
 flush(); @ob_flush();
 echo '  <ul data-role="listview"  data-inset="true">';
 $stopsGrouped = Array();
@@ -44,10 +45,11 @@
 			$stopsGrouped["endTime"] = $tripStopTime['arrival_time'];
 			echo '<a href="stop.php?stopids=' . implode(",", $stopsGrouped['stop_ids']) . '">';
 			echo '<p class="ui-li-aside">' . $stopsGrouped['startTime'] . ' to ' . $stopsGrouped['endTime'];
-                        echo '</p>';
+                        
                         if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) {
-						echo '<span class="ui-li-count">' . distance($stop['stop_lat'],$stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away</span>';
+						echo '<br>' . distance($tripStopTime['stop_lat'],$tripStopTime['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away';
 					}
+                                        echo '</p>';
 			echo bracketsMeanNewLine($tripStopTime["stop_name"]);
 			echo '</a></li>';
                         flush(); @ob_flush();
@@ -56,10 +58,11 @@
 		else {
 			// just a normal stop
 			echo '<a href="stop.php?stopid=' . $tripStopTime['stop_id'] . (startsWith($tripStopTime['stop_code'], "Wj") ? '&amp;stopcode=' . $tripStopTime['stop_code'] : "") . '">';
-			echo '<p class="ui-li-aside">' . $tripStopTime['arrival_time'] . '</p>';
+			echo '<p class="ui-li-aside">' . $tripStopTime['arrival_time']; 
 			if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) {
-						echo '<span class="ui-li-count">' . distance($stop['stop_lat'],$stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away</span>';
+						echo '<br>' . distance($tripStopTime['stop_lat'],$tripStopTime['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away';
 					}
+                                        echo '</p>';
                                         echo bracketsMeanNewLine($tripStopTime['stop_name']);
 			echo '</a></li>';
                         flush(); @ob_flush();
@@ -85,6 +88,8 @@
 	}
 }
 echo '</ul>';
+
+echo '</span>';
 include_footer();
 ?>