From 156dd142883f924cdce11e9ddd41dc11ed604294 Mon Sep 17 00:00:00 2001 From: Arun Isaac Date: Sat, 14 Oct 2023 21:08:29 +0100 Subject: Directly query TfL API to find tube lines at station. Earlier, we were laboriously building a lookup table mapping all tube lines to the stations they serve, and inverting that lookup table. * rent.scm (all-tube-lines, stations-on-line): Delete functions. (lines-at-station): Rewrite to directly query TfL API. --- rent.scm | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'rent.scm') diff --git a/rent.scm b/rent.scm index 9a0857a..d380d1f 100644 --- a/rent.scm +++ b/rent.scm @@ -365,34 +365,35 @@ and not distance as the crow flies." "distances" 0 0) 1000)))))) -(define (all-tube-lines) - "Return a list of all tube lines in London." - (call-with-port (open-bytevector-input-port - (http-get* (string-append %tfl-base-url - "/Line/Mode/tube"))) - (lambda (port) - (map (lambda (line) - (json-ref line "id")) - (vector->list (json->scm port)))))) - -(define (stations-on-line line-id) - "Return a list of tube stations on @var{line-id}." - (call-with-port (open-bytevector-input-port - (http-get* (string-append %tfl-base-url - "/Line/" line-id "/StopPoints"))) - (lambda (port) - (map (lambda (station) - (let ((station-name (json-ref station "commonName"))) - (if (string-suffix? " Underground Station" station-name) - (substring station-name 0 (- (string-length station-name) - (string-length " Underground Station")))))) - (vector->list (json->scm port)))))) - (define (lines-at-station station-name) "Return a list of tube lines serving @var{station-name}." - (filter (lambda (line) - (member station-name (stations-on-line line))) - (all-tube-lines))) + (let* ((modes (list "dlr" "elizabeth-line" "tube")) + (station-id + (call-with-port (open-bytevector-input-port + (http-get* (string-append %tfl-base-url + "/StopPoint/Search/" + (uri-encode station-name) + "?modes=" + (string-join modes ",")))) + (lambda (port) + ;; Assume the first search result is the station we are + ;; looking for. + (json-ref (json->scm port) + "matches" 0 "id"))))) + (call-with-port (open-bytevector-input-port + (http-get* (string-append %tfl-base-url + "/StopPoint/" station-id))) + (lambda (port) + (vector->list + ;; Assume that we actually find tube lines at this + ;; station. This may not be the case if the supplied + ;; station-name is not actually a tube station. + (json-ref (find (lambda (mode-group) + (member (json-ref mode-group "modeName") + modes)) + (vector->list (json-ref (json->scm port) + "lineModeGroups"))) + "lineIdentifier")))))) (define (list-house house) "Display details of @var{house} on the current output port." -- cgit v1.2.3