Transport Direct API

As part of Show Us A Better Way, Transport Direct provided access to their journey planning API (which is actually run by Atos Origin). It took about 25 emails to get set up with an account and IP-based access to the API, and a slog through the usual XML-based documentation for a government SOAP API (that doesn't even mention the WSDL file), but it's working now so here are some notes.

The first API I wanted to use was the DepartureBoardService, which has a GetDepartureBoard function that lists the next departures from any given bus or rail stop:

<?php
$client = new SOAPClient('http://testservices.transportdirect.info/DepartureBoard/V1/DepartureBoardService.asmx?WSDL');
// WSSE authentication header
$auth = new SoapVar(sprintf(
  '<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <UsernameToken><Username>%s</Username><Password>%s</Password></UsernameToken>
  </Security>',
  htmlspecialchars(USERNAME), htmlspecialchars(PASSWORD)
), XSD_ANYXML);
$client->__setSoapHeaders(array(new SoapHeader('http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', 'Security', $auth)));
$now = getdate();
$service = $_GET['service']; // optional number of a specific route
$detail = $_GET['detail']; // optional parameter, whether to retrieve detailed information for the route
$naptan = $_GET['naptan']; //  NaPTAN code for this stop
$response = $client->GetDepartureBoard(array(
  'transactionId' => 'test1',
  'language' => 'en-GB',
  'departureBoardRequest' => array(
    'RangeType' => 'Sequence',
    'Range' => $detail ? 1 : 5, // retrieve the next 5 departures, or detail for 1 departure
    'ShowDepartures' => 'true',
    'ServiceNumber' => $service, // number of the service/bus route - set this if fetching information for a single route
    'ShowCallingStops' => $detail ? 'true' : 'false', // 'true' to retrieve all the stops on a single route
    
    'OriginLocation' => array(
      'NaptanIds' => array($naptan),
      'Type' => 'NAPTAN',
      'Valid' => 'true',
      ),
      
    'JourneyTimeInformation' => array(
      'Type' => 'Now',
      'Hour' => $now['hours'],
      'Minute' => $now['minutes'],
      ),
    ),
  ));
$results = $response->GetDepartureBoardResult->DepartureBoardServiceStopInformation;

You can see this in use to show the next departures from a specific bus stop.

There are other useful methods available too, such as CodeService (fuzzy lookup of NaPTAN/IATA/postcode codes from textual location names), FindNearest (finds the nearest stations or stops to a given location), and of course the journey planner as used by Transport Direct itself.

A FindText request looks like this:

<?php
$client = new SOAPClient('http://testservices.transportdirect.info/CodeHandler/v1/CodeService.asmx?WSDL');
// authentication here
$response = $client->FindText(array(
  'transactionId' => 'test1',
  'language' => 'en-GB',
  'codeRequest' => array(
    'PlaceText' => 'Victoria Station, London',
    'Fuzzy' => 'true',
    'ModeTypes' => array(
      'CodeServiceModeType' => 'Rail',
      'CodeServiceModeType' => 'Bus',
      )
    ),
  ));
?>

A FindNearest request looks like this:

<?php
$client = new SOAPClient('http://testservices.transportdirect.info/FindNearest/v1/FindNearestService.asmx?WSDL');
// authentication here
$reference = $client->GetGridReference(array(
  'transactionId' => 'null',
  'language' => 'en-GB',
  'postcode' => 'N1 9XW',
  ));
$response = $client->FindNearestBusStops(array(
  'transactionId' => 'null',
  'language' => 'en-GB',
  'maxResults' => 5,
  'gridReference' => array(
    'Easting' => $reference->GetGridReferenceResult->Easting,
    'Northing' => $reference->GetGridReferenceResult->Northing,
    )
  ));
?>