From: maxious Date: Tue, 11 Oct 2011 03:51:43 +0000 Subject: Begin support of double service ids for each service period X-Git-Url: https://maxious.lambdacomplex.org/git/?p=busui.git&a=commitdiff&h=5f65726a59cf3812ff417db2d02d8d9f7de5ce03 --- Begin support of double service ids for each service period --- --- a/include/common-transit.inc.php +++ b/include/common-transit.inc.php @@ -37,6 +37,17 @@ return 'saturday'; default: return 'weekday'; + } +} +function service_ids($service_period) { + switch ($service_period) { + case 'sunday': + return Array("2010-TUGGSUN-Sunday-20","2010-BELCSUN-Sunday-19"); + case 'saturday': + return Array("2010-BELCSAT-Saturday-19","2010-TUGGSAT-Saturday-19"); + default: + //return 'weekday'; + return Array("2010-BELCMAST-Weekday-15","2010-TUGGMAST-Weekday-14"); } } --- a/include/common.inc.php +++ b/include/common.inc.php @@ -55,6 +55,7 @@ $basePath = "../"; function isDebugServer() { + return php_sapi_name() == "cli" || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == "azusa" || $_SERVER['SERVER_NAME'] == "vanille" || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1"); } @@ -71,7 +72,7 @@ function isAnalyticsOn() { $user_agent = $_SERVER['HTTP_USER_AGENT']; - return!isDebugServer() && !preg_match('/cloudkick/i', $user_agent) && !preg_match('/googlebot/i', $user_agent) && + return !isDebugServer() && !preg_match('/cloudkick/i', $user_agent) && !preg_match('/googlebot/i', $user_agent) && !preg_match('/baidu/i', $user_agent); } @@ -133,10 +134,6 @@ 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(")", "", str_replace("(", "
", $input)); } function sksort(&$array, $subkey = "id", $sort_ascending = false) { @@ -202,5 +199,6 @@ return implode($glue, $retVal); } + ?> --- a/include/db/route-dao.inc.php +++ b/include/db/route-dao.inc.php @@ -140,10 +140,10 @@ return $r; } -function getTimeInterpolatedRouteAtStop($routeID, $stop_id) { +function getRouteAtStop($routeID, $stop_id) { $nextTrip = getRouteNextTrip($routeID); if ($nextTrip['trip_id']) { - foreach (getTimeInterpolatedTrip($nextTrip['trip_id']) as $tripStop) { + foreach (getTripStopTimes($nextTrip['trip_id']) as $tripStop) { if ($tripStop['stop_id'] == $stop_id) return $tripStop; } @@ -220,6 +220,9 @@ function getRoutesNearby($lat, $lng, $limit = "", $distance = 500) { if ($service_period == "") $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; if ($limit != "") $limitSQL = " LIMIT :limit "; global $conn; @@ -229,13 +232,14 @@ join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id join stops on stops.stop_id = stop_times.stop_id -WHERE service_id=:service_period +WHERE (service_id=:service_periodA OR service_id=:service_periodB) AND ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), :distance, FALSE) group by service_id,trips.route_id,route_short_name,route_long_name order by distance $limitSQL"; debug($query, "database"); $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); $query->bindParam(":distance", $distance); if ($limit != "") $query->bindParam(":limit", $limit); --- a/include/db/stop-dao.inc.php +++ b/include/db/stop-dao.inc.php @@ -30,11 +30,9 @@ return $query->fetch(PDO :: FETCH_ASSOC); } -function getStops($timingPointsOnly = false, $firstLetter = "", $startsWith = "") { +function getStops($firstLetter = "", $startsWith = "") { global $conn; $conditions = Array(); - if ($timingPointsOnly) - $conditions[] = "substr(stop_code,1,2) != 'Wj'"; if ($firstLetter != "") $conditions[] = "substr(stop_name,1,1) = :firstLetter"; if ($startsWith != "") @@ -48,6 +46,7 @@ } } $query .= " order by stop_name;"; + debug($query,"database"); $query = $conn->prepare($query); if ($firstLetter != "") $query->bindParam(":firstLetter", $firstLetter); @@ -142,13 +141,19 @@ 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_period"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); +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) { @@ -161,6 +166,9 @@ function getStopTrips($stopID, $service_period = "", $afterTime = "", $limit = "") { if ($service_period == "") $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; if ($limit != "") $limitSQL = " LIMIT :limit "; global $conn; @@ -173,7 +181,7 @@ 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_period +AND (service_id=:service_periodA OR service_id=:service_periodB) AND end_times.arrival_time > :afterTime ORDER BY end_time $limitSQL"; } else { @@ -183,12 +191,13 @@ stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_times.stop_id = :stopID -AND service_id=:service_period +AND (service_id=:service_periodA OR service_id=:service_periodB) ORDER BY arrival_time $limitSQL"; } debug($query, "database"); $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); $query->bindParam(":stopID", $stopID); if ($limit != "") $query->bindParam(":limit", $limit); @@ -220,7 +229,7 @@ $timedTrips[] = $trip; } } else { - $timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']); + $timedTrip = getTripAtStop($trip['trip_id'], $trip['stop_sequence']); if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) { $timedTrips[] = $timedTrip; } --- a/include/db/trip-dao.inc.php +++ b/include/db/trip-dao.inc.php @@ -34,6 +34,7 @@ } function getTripShape($tripID) { + // todo, use shapes table if shape_id specified global $conn; $query = "SELECT ST_AsKML(ST_MakeLine(geometry(a.position))) as the_route FROM (SELECT position, @@ -53,7 +54,7 @@ return $query->fetchColumn(0); } -function getTimeInterpolatedTrip($tripID, $range = "") { +function getTripStopTimes($tripID) { global $conn; $query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_lat,stop_lon,stop_name,stop_code, stop_sequence,service_id,trips.route_id,route_short_name,route_long_name @@ -71,104 +72,137 @@ return Array(); } $stopTimes = $query->fetchAll(); - $cur_timepoint = Array(); - $next_timepoint = Array(); - $distance_between_timepoints = 0.0; - $distance_traveled_between_timepoints = 0.0; - $rv = Array(); - foreach ($stopTimes as $i => $stopTime) { - if ($stopTime['arrival_time'] != "") { - // is timepoint - $cur_timepoint = $stopTime; - $distance_between_timepoints = 0.0; - $distance_traveled_between_timepoints = 0.0; - if ($i + 1 < sizeof($stopTimes)) { - $k = $i + 1; - $distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); - while ($stopTimes[$k]["arrival_time"] == "" && $k + 1 < sizeof($stopTimes)) { - $k += 1; - // echo "k".$k; - $distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); - } - $next_timepoint = $stopTimes[$k]; - } - $rv[] = $stopTime; - } else { - // is untimed point - // echo "i".$i; - $distance_traveled_between_timepoints += distance($stopTimes[$i - 1]["stop_lat"], $stopTimes[$i - 1]["stop_lon"], $stopTimes[$i]["stop_lat"], $stopTimes[$i]["stop_lon"]); - // echo "$distance_traveled_between_timepoints / $distance_between_timepoints
"; - $distance_percent = $distance_traveled_between_timepoints / $distance_between_timepoints; - if ($next_timepoint["arrival_time"] != "") { - $total_time = strtotime($next_timepoint["arrival_time"]) - strtotime($cur_timepoint["arrival_time"]); - // echo strtotime($next_timepoint["arrival_time"])." - ".strtotime($cur_timepoint["arrival_time"])."
"; - $time_estimate = ($distance_percent * $total_time) + strtotime($cur_timepoint["arrival_time"]); - $stopTime["arrival_time"] = date("H:i:s", $time_estimate); - } else { - $stopTime["arrival_time"] = $cur_timepoint["arrival_time"]; - } - $rv[] = $stopTime; - } - } - // var_dump($rv); - return $rv; -} - -function getTripPreviousTimePoint($tripID, $stop_sequence) { - global $conn; - $query = " SELECT trip_id,stop_id, - stop_sequence -FROM stop_times -WHERE trip_id = :tripID and stop_sequence < :stop_sequence -and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence DESC LIMIT 1"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":tripID", $tripID); - $query->bindParam(":stop_sequence", $stop_sequence); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetch(PDO :: FETCH_ASSOC); -} - -function getTripNextTimePoint($tripID, $stop_sequence) { - global $conn; - $query = " SELECT trip_id,stop_id, - stop_sequence -FROM stop_times -WHERE trip_id = :tripID and stop_sequence > :stop_sequence -and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence LIMIT 1"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":tripID", $tripID); - $query->bindParam(":stop_sequence", $stop_sequence); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetch(PDO :: FETCH_ASSOC); -} - -function getTimeInterpolatedTripAtStop($tripID, $stop_sequence) { - global $conn; - // limit interpolation to between nearest actual points. - $prevTimePoint = getTripPreviousTimePoint($tripID, $stop_sequence); - $nextTimePoint = getTripNextTimePoint($tripID, $stop_sequence); - // echo " prev {$lowestDelta['stop_sequence']} next {$nextTimePoint['stop_sequence']} "; - $range = ""; - if ($prevTimePoint != "") - $range .= " AND stop_sequence >= '{$prevTimePoint['stop_sequence']}'"; - if ($nextTimePoint != "") - $range .= " AND stop_sequence <= '{$nextTimePoint['stop_sequence']}'"; - foreach (getTimeInterpolatedTrip($tripID, $range) as $tripStop) { + return $stopTimes; +} + +function getTripAtStop($tripID, $stop_sequence) { + global $conn; + foreach (getTripStopTimes($tripID) as $tripStop) { if ($tripStop['stop_sequence'] == $stop_sequence) return $tripStop; } return Array(); } + +/* DEPRECIATED + function getTimeInterpolatedTrip($tripID, $range = "") { + global $conn; + $query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_lat,stop_lon,stop_name,stop_code, + 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 + join stops on stops.stop_id = stop_times.stop_id + WHERE trips.trip_id = :tripID $range ORDER BY stop_sequence"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $stopTimes = $query->fetchAll(); + $cur_timepoint = Array(); + $next_timepoint = Array(); + $distance_between_timepoints = 0.0; + $distance_traveled_between_timepoints = 0.0; + $rv = Array(); + foreach ($stopTimes as $i => $stopTime) { + if ($stopTime['arrival_time'] != "") { + // is timepoint + $cur_timepoint = $stopTime; + $distance_between_timepoints = 0.0; + $distance_traveled_between_timepoints = 0.0; + if ($i + 1 < sizeof($stopTimes)) { + $k = $i + 1; + $distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); + while ($stopTimes[$k]["arrival_time"] == "" && $k + 1 < sizeof($stopTimes)) { + $k += 1; + // echo "k".$k; + $distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); + } + $next_timepoint = $stopTimes[$k]; + } + $rv[] = $stopTime; + } else { + // is untimed point + // echo "i".$i; + $distance_traveled_between_timepoints += distance($stopTimes[$i - 1]["stop_lat"], $stopTimes[$i - 1]["stop_lon"], $stopTimes[$i]["stop_lat"], $stopTimes[$i]["stop_lon"]); + // echo "$distance_traveled_between_timepoints / $distance_between_timepoints
"; + $distance_percent = $distance_traveled_between_timepoints / $distance_between_timepoints; + if ($next_timepoint["arrival_time"] != "") { + $total_time = strtotime($next_timepoint["arrival_time"]) - strtotime($cur_timepoint["arrival_time"]); + // echo strtotime($next_timepoint["arrival_time"])." - ".strtotime($cur_timepoint["arrival_time"])."
"; + $time_estimate = ($distance_percent * $total_time) + strtotime($cur_timepoint["arrival_time"]); + $stopTime["arrival_time"] = date("H:i:s", $time_estimate); + } else { + $stopTime["arrival_time"] = $cur_timepoint["arrival_time"]; + } + $rv[] = $stopTime; + } + } + // var_dump($rv); + return $rv; + } + + function getTripPreviousTimePoint($tripID, $stop_sequence) { + global $conn; + $query = " SELECT trip_id,stop_id, + stop_sequence + FROM stop_times + WHERE trip_id = :tripID and stop_sequence < :stop_sequence + and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence DESC LIMIT 1"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->bindParam(":stop_sequence", $stop_sequence); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); + } + + function getTripNextTimePoint($tripID, $stop_sequence) { + global $conn; + $query = " SELECT trip_id,stop_id, + stop_sequence + FROM stop_times + WHERE trip_id = :tripID and stop_sequence > :stop_sequence + and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence LIMIT 1"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->bindParam(":stop_sequence", $stop_sequence); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); + } + + + + function getTimeInterpolatedTripAtStop($tripID, $stop_sequence) { + global $conn; + // limit interpolation to between nearest actual points. + $prevTimePoint = getTripPreviousTimePoint($tripID, $stop_sequence); + $nextTimePoint = getTripNextTimePoint($tripID, $stop_sequence); + // echo " prev {$lowestDelta['stop_sequence']} next {$nextTimePoint['stop_sequence']} "; + $range = ""; + if ($prevTimePoint != "") + $range .= " AND stop_sequence >= '{$prevTimePoint['stop_sequence']}'"; + if ($nextTimePoint != "") + $range .= " AND stop_sequence <= '{$nextTimePoint['stop_sequence']}'"; + foreach (getTimeInterpolatedTrip($tripID, $range) as $tripStop) { + if ($tripStop['stop_sequence'] == $stop_sequence) + return $tripStop; + } + return Array(); + } */ function getTripStartTime($tripID) { global $conn; @@ -222,12 +256,12 @@ return $query->fetchAll(); } -function viaPoints($tripID, $stop_sequence = "", $timing_points_only = true) { +function viaPoints($tripID, $stop_sequence = "") { global $conn; $query = "SELECT stops.stop_id, stop_name, arrival_time FROM stop_times join stops on stops.stop_id = stop_times.stop_id WHERE stop_times.trip_id = :tripID -" . ($stop_sequence != "" ? " AND stop_sequence > :stop_sequence " : "") . ($timing_points_only ? "AND substr(stop_code,1,2) != 'Wj' " : "") . " ORDER BY stop_sequence"; +" . ($stop_sequence != "" ? " AND stop_sequence > :stop_sequence " : "") . " ORDER BY stop_sequence"; debug($query, "database"); $query = $conn->prepare($query); if ($stop_sequence != "") --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -1,5 +1,5 @@ include.path=${php.global.include.path} -php.version=PHP_5 +php.version=PHP_53 source.encoding=UTF-8 src.dir=. tags.asp=false --- a/routeList.php +++ b/routeList.php @@ -71,7 +71,7 @@ foreach ($routes as $route) { echo '
  • ' . $route['route_short_name'] . "

    " . $route['route_long_name'] . " (" . ucwords($route['service_id']) . ")

    "; if (isset($nearby)) { - $time = getTimeInterpolatedRouteAtStop($route['route_id'], $route['stop_id']); + $time = getRouteAtStop($route['route_id'], $route['stop_id']); echo '' . ($time['arrival_time'] ? $time['arrival_time'] : "No more trips today") . "
    " . floor($route['distance']) . 'm away
    '; } echo "
  • \n"; --- a/stop.php +++ b/stop.php @@ -43,16 +43,12 @@ } $stop = $stops[0]; $stopid = $stops[0]["stop_id"]; - $stopLinks.= "Individual stop pages: "; + $stopLinks.= "Individual stop pages:
    "; foreach ($stops as $key => $sub_stop) { - // $stopNames[$key] = $sub_stop[1] . ' Stop #' . ($key + 1); - if (strpos($stop["stop_name"], "Station")) { - $stopNames[$key] = 'Platform ' . ($key + 1); - $stopLinks.= '' . $sub_stop["stop_name"] . ' '; - } else { - $stopNames[$key] = '#' . ($key + 1); - $stopLinks.= '' . $sub_stop["stop_name"] . ' Stop #' . ($key + 1) . ' '; - } + + $stopNames[$key] = $sub_stop["stop_name"]; + $stopLinks.= '' . $sub_stop["stop_name"] . ' '; + $stopPositions[$key] = Array( $sub_stop["stop_lat"], $sub_stop["stop_lon"] @@ -143,8 +139,12 @@ echo '
    Via: ' . $viaPoints . ''; if (sizeof($tripStopNumbers) > 0) { echo '
    Boarding At: '; - foreach ($tripStopNumbers[$trip['trip_id']] as $key) { - echo $stopNames[$key] . ' '; + if (sizeof($tripStopNumbers[$trip['trip_id']]) == sizeof($stopids)) { + echo "All Stops"; + } else { + foreach ($tripStopNumbers[$trip['trip_id']] as $key) { + echo $stopNames[$key] . ', '; + } } echo ''; } --- a/stopList.php +++ b/stopList.php @@ -17,7 +17,17 @@ */ include ('include/common.inc.php'); $stops = Array(); - +function stopCompare($stopName) { + return substr(trim(preg_replace("/\(Platform.*/", "", $stopName)),0,9); +} +function stopGroupTitle($stopName,$stopdesc) { + if (preg_match("/Dr |Cct |Cir |Av |St /",$stopName)) { + $descParts = explode("
    ",$stopdesc); + return trim(str_replace("Street: ","",$descParts[0])); + } else { + return trim(preg_replace("/\(Platform.*/", "",$stopName)); + } +} function navbar() { echo '
    @@ -52,7 +62,7 @@ // Timing Points / All stops if (isset($allstops)) { $listType = 'allstops=yes'; - $stops = getStops(); + $stops = getStops($firstLetter); include_header("All Stops", "stopList"); navbar(); } else if (isset($nearby)) { @@ -99,19 +109,19 @@ //var_dump($stops); $stopsGrouped = Array(); foreach ($stops as $key => $stop) { - if ((trim(preg_replace("/\(Platform.*/", "", $stops[$key]["stop_name"])) != trim(preg_replace("/\(Platform.*/", "", $stops[$key + 1]["stop_name"]))) || $key + 1 >= sizeof($stops)) { + if (stopCompare($stops[$key]["stop_name"]) + != stopCompare($stops[$key + 1]["stop_name"]) + || $key + 1 >= sizeof($stops)) { if (sizeof($stopsGrouped) > 0) { // print and empty grouped stops // subsequent duplicates $stopsGrouped["stop_ids"][] = $stop['stop_id']; echo '
  • '; - if (!startsWith($stopsGrouped['stop_codes'][0], "Wj")) - echo 'Timing Point: '; echo ''; if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { echo '' . distance($stop['stop_lat'], $stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away'; } - echo bracketsMeanNewLine(trim(preg_replace("/\(Platform.*/", "", $stop['stop_name'])) . '(' . sizeof($stopsGrouped["stop_ids"]) . ' stops)'); + echo stopGroupTitle($stop['stop_name'],$stop['stop_desc']) . '
    ' . sizeof($stopsGrouped["stop_ids"]) . ' stops'; echo "
  • \n"; flush(); @ob_flush(); @@ -119,20 +129,18 @@ } else { // just a normal stop echo '
  • '; - if (!startsWith($stop['stop_code'], "Wj")) - echo 'Timing Point'; - echo ''; + echo ''; if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { echo '' . distance($stop['stop_lat'], $stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away'; } - echo bracketsMeanNewLine($stop['stop_name']); + echo $stop['stop_name']; echo "
  • \n"; flush(); @ob_flush(); } } else { // this is a duplicated line item - if ($key - 1 <= 0 || (trim(preg_replace("/\(Platform.*/", "", $stops[$key]['stop_name'])) != trim(preg_replace("/\(Platform.*/", "", $stops[$key - 1]['stop_name'])))) { + if ($key - 1 <= 0 || stopCompare($stops[$key]['stop_name']) != stopCompare($stops[$key - 1]['stop_name'])) { // first duplicate $stopsGrouped = Array( "name" => trim(preg_replace("/\(Platform.*/", "", $stop['stop_name'])), --- a/trip.php +++ b/trip.php @@ -66,13 +66,12 @@ echo "
    "; echo '