Bus Stop density heatmap
Bus Stop density heatmap

<?php <?php
// you have to open the session to be able to modify or remove it // you have to open the session to be able to modify or remove it
session_start(); session_start();
if (isset($_REQUEST['service_period'])) { if (isset($_REQUEST['service_period'])) {
$_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING); $_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING);
sessionUpdated(); sessionUpdated();
} }
if (isset($_REQUEST['time'])) { if (isset($_REQUEST['time'])) {
$_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); $_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING);
sessionUpdated(); sessionUpdated();
} }
if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") { if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") {
$geocoded = false; $geocoded = false;
if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) {
$_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); $_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
$_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); $_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
} }
else { else {
$geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL); $geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL);
if (startsWith($geolocate, "-")) { if (startsWith($geolocate, "-")) {
$locateparts = explode(",", $geolocate); $locateparts = explode(",", $geolocate);
$_SESSION['lat'] = $locateparts[0]; $_SESSION['lat'] = $locateparts[0];
$_SESSION['lon'] = $locateparts[1]; $_SESSION['lon'] = $locateparts[1];
} }
else { else {
$contents = geocode($geolocate, true); $contents = geocode($geolocate, true);
print_r($contents); print_r($contents);
if (isset($contents[0]->centroid)) { if (isset($contents[0]->centroid)) {
$geocoded = true; $geocoded = true;
$_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; $_SESSION['lat'] = $contents[0]->centroid->coordinates[0];
$_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; $_SESSION['lon'] = $contents[0]->centroid->coordinates[1];
} }
else { else {
$_SESSION['lat'] = ""; $_SESSION['lat'] = "";
$_SESSION['lon'] = ""; $_SESSION['lon'] = "";
} }
} }
} }
if ($_SESSION['lat'] != "" && isAnalyticsOn()) { if ($_SESSION['lat'] != "" && isAnalyticsOn()) {
trackEvent("Geolocation","Updated Location", "Geocoded - ".($geocoded ? "Yes" : "No")); trackEvent("Geolocation","Updated Location", "Geocoded - ".($geocoded ? "Yes" : "No"));
} }
sessionUpdated(); sessionUpdated();
} }
function sessionUpdated() { function sessionUpdated() {
$_SESSION['lastUpdated'] = time(); $_SESSION['lastUpdated'] = time();
} }
// timeoutSession // timeoutSession
$TIMEOUT_LIMIT = 60*5; // 5 minutes $TIMEOUT_LIMIT = 60*5; // 5 minutes
if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated']+$TIMEOUT_LIMIT < time()) { if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated']+$TIMEOUT_LIMIT < time()) {
debug ("Session timeout ".($_SESSION['lastUpdated']+$TIMEOUT_LIMIT).">".time(),"session"); debug ("Session timeout ".($_SESSION['lastUpdated']+$TIMEOUT_LIMIT).">".time(),"session");
session_destroy(); session_destroy();
session_start(); session_start();
} }
debug(print_r($_SESSION, true) , "session"); //debug(print_r($_SESSION, true) , "session");
   
function current_time() { function current_time() {
return ($_SESSION['time']? $_SESSION['time'] : date("H:i:s")); return ($_SESSION['time']? $_SESSION['time'] : date("H:i:s"));
} }
?> ?>
  <?php
  include ('../include/common.inc.php');
  //include_header("Bus Stop Density", "busstopdensity")
  ?>
 
  <style type="text/css">
 
  #map_container{
  width:100%;
  height:100%;
  }
  #status, #legend {
  background-color: #eeeeee;
  padding: 3px 5px 3px 5px;
  opacity: .9;
  }
  </style>
 
  <div id="map_container"></div>
  <div id="status">
  Status:&nbsp; <span id="log"> <img alt="progess bar" src="progress_bar.gif" width="150" height="16"/></span>
  </div>
  <script type="text/javascript" src="http://www.google.com/jsapi?autoload={%22modules%22:[{%22name%22:%22maps%22,version:3,other_params:%22sensor=false%22},{%22name%22:%22jquery%22,%22version%22:%221.4.2%22}]}"></script>
  <script type="text/javascript">
  //<![CDATA[
  //Google Map API v3
 
  var googleMap = null;
  var previousPos = null;
 
  $(function($){//Called when page is loaded
  googleMap = new google.maps.Map(document.getElementById("map_container"), {
  zoom: 17,
  center: new google.maps.LatLng(-35.25,149.125),
  mapTypeId: google.maps.MapTypeId.SATELLITE});
  //Set status bar
  googleMap.controls[google.maps.ControlPosition.TOP_LEFT].push($("#status").get(0));
  //Set legend
  googleMap.controls[google.maps.ControlPosition.BOTTOM_LEFT].push($("#legend").get(0));
 
  google.maps.event.addListener(googleMap, "zoom_changed", function(){
  google.maps.event.trigger(googleMap, "mousemove", previousPos);
  });//onzoomend
 
  //Add a listener when mouse moves
  google.maps.event.addListener(googleMap, "mousemove", function(event){
  var latLng = event.latLng;
  var xy = googleMap.getProjection().fromLatLngToPoint(latLng);
  var ratio = Math.pow(2,googleMap.getZoom());
  $("#log").html("Zoom:" + googleMap.getZoom() + " WGS84:(" + latLng.lat().toFixed(5) + ", " + latLng.lng().toFixed(5) + ") Px:(" + Math.floor(xy.x * ratio) + "," + Math.floor(xy.y *ratio) + ")");
  previousPos = event;
  });//onmouseover
 
  //Add a listener when mouse leaves the map area
  google.maps.event.addListener(googleMap, "mouseout", function(event){
  $("#log").html("");
  });//onmouseout
 
  //Add tile overlay
  var myOverlay = new google.maps.ImageMapType({
  getTileUrl: function(coord, zoom) {
  return 'busstopdensity.tile.php?x=' + coord.x + '&y=' + coord.y + '&zoom=' +zoom;
  },
  tileSize: new google.maps.Size(256, 256),
  isPng: true,
  opacity:1.0
  });
  googleMap.overlayMapTypes.insertAt(0, myOverlay);
  $("#log").html("Map loaded!");
  });//onload
  //]]>
  </script>
  <?php
  include_footer()
  ?>
 
 
  <?php
  include ('../include/common.inc.php');
  $debugOkay = Array();
 
  /*
  *DISCLAIMER
  * http://blog.gmapify.fr/create-beautiful-tiled-heat-maps-with-php-and-gd
  *THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * @author: Olivier G. <olbibigo_AT_gmail_DOT_com>
  * @version: 1.0
  * @history:
  * 1.0 creation
  */
  set_time_limit(120);//2mn
  ini_set('memory_limit', '256M');
  error_reporting(E_ALL ^ E_DEPRECATED);
  require_once ('lib/GoogleMapUtility.php');
  require_once ('lib/HeatMap.php');
 
  //Root folder to store generated tiles
  define('TILE_DIR', 'tiles/');
  //Covered geographic areas
  define('MIN_LAT', -35.48);
  define('MAX_LAT', -35.15);
  define('MIN_LNG', 148.98);
  define('MAX_LNG', 149.25);
  define('TILE_SIZE_FACTOR', 0.5);
  define('SPOT_RADIUS', 30);
  define('SPOT_DIMMING_LEVEL', 50);
 
  //Input parameters
  if(isset($_GET['x']))
  $X = (int)$_GET['x'];
  else
  exit("x missing");
  if(isset($_GET['y']))
  $Y = (int)$_GET['y'];
  else
  exit("y missing");
  if(isset($_GET['zoom']))
  $zoom = (int)$_GET['zoom'];
  else
  exit("zoom missing");
 
  $dir = TILE_DIR.$zoom;
  $tilename = $dir.'/'.$X.'_'.$Y.'.png';
  //HTTP headers (data type and caching rule)
  header("Cache-Control: must-revalidate");
  header("Expires: " . gmdate("D, d M Y H:i:s", time() + 86400) . " GMT");
  if(!file_exists($tilename)){
  $rect = GoogleMapUtility::getTileRect($X, $Y, $zoom);
  //A tile can contain part of a spot with center in an adjacent tile (overlaps).
  //Knowing the spot radius (in pixels) and zoom level, a smart way to process tiles would be to compute the box (in decimal degrees) containing only spots that can be drawn on current tile. We choose a simpler solution by increeasing geo bounds by 2*TILE_SIZE_FACTOR whatever the zoom level and spot radius.
  $extend_X = $rect->width * TILE_SIZE_FACTOR;//in decimal degrees
  $extend_Y = $rect->height * TILE_SIZE_FACTOR;//in decimal degrees
  $swlat = $rect->y - $extend_Y;
  $swlng = $rect->x - $extend_X;
  $nelat = $swlat + $rect->height + 2 * $extend_Y;
  $nelng = $swlng + $rect->width + 2 * $extend_X;
 
  if( ($nelat <= MIN_LAT) || ($swlat >= MAX_LAT) || ($nelng <= MIN_LNG) || ($swlng >= MAX_LNG)){
  //No geodata so return generic empty tile
  echo file_get_contents(TILE_DIR.'empty.png');
  exit();
  }
 
  //Get McDonald's spots
  $spots = fGetPOI('Select * from stops where
  (stop_lon > '.$swlng.' AND stop_lon < '.$nelng.')
  AND (stop_lat < '.$nelat.' AND stop_lat > '.$swlat.')', $im, $X, $Y, $zoom, SPOT_RADIUS);
 
 
  if(empty($spots)){
  //No geodata so return generic empty tile
  header('Content-type: image/png');
  echo file_get_contents(TILE_DIR.'empty.png');
  }else{
  if(!file_exists($dir)){
  mkdir($dir, 0705);
  }
  //All the magics is in HeatMap class :)
  $im = HeatMap::createImage($spots, GoogleMapUtility::TILE_SIZE, GoogleMapUtility::TILE_SIZE, heatMap::$WITH_ALPHA, SPOT_RADIUS, SPOT_DIMMING_LEVEL, HeatMap::$GRADIENT_FIRE);
  //Store tile for reuse and output it
  header('content-type:image/png;');
  imagepng($im, $tilename);
  echo file_get_contents($tilename);
  imagedestroy($im);
  unset($im);
  }
  }else{
  //Output stored tile
  header('content-type:image/png;');
  echo file_get_contents($tilename);
  }
  /////////////
  //Functions//
  /////////////
  function fGetPOI($query, &$im, $X, $Y, $zoom, $offset){
  global $conn;
  $nbPOIInsideTile = 0;
 
  $result = pg_query($conn, $query);
  $spots = Array();
  if (!$result) {
  databaseError(pg_result_error($result));
  return Array();
  }
  foreach( pg_fetch_all($result) as $row){
  $point = GoogleMapUtility::getOffsetPixelCoords($row['stop_lat'], $row['stop_lon'], $zoom, $X, $Y);
  //Count result only in the tile
  if( ($point->x > -$offset) && ($point->x < (GoogleMapUtility::TILE_SIZE+$offset)) && ($point->y > -$offset) && ($point->y < (GoogleMapUtility::TILE_SIZE+$offset))){
  $spots[] = new HeatMapPoint($point->x, $point->y);
  }
 
  }//while
  return $spots;
  }//fAddPOI
  ?>
 
 
 Binary files /dev/null and b/labs/gradient/classic.png differ
 Binary files /dev/null and b/labs/gradient/fire.png differ
 Binary files /dev/null and b/labs/gradient/pgaitch.png differ
<?php <?php
include ('../include/common.inc.php'); include ('../include/common.inc.php');
include_header("Busness R&D", "index") include_header("Busness R&D", "index")
?> ?>
<ul data-role="listview" data-theme="e" data-groupingtheme="e"> <ul data-role="listview" data-theme="e" data-groupingtheme="e">
<li data-role="list-divider" > Experimental Features </li> <li data-role="list-divider" > Experimental Features </li>
<li><a href="mywaybalance.php"><h3>MyWay Balance for mobile</h3> <li><a href="mywaybalance.php"><h3>MyWay Balance for mobile</h3>
<p>Mobile viewer for MyWay balance. Warning! No HTTPS security.</p></a></li> <p>Mobile viewer for MyWay balance. Warning! No HTTPS security.</p></a></li>
<li><a href="networkstats.php"><h3>Network/Route Statistics</h3> <li><a href="networkstats.php"><h3>Route Statistics</h3>
<p>Statistical analysis of network/routes</p></a></li> <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>More coming soon!</li> <li>More coming soon!</li>
</ul> </ul>
</div> </div>
<?php <?php
include_footer() include_footer()
?> ?>
   
<?php <?php
include ('../include/common.inc.php'); include ('../include/common.inc.php');
include_header("Network/Route Statistics", "networkstats") include_header("Route Statistics", "networkstats")
?> ?>
<script type="text/javascript" src="js/flotr/lib/prototype-1.6.0.2.js"></script> <script type="text/javascript" src="js/flotr/lib/prototype-1.6.0.2.js"></script>
   
<!--[if IE]> <!--[if IE]>
   
<script type="text/javascript" src="js/flotr/lib/excanvas.js"></script> <script type="text/javascript" src="js/flotr/lib/excanvas.js"></script>
   
<script type="text/javascript" src="js/flotr/lib/base64.js"></script> <script type="text/javascript" src="js/flotr/lib/base64.js"></script>
   
<![endif]--> <![endif]-->
   
<script type="text/javascript" src="js/flotr/lib/canvas2image.js"></script> <script type="text/javascript" src="js/flotr/lib/canvas2image.js"></script>
   
<script type="text/javascript" src="js/flotr/lib/canvastext.js"></script> <script type="text/javascript" src="js/flotr/lib/canvastext.js"></script>
   
<script type="text/javascript" src="js/flotr/flotr.debug-0.2.0-alpha_radar1.js"></script> <script type="text/javascript" src="js/flotr/flotr.debug-0.2.0-alpha_radar1.js"></script>
<form method="get" action="networkstats.php"> <form method="get" action="networkstats.php">
<select id="routeid" name="routeid"> <select id="routeid" name="routeid">
<?php <?php
foreach (getRoutes() as $route) { foreach (getRoutes() as $route) {
echo "<option value=\"{$route['route_id']}\">{$route['route_short_name']} {$route['route_long_name']}</option>"; echo "<option value=\"{$route['route_id']}\">{$route['route_short_name']} {$route['route_long_name']}</option>";
} }
?> ?>
</select> </select>
<input type="submit" value="View"/> <input type="submit" value="View"/>
</form> </form>
   
<?php <?php
// middle of graph = 6am // middle of graph = 6am
$adjustFactor = 0; $adjustFactor = 0;
$routeid = ($_REQUEST['routeid'] ? filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT) : 0); $routeid = ($_REQUEST['routeid'] ? filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT) : 0);
$route = getRoute($routeid); $route = getRoute($routeid);
echo "<h1>{$route['route_short_name']} {$route['route_long_name']}</h1>"; echo "<h1>{$route['route_short_name']} {$route['route_long_name']}</h1>";
foreach (getRouteTrips($routeid) as $key => $trip) { foreach (getRouteTrips($routeid) as $key => $trip) {
$dLabel[$key] = $trip['arrival_time']; $dLabel[$key] = $trip['arrival_time'];
if ($key == 0) { if ($key == 0) {
$time = strtotime($trip['arrival_time']); $time = strtotime($trip['arrival_time']);
$adjustFactor = (date("G", $time) * 3600); $adjustFactor = (date("G", $time) * 3600);
} }
$tripStops = viaPoints($trip['trip_id']); $tripStops = viaPoints($trip['trip_id']);
foreach ($tripStops as $i => $stop) { foreach ($tripStops as $i => $stop) {
if ($key == 0) { if ($key == 0) {
$dTicks[$i] = $stop['stop_name']; $dTicks[$i] = $stop['stop_name'];
} }
$time = strtotime($stop['arrival_time']); $time = strtotime($stop['arrival_time']);
$d[$key][$i] = (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time) - $adjustFactor; $d[$key][$i] = (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time) - $adjustFactor;
   
} }
} }
   
?> ?>
<div id="container" style="width:100%;height:900px;"></div> <div id="container" style="width:100%;height:900px;"></div>
<script type="text/javascript"> <script type="text/javascript">
   
/** /**
   
* Wait till dom's finished loading. * Wait till dom's finished loading.
   
*/ */
   
document.observe('dom:loaded', function(){ document.observe('dom:loaded', function(){