Refactor to use PostGIS database instead of gtfs tools
[busui.git] / include / db / stop-dao.inc.php
blob:a/include/db/stop-dao.inc.php -> blob:b/include/db/stop-dao.inc.php
<?php <?php
/* def StopZoneToTuple(stop):  
"""Return tuple as expected by javascript function addStopMarkerFromList""" /*
return (stop.stop_id, stop.stop_name, float(stop.stop_lat), * Copyright 2010,2011 Alexander Sadleir
float(stop.stop_lon), stop.location_type, stop.stop_code, stop.zone_id)  
*/ 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.
  */
   
function getStop($stopID) { function getStop($stopID) {
  global $conn;
} $query = 'Select * from stops where stop_id = :stopID LIMIT 1';
  debug($query, 'database');
function getStops($timingPointsOnly = false) { $query = $conn->prepare($query);
  $query->bindParam(':stopID', $stopID);
} $query->execute();
  if (!$query) {
function stopsNear($lat,$lng,$limit) { databaseError($conn->errorInfo());
  return Array();
/* }
-- Show a distance query and note, London is outside the 1000km tolerance return $query->fetch(PDO :: FETCH_ASSOC);
SELECT name FROM global_points WHERE ST_DWithin(location, ST_GeographyFromText('SRID=4326;POINT(-110 29)'), 1000000, FALSE); }
// All the geography functions have the option of using a sphere calculation, by setting a final boolean parameter to 'FALSE'. This will somewhat speed up calculations, particularly for cases where the geometries are very simple.  
*/ function getStops($firstLetter = '', $startsWith = '') {
} global $conn;
  $conditions = Array();
function stopsBySuburb($suburb) { if ($firstLetter != '')
  $conditions[] = 'substr(stop_name,1,1) = :firstLetter';
} if ($startsWith != '')
  $conditions[] = 'stop_name like :startsWith';
function stopRoutes($stopID,$service_period) $query = 'Select * from stops';
/* if (sizeof($conditions) > 0) {
def handle_json_GET_stoproutes(self, params): if (sizeof($conditions) > 1) {
"""Given a stop_id return all routes to visit the stop.""" $query .= ' Where ' . implode(' AND ', $conditions) . ' ';
schedule = self.server.schedule } else {
stop = schedule.GetStop(params.get('stop', None)) $query .= ' Where ' . $conditions[0] . ' ';
service_period = params.get('service_period', None) }
trips = stop.GetTrips(schedule) }
result = {} $query .= ' order by stop_name;';
for trip in trips: debug($query, 'database');
route = schedule.GetRoute(trip.route_id) $query = $conn->prepare($query);
if service_period == None or trip.service_id == service_period: if ($firstLetter != '')
if not route.route_short_name+route.route_long_name+trip.service_id in result: $query->bindParam(':firstLetter', $firstLetter);
result[route.route_short_name+route.route_long_name+trip.service_id] = (route.route_id, route.route_short_name, route.route_long_name, trip.trip_id, trip.service_id)  
return result if ($startsWith != '') {
*/ $startsWith = $startsWith . '%';
  $query->bindParam(':startsWith', $startsWith);
function stopTrips($stopID) { }
/* $query->execute();
def handle_json_GET_stopalltrips(self, params): if (!$query) {
"""Given a stop_id return all trips to visit the stop (without times).""" databaseError($conn->errorInfo());
schedule = self.server.schedule return Array();
stop = schedule.GetStop(params.get('stop', None)) }
service_period = params.get('service_period', None) return $query->fetchAll();
trips = stop.GetTrips(schedule) }
result = []  
for trip in trips: function getNearbyStops($lat, $lng, $limit = '', $distance = 1000) {
if service_period == None or trip.service_id == service_period: if ($lat == null || $lng == null)
result.append((trip.trip_id, trip.service_id)) return Array();
return result if ($limit != '')
*/ $limitSQL = ' LIMIT :limit ';
} global $conn;
function stopTripsWithTimes($stopID, $time, $service_period) { $query = 'Select *, ST_Distance(position, ST_GeographyFromText(\'SRID=4326;POINT('.$lng.' '.$lat.')\'), FALSE) as distance
/* from stops WHERE ST_DWithin(position, ST_GeographyFromText(\'SRID=4326;POINT('.$lng.' '.$lat.')\'), :distance, FALSE)
def handle_json_GET_stoptrips(self, params): order by distance '.$limitSQL;
"""Given a stop_id and time in seconds since midnight return the next debug($query, 'database');
trips to visit the stop.""" $query = $conn->prepare($query);
schedule = self.server.schedule $query->bindParam(':distance', $distance);
stop = schedule.GetStop(params.get('stop', None)) $query->bindParam(':limit', $limit);
requested_time = int(params.get('time', 0)) $query->execute();
limit = int(params.get('limit', 15)) if (!$query) {
service_period = params.get('service_period', None) databaseError($conn->errorInfo());
time_range = int(params.get('time_range', 24*60*60)) return Array();
  }
filtered_time_trips = [] return $query->fetchAll();
for trip, index in stop._GetTripIndex(schedule): }
tripstarttime = trip.GetStartTime()  
if tripstarttime > requested_time and tripstarttime < (requested_time + time_range): function getStopsByName($name) {
time, stoptime, tp = trip.GetTimeInterpolatedStops()[index] global $conn;
if time > requested_time and time < (requested_time + time_range): $query = 'Select * from stops where stop_name LIKE :name;';
bisect.insort(filtered_time_trips, (time, (trip, index), tp)) debug($query, 'database');
result = [] $query = $conn->prepare($query);
for time, (trip, index), tp in filtered_time_trips: $name = $name . '%';
if len(result) > limit: $query->bindParam(':name', $name);
break $query->execute();
route = schedule.GetRoute(trip.route_id) if (!$query) {
trip_name = '' databaseError($conn->errorInfo());
if route.route_short_name: return Array();
trip_name += route.route_short_name }
if route.route_long_name: return $query->fetchAll();
if len(trip_name): }
trip_name += " - "  
trip_name += route.route_long_name function getStopsBySuburb($suburb) {
if service_period == None or trip.service_id == service_period: global $conn;
result.append((time, (trip.trip_id, trip_name, trip.service_id), tp)) $query = 'Select * from stops where stop_desc LIKE :suburb order by stop_name;';
return result debug($query, 'database');
*/ $query = $conn->prepare($query);
} $suburb = '%<br>Suburb: %' . $suburb . '%';
?> $query->bindParam(':suburb', $suburb);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
   
  function getStopsByStopCode($stop_code, $startsWith = '') {
  global $conn;
  $query = 'Select * from stops where (stop_code = :stop_code OR stop_code LIKE :stop_code2)';
  if ($startsWith != '')
  $query .= ' AND stop_name like :startsWith';
   
  debug($query, 'database');
  $query = $conn->prepare($query);
   
  $query->bindParam(':stop_code', $stop_code);
  $stop_code2 = $stop_code . '%';
  $query->bindParam(':stop_code2', $stop_code2);
  if ($startsWith != '') {
  $startsWith = $startsWith . '%';
  $query->bindParam(':startsWith', $startsWith);
  }
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
   
  function getStopRoutes($stopID, $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 WHERE stop_id = :stopID
  AND (service_id=:service_periodA OR service_id=:service_periodB)';
  debug($query, 'database');
  $query = $conn->prepare($query);
  $query->bindParam(':service_periodA', $sidA);
  $query->bindParam(':service_periodB', $sidB);
  $query->bindParam(':stopID', $stopID);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
   
  function getStopTrips($stopID, $service_period = '', $afterTime = '', $limit = '', $route_short_name = '') {
  if ($service_period == '') {
  $service_period = 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,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
  join routes on trips.route_id = routes.route_id , (SELECT trip_id,max(arrival_time) as arrival_time from stop_times
  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 end_times.arrival_time > :afterTime
  ORDER BY end_time '.$limitSQL;
  } else {
  $query = 'SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_sequence,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
  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 ' : '') . '
  ORDER BY arrival_time '.$limitSQL;
  }
  debug($query, 'database');
  $query = $conn->prepare($query);
  $query->bindParam(':service_periodA', $sidA);
  $query->bindParam(':service_periodB', $sidB);
  $query->bindParam(':stopID', $stopID);
  if ($limit != '')
  $query->bindParam(':limit', $limit);
  if ($afterTime != '')
  $query->bindParam(':afterTime', $afterTime);
  if ($route_short_name != '')
  $query->bindParam(':route_short_name', $route_short_name);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
   
  function getStopTripsWithTimes($stopID, $time = '', $service_period = '', $time_range = '', $limit = '') {
  if ($service_period == '')
  $service_period = service_period();
  if ($time_range == '')
  $time_range = (24 * 60 * 60);
  if ($time == '')
  $time = current_time();
  if ($limit == '')
  $limit = 10;
  $trips = getStopTrips($stopID, $service_period, $time);
  $timedTrips = Array();
  if ($trips && sizeof($trips) > 0) {
  foreach ($trips as $trip) {
  if ($trip['arrival_time'] != '') {
  if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) {
  $timedTrips[] = $trip;
  }
  } else {
  $timedTrip = getTripAtStop($trip['trip_id'], $trip['stop_sequence']);
  if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) {
  $timedTrips[] = $timedTrip;
  }
  }
  if (sizeof($timedTrips) > $limit)
  break;
  }
  sktimesort($timedTrips, 'arrival_time', true);
  }
  return $timedTrips;
  }