diff --git a/src/Trafiklab/Gtfs/Model/Entities/Directions.php b/src/Trafiklab/Gtfs/Model/Entities/Directions.php new file mode 100644 index 0000000..00200b2 --- /dev/null +++ b/src/Trafiklab/Gtfs/Model/Entities/Directions.php @@ -0,0 +1,156 @@ + $value) { + $this->$variable = $value; + } + $this->archive = $archive; + } + + /** + * @return string + */ + public function getRouteId(): string + { + return $this->route_id; + } + + /** + * @param string $route_id + */ + public function setRouteId(string $route_id): void + { + $this->route_id = $route_id; + } + + /** + * @return int + */ + public function getDirectionId(): int + { + return $this->direction_id; + } + + /** + * @param int $direction_id + */ + public function setDirectionId(int $direction_id): void + { + $this->direction_id = $direction_id; + } + + /** + * @return string + */ + public function getDirection(): string + { + return $this->direction; + } + + /** + * @param string $direction + */ + public function setDirection(string $direction): void + { + $this->direction = $direction; + } + + /** + * @return GtfsArchive + */ + public function getArchive(): GtfsArchive + { + return $this->archive; + } + + /** + * @param GtfsArchive $archive + */ + public function setArchive(GtfsArchive $archive): void + { + $this->archive = $archive; + } + + /** + * Get the Abbreviation of the Cardinal Direction. + * - Ex: North = N, West = W, South = S, Southeast = SE. + * @param bool $adjective - Whether or not to use NorthBound (NB) + * - Ex: North = NB, NorthEast = NB, South = SB, SouthWest = SB. + * @return string + * * Possible Values: + * - North, South, East, West, Northeast, Northwest, Southeast, Southwest + */ + public function getCardinalDirectionAbrv(bool $adjective = false): string + { + switch (strtolower($this->getDirection())) { + case 'north': + case 'northeast': + case 'northwest': + return $adjective ? 'NB' : 'N'; + case 'south': + case 'southeast': + case 'southwest': + return $adjective ? 'SB' : 'S'; + case 'west': + return $adjective ? 'WB' : 'W'; + case 'east': + return $adjective ? 'EB' : 'E'; + default: + return ''; + } + } + + /** + * Return the value of Inbound(1) or Outbound(0) depending on the value of direction_id. + * Inbound assumes that the vehicle is arriving at said stop or location. + * Outbound assumes that the vehicle is leaving said stop or location. + * @return string + */ + public function getBoundDirection(): string + { + return $this->getDirectionId() === 0 ? 'Outbound' : 'Inbound'; + } +} diff --git a/src/Trafiklab/Gtfs/Model/Files/GtfsDirectionsFile.php b/src/Trafiklab/Gtfs/Model/Files/GtfsDirectionsFile.php new file mode 100644 index 0000000..d40b333 --- /dev/null +++ b/src/Trafiklab/Gtfs/Model/Files/GtfsDirectionsFile.php @@ -0,0 +1,31 @@ +dataRows = GtfsParserUtil::deserializeCSV( + $parent, + $filePath, + Directions::class + ); + } + + /** + * Get the file data as an array of its rows. + * + * @return Directions[] + */ + public function getDirections(): array + { + return $this->dataRows; + } +} diff --git a/src/Trafiklab/Gtfs/Model/GtfsArchive.php b/src/Trafiklab/Gtfs/Model/GtfsArchive.php index b43408b..4dc20a2 100644 --- a/src/Trafiklab/Gtfs/Model/GtfsArchive.php +++ b/src/Trafiklab/Gtfs/Model/GtfsArchive.php @@ -8,6 +8,7 @@ use Trafiklab\Gtfs\Model\Files\GtfsAgencyFile; use Trafiklab\Gtfs\Model\Files\GtfsCalendarDatesFile; use Trafiklab\Gtfs\Model\Files\GtfsCalendarFile; +use Trafiklab\Gtfs\Model\Files\GtfsDirectionsFile; use Trafiklab\Gtfs\Model\Files\GtfsFeedInfoFile; use Trafiklab\Gtfs\Model\Files\GtfsFrequenciesFile; use Trafiklab\Gtfs\Model\Files\GtfsRoutesFile; @@ -38,6 +39,7 @@ class GtfsArchive private const PATHWAYS_TXT = "pathways.txt"; // Unsupported at this moment private const LEVELS_TXT = "levels.txt"; // Unsupported at this moment private const FEED_INFO_TXT = "feed_info.txt"; + private const DIRECTIONS_TXT = "directions.txt"; // Experimental GTFS+ feed. private const TEMP_ROOT = "/tmp/gtfs/"; @@ -320,6 +322,13 @@ public function getFrequenciesFile(): GtfsFrequenciesFile { return $this->loadGtfsFileThroughCache(__METHOD__, self::FREQUENCIES_TXT, GtfsFrequenciesFile::class); } + /** + * @return GtfsDirectionsFile|null + */ + public function getDirectionsFile(): ?GtfsDirectionsFile + { + return $this->loadGtfsFileThroughCache(__METHOD__, self::DIRECTIONS_TXT, GtfsDirectionsFile::class); + } /** * Delete the uncompressed files. This should be done as a cleanup when you're ready. diff --git a/tests/Resources/Gtfs/minified-test-feed.zip b/tests/Resources/Gtfs/minified-test-feed.zip index 84dd5e9..a19330a 100644 Binary files a/tests/Resources/Gtfs/minified-test-feed.zip and b/tests/Resources/Gtfs/minified-test-feed.zip differ diff --git a/tests/Trafiklab/Gtfs/GtfsArchiveIntegrationTest.php b/tests/Trafiklab/Gtfs/GtfsArchiveIntegrationTest.php index 67a6e2d..96ace02 100644 --- a/tests/Trafiklab/Gtfs/GtfsArchiveIntegrationTest.php +++ b/tests/Trafiklab/Gtfs/GtfsArchiveIntegrationTest.php @@ -224,4 +224,33 @@ public function testGetAgency() self::assertNull($agencies[1]->getAgencyEmail(), 'Agency Email is not null!'); self::assertEquals('000-000-0000', $agencies[1]->getAgencyPhone(), 'Agency Phone is not equal to 000-000-0000'); } + + /** + * Test the Directions GTFSArchive. + * @return void + */ + public function testGetDirections() + { + /** Directions file should be retrieved. */ + $directions = $this->gtfsArchive->getDirectionsFile()->getDirections(); + /** Test correct number of directions parsed. */ + self::assertEquals(17, count($directions), 'Parsed incorrect number of Directions.'); + /** Test Types */ + self::assertIsString($directions[0]->getRouteId(), 'route_id should be a string.'); + self::assertIsString($directions[0]->getDirection(), 'direction should be a string.'); + self::assertIsNumeric($directions[0]->getDirectionId(), 'direction_id should be numeric (0,1).'); + /** Test Getters/Validity */ + self::assertEquals(0, $directions[16]->getDirectionId(), 'direction_id should be 0.'); + self::assertEquals('North', $directions[0]->getDirection(), 'Should Equal North.'); + self::assertEquals('1', $directions[0]->getRouteId(), 'Should equal 1'); + self::assertEquals('Northeast', $directions[4]->getDirection(), 'Should Equal Northeast.'); + self::assertEquals('A Loop', $directions[15]->getDirection(), 'Should Equal A Loop.'); + /** Test Abbreviations method. */ + self::assertEquals('N', $directions[0]->getCardinalDirectionAbrv(), 'Should Equal N'); + self::assertEquals('NB', $directions[0]->getCardinalDirectionAbrv(true), 'Should Equal NB'); + self::assertEquals('SB', $directions[6]->getCardinalDirectionAbrv(true), 'Should Equal SB'); + /** Test DirectionBound method (Inbound/Outbound) */ + self::assertEquals("Inbound", $directions[0]->getBoundDirection(), 'Should be equal to Inbound.'); + self::assertEquals("Outbound", $directions[16]->getBoundDirection(), 'Should be equal to Outbound.'); + } }