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");
  $query = $conn->prepare($query);
  $query->bindParam(":stopID", $stopID);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetch(PDO :: FETCH_ASSOC);
  }
   
  function getStops($firstLetter = "", $startsWith = "") {
  global $conn;
  $conditions = Array();
  if ($firstLetter != "")
  $conditions[] = "substr(stop_name,1,1) = :firstLetter";
  if ($startsWith != "")
  $conditions[] = "stop_name like :startsWith";
  $query = "Select * from stops";
  if (sizeof($conditions) > 0) {
  if (sizeof($conditions) > 1) {
  $query .= " Where " . implode(" AND ", $conditions) . " ";
  } else {
  $query .= " Where " . $conditions[0] . " ";
  }
  }
  $query .= " order by stop_name;";
  debug($query,"database");
  $query = $conn->prepare($query);
  if ($firstLetter != "")
  $query->bindParam(":firstLetter", $firstLetter);
   
  if ($startsWith != "") {
  $startsWith = $startsWith . "%";
  $query->bindParam(":startsWith", $startsWith);
  }
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
   
  function getNearbyStops($lat, $lng, $limit = "", $distance = 1000) {
  if ($lat == null || $lng == null)
  return Array();
  if ($limit != "")
  $limitSQL = " LIMIT :limit ";
  global $conn;
  $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)
  order by distance $limitSQL;";
  debug($query, "database");
  $query = $conn->prepare($query);
  $query->bindParam(":distance", $distance);
  $query->bindParam(":limit", $limit);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
   
  function getStopsByName($name) {
  global $conn;
  $query = "Select * from stops where stop_name LIKE :name;";
  debug($query, "database");
  $query = $conn->prepare($query);
  $name = "%" . $name . ";%";
  $query->bindParam(":name", $name);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
   
  function getStopsBySuburb($suburb) {
  global $conn;
  $query = "Select * from stops where zone_id LIKE :suburb order by stop_name;";
  debug($query, "database");
  $query = $conn->prepare($query);
  $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];
function getStops($timingPointsOnly = false) { $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 =
function stopsNear($lat,$lng,$limit) { 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");
-- Show a distance query and note, London is outside the 1000km tolerance $query = $conn->prepare($query);
SELECT name FROM global_points WHERE ST_DWithin(location, ST_GeographyFromText('SRID=4326;POINT(-110 29)'), 1000000, FALSE); $query->bindParam(":service_periodA", $sidA);
// 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. $query->bindParam(":service_periodB", $sidB);
*/ $query->bindParam(":stopID", $stopID);
} $query->execute();
  if (!$query) {
function stopsBySuburb($suburb) { databaseError($conn->errorInfo());
  return Array();
} }
  return $query->fetchAll();
function stopRoutes($stopID,$service_period) }
/*  
def handle_json_GET_stoproutes(self, params): function getStopTrips($stopID, $service_period = "", $afterTime = "", $limit = "") {
"""Given a stop_id return all routes to visit the stop.""" if ($service_period == "")
schedule = self.server.schedule $service_period = service_period();
stop = schedule.GetStop(params.get('stop', None)) $service_ids = service_ids($service_period);
service_period = params.get('service_period', None) $sidA = $service_ids[0];
trips = stop.GetTrips(schedule) $sidB = $service_ids[1];
result = {} if ($limit != "")
for trip in trips: $limitSQL = " LIMIT :limit ";
route = schedule.GetRoute(trip.route_id) global $conn;
if service_period == None or trip.service_id == service_period: if ($afterTime != "") {
if not route.route_short_name+route.route_long_name+trip.service_id in result: $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
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) FROM stop_times
return result 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
function stopTrips($stopID) { WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times
/* WHERE stop_times.stop_id = :stopID
def handle_json_GET_stopalltrips(self, params): AND stop_times.trip_id = end_times.trip_id
"""Given a stop_id return all trips to visit the stop (without times).""" AND (service_id=:service_periodA OR service_id=:service_periodB)
schedule = self.server.schedule AND end_times.arrival_time > :afterTime
stop = schedule.GetStop(params.get('stop', None)) ORDER BY end_time $limitSQL";
service_period = params.get('service_period', None) } else {
trips = stop.GetTrips(schedule) $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
result = [] FROM stop_times
for trip in trips: join trips on trips.trip_id =
if service_period == None or trip.service_id == service_period: stop_times.trip_id
result.append((trip.trip_id, trip.service_id)) join routes on trips.route_id = routes.route_id
return result WHERE stop_times.stop_id = :stopID
*/ AND (service_id=:service_periodA OR service_id=:service_periodB)
} ORDER BY arrival_time $limitSQL";
function stopTripsWithTimes($stopID, $time, $service_period) { }
/* debug($query, "database");
def handle_json_GET_stoptrips(self, params): $query = $conn->prepare($query);
"""Given a stop_id and time in seconds since midnight return the next $query->bindParam(":service_periodA", $sidA);
trips to visit the stop.""" $query->bindParam(":service_periodB", $sidB);
schedule = self.server.schedule $query->bindParam(":stopID", $stopID);
stop = schedule.GetStop(params.get('stop', None)) if ($limit != "")
requested_time = int(params.get('time', 0)) $query->bindParam(":limit", $limit);
limit = int(params.get('limit', 15)) if ($afterTime != "")
service_period = params.get('service_period', None) $query->bindParam(":afterTime", $afterTime);
time_range = int(params.get('time_range', 24*60*60)) $query->execute();
  if (!$query) {
filtered_time_trips = [] databaseError($conn->errorInfo());
for trip, index in stop._GetTripIndex(schedule): return Array();
tripstarttime = trip.GetStartTime() }
if tripstarttime > requested_time and tripstarttime < (requested_time + time_range): return $query->fetchAll();
time, stoptime, tp = trip.GetTimeInterpolatedStops()[index] }
if time > requested_time and time < (requested_time + time_range):  
bisect.insort(filtered_time_trips, (time, (trip, index), tp)) function getStopTripsWithTimes($stopID, $time = "", $service_period = "", $time_range = "", $limit = "") {
result = [] if ($service_period == "")
for time, (trip, index), tp in filtered_time_trips: $service_period = service_period();
if len(result) > limit: if ($time_range == "")
break $time_range = (24 * 60 * 60);
route = schedule.GetRoute(trip.route_id) if ($time == "")
trip_name = '' $time = current_time();
if route.route_short_name: if ($limit == "")
trip_name += route.route_short_name $limit = 10;
if route.route_long_name: $trips = getStopTrips($stopID, $service_period, $time);
if len(trip_name): $timedTrips = Array();
trip_name += " - " if ($trips && sizeof($trips) > 0) {
trip_name += route.route_long_name foreach ($trips as $trip) {
if service_period == None or trip.service_id == service_period: if ($trip['arrival_time'] != "") {
result.append((time, (trip.trip_id, trip_name, trip.service_id), tp)) if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) {
return result $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;
  }
   
?> ?>